{ "info": { "author": "Yves Serrano", "author_email": "ys@taywa.ch", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 1.11", "Framework :: Django :: 2.0", "Framework :: Django :: 2.1", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# django-oscar-saferpay\n\n*Saferpay dashboard for django-oscar*\n\nThis package is a [django-oscar](http://oscarcommerce.com) dashboard component for saferpay. \nFirst follow the install instructions for django-saferpay ([pypi](https://pypi.org/project/django-saferpay/), [github](https://github.com/taywa/django-saferpay))\n.\n\nInstall with `pip install django-oscar-saferpay`.\n\nUpdate your `settings.py`:\n\n```python\nINSTALLED_APPS = [\n ...\n 'saferpay_oscar',\n]\n```\n\nin your project `urls.py`:\n\n```python\nfrom saferpay_oscar.dashboard.app import application as saferpay_dashboard_application\n...\n url(r'^dashboard/saferpay/', saferpay_dashboard_application.urls),\n...\n```\n\nadd a new payment method to oscar in `settings.py`:\n\n```python\n...\nOSCAR_PAYMENT_METHODS = (\n ('saferpay', _('Creditcard (Visa, Mastercard, etc..)')), # all your activated saferpay methods\n)\n...\n```\n\n## Example implementation\n\nHere is an example implementation not meant for for copy & paste. A oscar shop can be setup\ntotally different.\n\n### Update your checkout `myshop/checkout/app.py`\n\n```python\n\nfrom django.conf.urls import url\nfrom oscar.apps.checkout import app\nfrom myshop.checkout import views\n\n\nclass CheckoutApplication(app.CheckoutApplication):\n shipping_address_view = views.ShippingAddressView\n shipping_method_view = views.ShippingMethodView\n payment_details_view = views.PaymentDetailsView\n payment_method_view = views.PaymentMethodView\n preview_view = views.PreviewView # normally just in PaymentDetailsView, custom to this use-case\n payment_capture_view = views.PaymentCapture # new view not in oscar\n thankyou_view = views.ThankYouView\n payment_failed_view = views.PaymentFailed # new view not in oscar\n\n def get_urls(self):\n urls = [\n url(r'^$', self.index_view.as_view(), name='index'),\n\n # Shipping/user address views\n url(r'shipping-address/$', self.shipping_address_view.as_view(), name='shipping-address'),\n url(r'user-address/edit/(?P\\d+)/$', self.user_address_update_view.as_view(), name='user-address-update'),\n url(r'user-address/delete/(?P\\d+)/$', self.user_address_delete_view.as_view(), name='user-address-delete'),\n\n # Shipping method views\n url(r'shipping-method/$', self.shipping_method_view.as_view(), name='shipping-method'),\n\n # Payment views\n url(r'payment-details/$', self.payment_details_view.as_view(), name='payment-details'),\n url(r'payment-method/$', self.payment_method_view.as_view(), name='payment-method'),\n url(r'payment-failed/$', self.payment_failed_view.as_view(), name='payment-failed'),\n\n # Preview and thankyou\n url(r'preview/$', self.preview_view.as_view(), name='preview'),\n url(r'payment-capture/$', self.payment_capture_view.as_view(), name='payment-capture'),\n url(r'thank-you/$', self.thankyou_view.as_view(), name='thank-you'),\n ]\n return self.post_process_urls(urls)\n\napplication = CheckoutApplication()\n```\n\n### Update your views\n\nAdd it to your custom extended oscar checkout app views.\n\nin `myshop/checkout/views.py`:\n\n```python\n...\nfrom saferpay.gateway import SaferpayService\nfrom saferpay import execptions as sp_execptions\n...\n\ndef billing_address_for_saferpay(billing_address):\n data = {}\n data['FirstName'] = billing_address.first_name\n data['LastName'] = billing_address.last_name\n data['Street'] = billing_address.line1\n if billing_address.line2:\n data['Street2'] = billing_address.line2\n data['Zip'] = billing_address.postcode\n data['City'] = billing_address.city\n return data\n\n#\u00a0in your PaymentDetailsView in handle_payment()\nclass PaymentDetailsView(OrderPlacementMixin, generic.TemplateView):\n ...\n\n def handle_payment(self, order_number, total, **kwargs):\n payment_method = self.checkout_session._get('payment', 'payment_method')\n # invoice\n if payment_method == 'invoice':\n pass\n # nothing to do for invoice, no money collected\n\n # saferpay\n elif payment_method == 'saferpay\n language_code = translation.get_language()[0:2]\n saferpay_service = SaferpayService(\n order_id=order_number, amount=total.incl_tax, currency=total.currency,\n language_code=language_code\n )\n billing_address = self.get_billing_address(\n shipping_address=self.get_shipping_address(self.request.basket)\n )\n billing_address_data = billing_address_for_saferpay(billing_address)\n payload = saferpay_service.payload_init(billing_address=billing_address_data)\n\n # redirects to payment page\n try:\n token = saferpay_service.paymentpage_init(payload)\n self.checkout_session._set('payment', 'saferpay_token', token)\n raise RedirectRequired(saferpay_service.paymentpage_redirect().url)\n except sp_execptions.GatewayError as e:\n self.restore_frozen_basket()\n return redirect(reverse_lazy('checkout:payment-failed'))\n\n# new class\nclass PaymentCapture(views.PaymentDetailsView):\n success_url = reverse_lazy('checkout:thank-you')\n pre_conditions = []\n\n def load_frozen_basket(self, basket_id):\n # Lookup the frozen basket that this txn corresponds to\n try:\n basket = Basket.objects.get(id=basket_id, status=Basket.FROZEN)\n except Basket.DoesNotExist:\n return None\n\n if Selector:\n basket.strategy = Selector().strategy(self.request)\n\n Applicator().apply(basket, self.request.user, request=self.request)\n\n return basket\n\n def get(self, request, *args, **kwargs):\n token = self.checkout_session._get('payment', 'saferpay_token')\n saferpay_service = SaferpayService.init_from_transaction(token=token)\n try:\n status = saferpay_service.paymentpage_assert()\n except (\n sp_execptions.GatewayError, sp_execptions.TransactionDeclined,\n sp_execptions.UnableToTakePayment, sp_execptions.PaymentError\n ) as e:\n self.restore_frozen_basket()\n return redirect(reverse_lazy('checkout:payment-failed'))\n if status == 'CAPTURED':\n source_type, is_created = models.SourceType.objects.get_or_create(\n name='saferpay')\n source = source_type.sources.model(\n source_type=source_type,\n amount_allocated=saferpay_service.amount,\n currency=saferpay_service.currency\n )\n self.add_payment_source(source)\n self.add_payment_event('CAPTURED', saferpay_service.amount)\n\n post_payment.send_robust(sender=self, view=self)\n\n # If all is ok with payment, try and place order\n logger.info(\"Order #%s: payment successful, placing order\", saferpay_service.order_id)\n\n try:\n basket_id = self.checkout_session.get_submitted_basket_id()\n basket = self.load_frozen_basket(basket_id)\n shipping_address = self.get_shipping_address(basket)\n billing_address = self.get_billing_address(shipping_address=shipping_address)\n shipping_method = self.get_shipping_method(\n basket=basket, shipping_address=shipping_address\n )\n shipping_charge = shipping_method.calculate(basket)\n order_total = Price(\n saferpay_service.currency, saferpay_service.amount, saferpay_service.amount\n )\n order_kwargs = self.checkout_session._get('payment', 'order_kwargs')\n order_number = saferpay_service.order_id\n return self.handle_order_placement(\n order_number, self.request.user,\n basket, shipping_address, shipping_method, shipping_charge,\n billing_address, order_total, **order_kwargs\n )\n except UnableToPlaceOrder as e:\n # It's possible that something will go wrong while trying to\n # actually place an order.\n msg = six.text_type(e)\n logger.error(\"Order #%s: unable to place order - %s\",\n order_number, msg, exc_info=True)\n self.restore_frozen_basket()\n return self.render_preview(\n self.request, error=msg\n )\n\n# updated to add payment_method\nclass ThankYouView(CheckoutSessionMixin, views.ThankYouView):\n def get_context_data(self, **kwargs):\n ctx = super().get_context_data()\n ctx['payment_method'] = self.checkout_session._get('payment', 'payment_method')\n ctx.update(kwargs)\n return ctx\n\n# new class, redirect to preview on payment failure\nclass PaymentFailed(OrderPlacementMixin, View):\n def get(self, request, *args, **kwargs):\n self.restore_frozen_basket()\n error_txt = _(\"The payment was not successful, please try again or use a different payment method.\")\n messages.error(\n request,\n error_txt\n )\n return redirect(reverse_lazy('checkout:preview'))\n```", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/taywa/django-oscar-saferpay", "keywords": "saferpay,payment", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "django-oscar-saferpay", "package_url": "https://pypi.org/project/django-oscar-saferpay/", "platform": "", "project_url": "https://pypi.org/project/django-oscar-saferpay/", "project_urls": { "Homepage": "https://github.com/taywa/django-oscar-saferpay" }, "release_url": "https://pypi.org/project/django-oscar-saferpay/0.1.0/", "requires_dist": null, "requires_python": "", "summary": "Saferpay payment dashboard for django-oscar.", "version": "0.1.0" }, "last_serial": 4803259, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "abe1d1b52bdb6797de47b12faece62cc", "sha256": "0ed59afb5163d091b6b34e55ffdb6349895ae4f7c3a1437fae93c61ad8e4bd3c" }, "downloads": -1, "filename": "django-oscar-saferpay-0.1.0.tar.gz", "has_sig": false, "md5_digest": "abe1d1b52bdb6797de47b12faece62cc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6334, "upload_time": "2019-02-10T20:48:12", "url": "https://files.pythonhosted.org/packages/2a/b2/877b4d05dc83ca51643e4f86d879c8d3bff4d538b89f77e99410a5ae7f45/django-oscar-saferpay-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "abe1d1b52bdb6797de47b12faece62cc", "sha256": "0ed59afb5163d091b6b34e55ffdb6349895ae4f7c3a1437fae93c61ad8e4bd3c" }, "downloads": -1, "filename": "django-oscar-saferpay-0.1.0.tar.gz", "has_sig": false, "md5_digest": "abe1d1b52bdb6797de47b12faece62cc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6334, "upload_time": "2019-02-10T20:48:12", "url": "https://files.pythonhosted.org/packages/2a/b2/877b4d05dc83ca51643e4f86d879c8d3bff4d538b89f77e99410a5ae7f45/django-oscar-saferpay-0.1.0.tar.gz" } ] }