Integrating A Redirection-included Method Of Payment In Django-oscar
I am developing a shopping website using django-oscar framework, in fact I am using their sandbox site. I want to add payment to the checkout process, but the thing is, I am totall
Solution 1:
I had a similar problem, what I did was have the callBackUrl from the bank redirect to a view which is implemented something like this:
classCustomCheckoutDone(OrderPlacementMixin, RedirectView):
"""
here we verify payment was done and place the actual order
then redirect to thank you page
"""
permanent = Falsedefget_redirect_url(self, pk):
basket = Basket.objects.get(pk=self.checkout_session.get_submitted_basket_id())
basket.strategy = CustomStrategy()
order_number = self.checkout_session.get_order_number()
shipping_address = self.get_shipping_address(basket)
shipping_method = self.get_shipping_method(basket, shipping_address)
shipping_charge = shipping_method.calculate(basket)
billing_address = self.get_billing_address(shipping_address)
order_total = self.get_order_totals(basket, shipping_charge=shipping_charge)
order_kwargs = {}
# make sure payment was actually paid
CustomPayment.objects.get(order_number=order_number, payed_sum=str(float(order_total.incl_tax)))
user = self.request.user
ifnot user.is_authenticated():
order_kwargs['guest_email'] = self.checkout_session.get_guest_email()
self.handle_order_placement(
order_number, user, basket, shipping_address, shipping_method,
shipping_charge, billing_address, order_total, **order_kwargs
)
return'/checkout/thank-you/'
Solution 2:
Well, I had same problem came across solution with the following:
As we redirect to the payment gateway, we should have callback URL for approve, decline and cancel.
First of all, we should add these to settings.py
SESSION_COOKIE_SAMESITE = None
SESSION_COOKIE_DOMAIN = 'localhost'#change it to your domain in prod env.
As the documentation says we need some extra things to do, after payment completed:
https://django-oscar.readthedocs.io/en/2.0.4/howto/how_to_integrate_payment.html
Everything you wrote in the above correct.
Afterwards set your callback URL:
path('gateway/', PaymentReturnURL.as_view(), name="gateway")
from django.shortcuts import render
from oscar.apps.checkout.mixins import OrderPlacementMixin
from django.views.generic.base import TemplateView
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.shortcuts import redirect
from django.urls.base import reverse_lazy
from oscar.core.loading import get_model
from datetime import datetime
from oscar.apps.payment import models
from xml.etree import ElementTree
Basket = get_model('basket', 'Basket')
@method_decorator(csrf_exempt, name='dispatch')classPaymentReturnURL(OrderPlacementMixin,TemplateView):
success_url = reverse_lazy('checkout:thank-you')
basket_url = reverse_lazy('basket:summary')
defget_success_url(self):
return self.success_url
defget_order_details(self):
basket = Basket.objects.get(pk=self.checkout_session.get_submitted_basket_id())
basket.strategy = self.request.strategy
order_number = self.checkout_session.get_order_number()
shipping_address = self.get_shipping_address(basket)
shipping_method = self.get_shipping_method(basket, shipping_address)
shipping_charge = shipping_method.calculate(basket)
billing_address = self.get_billing_address(shipping_address)
order_total = self.get_order_totals(basket, shipping_charge=shipping_charge)
order_kwargs = {}
return {
"basket": basket,
"order_number": order_number,
"shipping_address": shipping_address,
"shipping_method": shipping_method,
"shipping_charge": shipping_charge,
"billing_address": billing_address,
"order_total": order_total,
"order_kwargs": order_kwargs,
}
defget(self, request, *args, **kwargs):
return redirect(self.get_success_url())
defpost(self, request, *args, **kwargs):
#for my case it was XML I needed to parse, after proceding from bank, banks posts the data to your callback url
context = {}
data = self.request.POST.get("xmlmsg")
xml_response = ElementTree.fromstring(data)
for i in xml_response.iter("*"):
context[i.tag] = i.text
status = context.get("OrderStatus")
if status == "APPROVED":
# Payment successful! Record payment source
user = self.request.user
print("the user",user)
order_details = self.get_order_details()
source_type, __ = models.SourceType.objects.get_or_create(name="Name of Payment")
source = models.Source(
source_type=source_type,
amount_allocated=context.get("PurchaseAmountScr"),
reference=context.get("OrderID"))
self.add_payment_source(source)
# Record payment event
self.add_payment_event('pre-auth', float(context.get("PurchaseAmountScr")))
return self.handle_order_placement(
order_details['order_number'], user, order_details['basket'], order_details['shipping_address'],
order_details['shipping_method'], order_details['shipping_charge'],
order_details['billing_address'], order_details['order_total'], **order_details['order_kwargs']
)
#for cancel situationelif status == "CANCELED":
self.restore_frozen_basket()
return redirect("basket:summary")
#for decline stiuationelif status == "DECLINED":
self.restore_frozen_basket()
return redirect("basket:summary")
defrestore_frozen_basket(self):
"""
Restores a frozen basket as the sole OPEN basket. Note that this also
merges in any new products that have been added to a basket that has
been created while payment.
"""try:
fzn_basket = self.get_submitted_basket()
except Basket.DoesNotExist:
# Strange place. The previous basket stored in the session does# not exist.passelse:
fzn_basket.thaw()
if self.request.basket.id != fzn_basket.id:
fzn_basket.merge(self.request.basket)
# Use same strategy as current request basket
fzn_basket.strategy = self.request.basket.strategy
self.request.basket = fzn_basket
After your post, you will be redirected to thank you page.
Post a Comment for "Integrating A Redirection-included Method Of Payment In Django-oscar"