Package: django-shop-payer-backend
Django SHOP payment backend forPayer. Usespython-payer-apifor interacting with the API.Installationpip install django-shop-payer-backendAdd to installed appsINSTALLED_APPS=[...'polymorphic','shop''shop.addressmodel','django_shop_payer_backend',...]Configure one ore more payment backendsSHOP_PAYMENT_BACKENDS=['django_shop_payer_backend.backends.PayerCreditCardPaymentBackend','django_shop_payer_backend.backends.PayerBankPaymentBackend','django_shop_payer_backend.backends.PayerInvoicePaymentBackend','django_shop_payer_backend.backends.PayerPhonePaymentBackend',]You could also use theGenericPayerBackendin order to let the user
choose payment methodafterbeing redirected to Payer, or define a
subclass of your own, listing a custom set of methods in thepayment_methodsproperty. This might be a good option if you are
using the Payer backend along with other backends such as Paypal etc.ConfigurationAdd your keys to settings.pySHOP_PAYER_BACKEND_AGENT_ID="AGENT_ID"SHOP_PAYER_BACKEND_ID1="6866ef97a972ba3a2c6ff8bb2812981054770162"SHOP_PAYER_BACKEND_ID2="1388ac756f07b0dda2961436ba8596c7b7995e94"The following settings are optional# Used for white/blacklisting callback IPsSHOP_PAYER_BACKEND_IP_WHITELIST=["192.168.0.1"]SHOP_PAYER_BACKEND_IP_BLACKLIST=["10.0.1.1"]# Used for suppliying an address modelSHOP_PAYER_BACKEND_ADDRESS_HANDLER='project.app.path.to.address_model_callback'SHOP_PAYER_BACKEND_HIDE_DETAILS=False# Hide order details during paymentSHOP_PAYER_BACKEND_DEBUG_MODE='verbose'# 'silent', 'brief'SHOP_PAYER_BACKEND_TEST_MODE=TrueConsiderationsDue to the fact that django SHOP by default does not store any relation
between the Order model and the AddressModel model there is no good way
for payment backends to determine the shipping/billing address for a
given order. For some backends this might not be an issue, but in this
case Payer expects to address data in the order details.django-shop-payer-backend tries to tackle by determining the order
(billing) address using the following strategy:Try to fetch AddressModel from current user (ifuser.is_authenticated()).Try to load an AddressModel using a callback supplied in theSHOP_PAYER_BACKEND_ADDRESS_HANDLERsetting.Try to extract address details fromorder.billing_address_textby
reverse parsing the address template used by django SHOP.Let you override/complete the data returned using the above methods
using thepopulate_buyer_details_dictsignal.This has two implications:For non-authenticated users it is simply not possible get an
AddressModel object using the default setup. In this case a reverse
parsing of the address template string django SHOP uses to store the
textual address representation on the Order object. Due to the
somewhat fragile nature of this parsing method, you should take
extreme precautions when modifying theSHOP_ADDRESS_TEMPLATEsetting. For the parser to function it is recommended that you use
some form identifying “key” to identify each keyword (as with
“Name:”” etc. in the default pattern). Patterns such as%(name)s,%(address)s,[...]will likely fail as there is nothing
differentiating thenameandaddresskeywords in the string
format, and alas the regexp will not be able to identify the keywords
correctly.Fields supported by the Payer API that do not have an obvious
counterpart on the AddressModel model (e.g. email, phone,
organisation, etc.) will unsurprisingly not be included in the
PayerBuyerDetails data using the default settings. To make sure they
are included, use the methods described in theExtensibilitysection below.The way to tackle both of the issues outlined above, is probably to add
a foreign key to AddressModel on Order and store the object used when
settingorder.billing_address_text. That way you could add a address
model callback handler (described below), which will let you return that
(or any other) object to the backend.ExtensibilityLet’s say you have a custom address model based onshop.addressmodel.models.Addresswhich adds the fieldcompany.
Naturally you would want this data sent to Payer as well, in order to
have it appear on invoices etc. To accomplish that, add a receiver for
thepopulate_buyer_details_dictsignal and update the buyer details
dict like so:fromdjango_shop_payer_backend.helperimportpopulate_buyer_details_dictfromdjango.dispatchimportreceiver@receiver(populate_buyer_details_dict)defadd_additional_buyer_details(sender,**kwargs):buyer_details_dict=kwargs.get('buyer_details_dict',None)user=kwargs.get('user',None)address=kwargs.get('address',None)order=kwargs.get('order',None)buyer_details_dict.update({'organisation':address.company,})There is a similar signal,populate_order_item_dict, for order
items, allowing you to modify the data that before the PayerOrderItem
object is initialized. This can be useful for example if your Product
model has a field holding VAT percentages, in which case you could
inject that value using this method.Another option for supplying an address to the backend is to implement
and address callback handler, and return an AddressModel object. This is
a good option if you are using a custom Order model that has foreign
keys to the AddressModel. In that case, you can implement a callback
something along the lines of the following:defaddress_model_callback(*args,**kwargs):address=kwargs.get('address',None)order=kwargs.get('order',None)ifaddressisNoneandorderisnotNone:try:address=order.billing_addressexceptException:passreturnaddressAnd add the following tosettings.py:SHOP_PAYER_BACKEND_ADDRESS_HANDLER='project.app.path.to.address_model_callback'