Package: django-oscar-saferpay
django-oscar-saferpaySaferpay dashboard for django-oscarThis package is adjango-oscardashboard component for saferpay.First follow the install instructions for django-saferpay (pypi,github)
.Install withpip install django-oscar-saferpay.Update yoursettings.py:INSTALLED_APPS=[...'saferpay_oscar',]in your projecturls.py:fromsaferpay_oscar.dashboard.appimportapplicationassaferpay_dashboard_application...url(r'^dashboard/saferpay/',saferpay_dashboard_application.urls),...add a new payment method to oscar insettings.py:...OSCAR_PAYMENT_METHODS=(('saferpay',_('Creditcard (Visa, Mastercard, etc..)')),# all your activated saferpay methods)...Example implementationHere is an example implementation not meant for for copy & paste. A oscar shop can be setup
totally different.Update your checkoutmyshop/checkout/app.pyfromdjango.conf.urlsimporturlfromoscar.apps.checkoutimportappfrommyshop.checkoutimportviewsclassCheckoutApplication(app.CheckoutApplication):shipping_address_view=views.ShippingAddressViewshipping_method_view=views.ShippingMethodViewpayment_details_view=views.PaymentDetailsViewpayment_method_view=views.PaymentMethodViewpreview_view=views.PreviewView# normally just in PaymentDetailsView, custom to this use-casepayment_capture_view=views.PaymentCapture# new view not in oscarthankyou_view=views.ThankYouViewpayment_failed_view=views.PaymentFailed# new view not in oscardefget_urls(self):urls=[url(r'^$',self.index_view.as_view(),name='index'),# Shipping/user address viewsurl(r'shipping-address/$',self.shipping_address_view.as_view(),name='shipping-address'),url(r'user-address/edit/(?P<pk>\d+)/$',self.user_address_update_view.as_view(),name='user-address-update'),url(r'user-address/delete/(?P<pk>\d+)/$',self.user_address_delete_view.as_view(),name='user-address-delete'),# Shipping method viewsurl(r'shipping-method/$',self.shipping_method_view.as_view(),name='shipping-method'),# Payment viewsurl(r'payment-details/$',self.payment_details_view.as_view(),name='payment-details'),url(r'payment-method/$',self.payment_method_view.as_view(),name='payment-method'),url(r'payment-failed/$',self.payment_failed_view.as_view(),name='payment-failed'),# Preview and thankyouurl(r'preview/$',self.preview_view.as_view(),name='preview'),url(r'payment-capture/$',self.payment_capture_view.as_view(),name='payment-capture'),url(r'thank-you/$',self.thankyou_view.as_view(),name='thank-you'),]returnself.post_process_urls(urls)application=CheckoutApplication()Update your viewsAdd it to your custom extended oscar checkout app views.inmyshop/checkout/views.py:...fromsaferpay.gatewayimportSaferpayServicefromsaferpayimportexecptionsassp_execptions...defbilling_address_for_saferpay(billing_address):data={}data['FirstName']=billing_address.first_namedata['LastName']=billing_address.last_namedata['Street']=billing_address.line1ifbilling_address.line2:data['Street2']=billing_address.line2data['Zip']=billing_address.postcodedata['City']=billing_address.cityreturndata# in your PaymentDetailsView in handle_payment()classPaymentDetailsView(OrderPlacementMixin,generic.TemplateView):...defhandle_payment(self,order_number,total,**kwargs):payment_method=self.checkout_session._get('payment','payment_method')# invoiceifpayment_method=='invoice':pass# nothing to do for invoice, no money collected# saferpayelifpayment_method=='saferpaylanguage_code=translation.get_language()[0:2]saferpay_service=SaferpayService(order_id=order_number,amount=total.incl_tax,currency=total.currency,language_code=language_code)billing_address=self.get_billing_address(shipping_address=self.get_shipping_address(self.request.basket))billing_address_data=billing_address_for_saferpay(billing_address)payload=saferpay_service.payload_init(billing_address=billing_address_data)# redirects to payment pagetry:token=saferpay_service.paymentpage_init(payload)self.checkout_session._set('payment','saferpay_token',token)raiseRedirectRequired(saferpay_service.paymentpage_redirect().url)exceptsp_execptions.GatewayErrorase:self.restore_frozen_basket()returnredirect(reverse_lazy('checkout:payment-failed'))# new classclassPaymentCapture(views.PaymentDetailsView):success_url=reverse_lazy('checkout:thank-you')pre_conditions=[]defload_frozen_basket(self,basket_id):# Lookup the frozen basket that this txn corresponds totry:basket=Basket.objects.get(id=basket_id,status=Basket.FROZEN)exceptBasket.DoesNotExist:returnNoneifSelector:basket.strategy=Selector().strategy(self.request)Applicator().apply(basket,self.request.user,request=self.request)returnbasketdefget(self,request,*args,**kwargs):token=self.checkout_session._get('payment','saferpay_token')saferpay_service=SaferpayService.init_from_transaction(token=token)try:status=saferpay_service.paymentpage_assert()except(sp_execptions.GatewayError,sp_execptions.TransactionDeclined,sp_execptions.UnableToTakePayment,sp_execptions.PaymentError)ase:self.restore_frozen_basket()returnredirect(reverse_lazy('checkout:payment-failed'))ifstatus=='CAPTURED':source_type,is_created=models.SourceType.objects.get_or_create(name='saferpay')source=source_type.sources.model(source_type=source_type,amount_allocated=saferpay_service.amount,currency=saferpay_service.currency)self.add_payment_source(source)self.add_payment_event('CAPTURED',saferpay_service.amount)post_payment.send_robust(sender=self,view=self)# If all is ok with payment, try and place orderlogger.info("Order #%s: payment successful, placing order",saferpay_service.order_id)try:basket_id=self.checkout_session.get_submitted_basket_id()basket=self.load_frozen_basket(basket_id)shipping_address=self.get_shipping_address(basket)billing_address=self.get_billing_address(shipping_address=shipping_address)shipping_method=self.get_shipping_method(basket=basket,shipping_address=shipping_address)shipping_charge=shipping_method.calculate(basket)order_total=Price(saferpay_service.currency,saferpay_service.amount,saferpay_service.amount)order_kwargs=self.checkout_session._get('payment','order_kwargs')order_number=saferpay_service.order_idreturnself.handle_order_placement(order_number,self.request.user,basket,shipping_address,shipping_method,shipping_charge,billing_address,order_total,**order_kwargs)exceptUnableToPlaceOrderase:# It's possible that something will go wrong while trying to# actually place an order.msg=six.text_type(e)logger.error("Order #%s: unable to place order -%s",order_number,msg,exc_info=True)self.restore_frozen_basket()returnself.render_preview(self.request,error=msg)# updated to add payment_methodclassThankYouView(CheckoutSessionMixin,views.ThankYouView):defget_context_data(self,**kwargs):ctx=super().get_context_data()ctx['payment_method']=self.checkout_session._get('payment','payment_method')ctx.update(kwargs)returnctx# new class, redirect to preview on payment failureclassPaymentFailed(OrderPlacementMixin,View):defget(self,request,*args,**kwargs):self.restore_frozen_basket()error_txt=_("The payment was not successful, please try again or use a different payment method.")messages.error(request,error_txt)returnredirect(reverse_lazy('checkout:preview'))