Skip to main content

Django Virtual Pos

Django module that abstracts the flow of several virtual points of sale including PayPal

What’s this?

This module abstracts the use of the most used virtual points of sale in Spain.

License

MIT LICENSE.

Implemented payment methods

Paypal

Paypal paypal payment available.

Bitpay

Bitpay bitcoin payments, from wallet to checkout

Spanish Virtual Points of Sale

  • Ceca

CECA is the Spanish confederation of savings banks.

  • RedSyS

RedSyS gives payment services to several Spanish banks like CaixaBank or Caja Rural.

Santander Elavon

Santander Elavon is one of the payment methods of the Spanish bank Santander.

Requirements and Installation

Requirements

  • Python 2.7 (Python 3 not tested, contributors wanted!)

  • Django

  • BeautifulSoup4

  • lxml

  • pycrypto

  • Pytz

  • Requests

Type:

$ pip install django beautifulsoup4 lxml pycrypto pytz

Installation

From PyPi

$ pip install django-virtual-pos

From master branch

Master branch will allways contain a working version of this module.

$ pip install git+git://github.com/intelligenia/django-virtual-pos.git

settings.py

Add the application djangovirtualpos to your settings.py:

INSTALLED_APPS = (
    # ...
    "djangovirtualpos",
)

Use

See this manual (currently only in Spanish).

Needed models

You will need to implement this skeleton view using your own Payment model.

This model has must have at least the following attributes: - code: sale code given by our system. - operation_number: bank operation number. - status: status of the payment: “paid”, “pending” (pending is mandatory) or “canceled”. - amount: amount to be charged.

And the following methods: - online_confirm: mark the payment as paid.

Integration examples

  • djshop

Needed views

Sale summary view

def payment_summary(request, payment_id):
    """
    Load a Payment object and show a summary of its contents to the user.
    """

    payment = get_object_or_404(Payment, id=payment_id, status="pending")
    replacements = {
        "payment": payment,
        # ...
    }
    return render(request, '<sale summary template path>', replacements)

Note that this payment summary view should load a JS file called set_payment_attributes.js.

This file is needed to set initial payment attributes according to which bank have the user selected.

Payment_confirm view

@csrf_exempt
def payment_confirmation(request, virtualpos_type):
    """
    This view will be called by the bank.
    """
    # Directly call to confirm_payment view

    # Or implement the following actions

    # Checking if the Point of Sale exists
    virtual_pos = VirtualPointOfSale.receiveConfirmation(request, virtualpos_type=virtualpos_type)

    if not virtual_pos:
            # The VPOS does not exist, inform the bank with a cancel
            # response if needed
            return VirtualPointOfSale.staticResponseNok(virtualpos_type)

    # Verify if bank confirmation is indeed from the bank
    verified = virtual_pos.verifyConfirmation()
    operation_number = virtual_pos.operation.operation_number

    with transaction.atomic():
            try:
                    # Getting your payment object from operation number
                    payment = Payment.objects.get(operation_number=operation_number, status="pending")
            except Payment.DoesNotExist:
                    return virtual_pos.responseNok("not_exists")

            if verified:
                    # Charge the money and answer the bank confirmation
                    try:
                            response = virtual_pos.charge()
                            # Implement the online_confirm method in your payment
                            # this method will mark this payment as paid and will
                            # store the payment date and time.
                            payment.online_confirm()
                    except VPOSCantCharge as e:
                            return virtual_pos.responseNok(extended_status=e)
                    except Exception as e:
                            return virtual_pos.responseNok("cant_charge")

            else:
                    # Payment could not be verified
                    # signature is not right
                    response = virtual_pos.responseNok("verification_error")

            return response

Payment ok view

def payment_ok(request, sale_code):
    """
    Informs the user that the payment has been made successfully
    :param payment_code: Payment code.
    :param request: request.
    """

    # Load your Payment model given its code
    payment =  get_object_or_404(Payment, code=sale_code, status="paid")

    context = {'pay_status': "Done", "request": request}
    return render(request, '<payment_ok template>', {'context': context, 'payment': payment})

Payment cancel view

def payment_cancel(request, sale_code):
    """
    Informs the user that the payment has been canceled
    :param payment_code: Payment code.
    :param request: request.
    """

    # Load your Payment model given its code
    payment =  get_object_or_404(Payment, code=sale_code, status="pending")
    # Mark this payment as canceled
    payment.cancel()

    context = {'pay_status': "Done", "request": request}
    return render(request, '<payment_canceled template>', {'context': context, 'payment': payment})

Refund view

def refund(request, tpv, payment_code, amount, description):
    """
    :param request:
    :param tpv: TPV Id
    :param payment_code: Payment code
    :param amount: Refund Amount (Example 10.89).
    :param description: Description of refund cause.
    :return:
    """

    amount = Decimal(amount)

    try:
            # Checking if the Point of Sale exists
            tpv = VirtualPointOfSale.get(id=tpv)
            # Checking if the Payment exists
            payment = Payment.objects.get(code=payment_code, state="paid")

    except Payment.DoesNotExist as e:
            return http_bad_request_response_json_error(message=u"Does not exist payment with code {0}".format(payment_code))

    refund_status = tpv.refund(payment_code, amount, description)

    if refund_status:
            message = u"Refund successful"
    else:
            message = u"Refund with erros"

    return http_response_json_ok(message)

Authors

Remove REMOVETHIS to contact the authors.

Metadata

Release files for django-virtual-pos 1.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-virtual-pos 1.7.1
File Size Uploaded Provenance
django-virtual-pos-1.7.1.tar.gz 55.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django-virtual-pos 1.7.1
File Interpreter ABI Platform
django_virtual_pos-1.7.1-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 117.8 kB

Release files / django-virtual-pos-1.7.1.tar.gz

Download URL django-virtual-pos-1.7.1.tar.gz
Size 55.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6664bc98f1af6b831157287b356b742a8291e7b153fc7228f7e2c37464f8e25d
BLAKE2b-256 checksum
How to use checksums
13cc300fa8f61bfee3d73e14650dadfee55d5575c7c17c2e6330d1f5b6452b91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.15.0 pkginfo/1.8.3 requests/2.27.1 setuptools/44.1.1 requests-toolbelt/1.0.0 tqdm/4.64.1 CPython/2.7.18

Release files / django_virtual_pos-1.7.1-py2.py3-none-any.whl

Download URL django_virtual_pos-1.7.1-py2.py3-none-any.whl
Size 62.5 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
85c80d7a1ddbd527a2bd016bf2ed250e77e2ac1f1936cdf3e2010f8cec7e94d0
BLAKE2b-256 checksum
How to use checksums
42b5ab82443ed8b807642cebbf34030b127e1278657994d25a00aceb2bf134f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.15.0 pkginfo/1.8.3 requests/2.27.1 setuptools/44.1.1 requests-toolbelt/1.0.0 tqdm/4.64.1 CPython/2.7.18

Security for django-virtual-pos 1.7.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page