Package: django-oscar-paymentexpress
This package provides integration with the payment gateway, PaymentExpress using theirPX POST API. It is designed to work seamlessly with the e-commerce frameworkdjango-oscarbut can be used without it.InstallationFrom PyPi:pip install django-oscar-paymentexpressor from Github:pip install git+git://github.com/tangentlabs/django-oscar-paymentexpress.git#egg=django-oscar-paymentexpressAdd'paymentexpress'toINSTALLED_APPSand run:./manage.py migrate paymentexpressto create the appropriate database tables.ConfigurationEdit yoursettings.pyto set the following settings:PAYMENTEXPRESS_POST_URL = 'https://sec.paymentexpress.com/pxpost.aspx'
PAYMENTEXPRESS_USERNAME = '…'
PAYMENTEXPRESS_PASSWORD = '…'
PAYMENTEXPRESS_CURRENCY = 'AUD'Integration into checkoutYou’ll need to use a subclass ofoscar.apps.checkout.views.PaymentDetailsViewwithin your own
checkout views.  Seeoscar’s documentationon how to create a local version of the checkout app.Override thehandle_paymentmethod (which is blank by default) and add your integration code.  An example
integration might look like:# myshop.checkout.views
from django.conf import settings

from oscar.apps.checkout.views import PaymentDetailsView as OscarPaymentDetailsView
from oscar.apps.payment.forms import BankcardForm
from paymentexpress.facade import Facade
from paymentexpress import PAYMENTEXPRESS

...

class PaymentDetailsView(OscarPaymentDetailsView):

    def get_context_data(self, **kwargs):
        ...
        ctx['bankcard_form'] = BankcardForm()
        ...
        return ctx

    def post(self, request, *args, **kwargs):
        """
        This method is designed to be overridden by subclasses which will
        validate the forms from the payment details page.  If the forms are valid
        then the method can call submit()
        """
        # Check bankcard form is valid
        bankcard_form = BankcardForm(request.POST)
        if not bankcard_form.is_valid():
            ctx = self.get_context_data(**kwargs)
            ctx['bankcard_form'] = bankcard_form
            return self.render_to_response(ctx)

        bankcard = bankcard_form.get_bankcard_obj()

        # Call oscar's submit method, passing through the bankcard object so it gets
        # passed to the 'handle_payment' method
        return self.submit(request.basket, payment_kwargs={'bankcard': bankcard})

    def handle_payment(self, order_number, total, **kwargs):
        # Make request to PaymentExpress - if there any problems (eg bankcard
        # not valid / request refused by bank) then an exception would be
        # raised and handled) within oscar's PaymentDetails view.
        bankcard = kwargs['bankcard']
        response_dict = Facade().purchase(order_number, total, None, bankcard)

        source_type, _ = SourceType.objects.get_or_create(name=PAYMENTEXPRESS)
        source = Source(source_type=source_type,
                        currency=settings.PAYMENTEXPRESS_CURRENCY,
                        amount_allocated=total,
                        amount_debited=total,
                        reference=response_dict['partner_reference'])

        self.add_payment_source(source)

        # Also record payment event
        self.add_payment_event(PURCHASE, total)Oscar’s view will handle the various exceptions that can get raised.Package structureThere are two key components:GatewayThe classpaymentexpress.gateway.Gatewayprovides fine-grained access to the PaymentExpress API, which involve constructing XML requests and decoding XML responses.  All calls return apaymentexpress.gateway.Responseinstance which provides dictionary-like access to the attributes of the response.Example calls:# Authorise a transaction.
# The funds are not transferred from the cardholder account.
response = gateway.authorise(card_holder='John Smith',
                             card_number='4500230021616301',
                             cvc2='123',
                             amount=50.23)

# Completes (settles) a pre-approved Auth Transaction.
response = gateway.complete(amount=50.23,
                            dps_txn_ref='0000000809b61753')


# Purchase on a new card - funds are transferred immediately
response = gateway.purchase(card_holder='Frankie',
                            card_number=CARD_VISA,
                            card_expiry='1015',
                            cvc2='123',
                            merchant_ref='100001_PURCHASE_1_2008',
                            enable_add_bill_card=1,
                            amount=29.95)

# Purchase on a previously used card
response = gateway.purchase(amount=29.95,
                            billing_id='0000080023748351')


# Refund a transaction - funds are transferred immediately
response = gateway.refund(dps_txn_ref='0000000809b61753',
                          merchant_ref='abc123',
                          amount=50.23)FacadeThe classpaymentexpress.facade.Facadewraps the above gateway object and provides a less granular API, as well as saving instances ofpaymentexpress.models.OrderTransactionto provide an audit trail for PaymentExpress activity.SettingsPAYMENTEXPRESS_POST_URL- PX POST URLPAYMENTEXPRESS_USERNAME- UsernamePAYMENTEXPRESS_PASSWORD- PasswordPAYMENTEXPRESS_CURRENCY- Currency to use for transactionsContributingTo work ondjango-oscar-paymentexpress, clone the repo, set up a virtualenv and install in develop mode:python setup.py developthen install the testing dependencies:pip install -r requirements.txtThe test suite can then be run using:./run_tests.pyMagic card numbers are available on the PaymentExpress site:http://www.paymentexpress.com/knowledge_base/faq/developer_faq.html#Testing%20DetailsSample VISA vard:4111111111111111