Complete order from return URL

90 views
Skip to first unread message

quart...@gmail.com

unread,
Jul 3, 2023, 11:32:17 PM7/3/23
to django-oscar
Hi all

What I am doing:
Integrating Square as a payment method in my checkout, using their Checkout API with the Create payment link.
So the flow thus far for checkout is:
payment-method  "credit card" is selected > preview is displayed > Place order  > redirect to Square's payment link > the user enters required info to pay > Square then redirects the user to the return URL I gave them in the payload.
For this last part I created a Django app within the project, with a urls.py  that routes the return from Square into my view.py and a class based view.
This all works up to this point.

class SquareReturnView(OrderPlacementMixin, RedirectView):
template_name = "mysquare/square_return.html"

def get_redirect_url(self, **kwargs):
basket = Basket.objects.get(pk=self.checkout_session.get_submitted_basket_id())
basket_id = self.checkout_session.get_submitted_basket_id()
order_number = self.checkout_session.get_order_number()
user = self.request.user
shipping_address = self.get_shipping_address(basket)
shipping_method = self.get_shipping_method(basket, shipping_address)
billing_address = self.get_billing_address(shipping_address)

print(f"DEBUG: request: {self.request}")

submission = {
"user": self.request.user,
"basket": basket,
"shipping_address": shipping_address,
"shipping_method": shipping_method,
"billing_address": billing_address,
"order_kwargs": {},
"payment_kwargs": {},
}

if not shipping_method:
order_total = shipping_charge = surcharges = None
else:
shipping_charge = shipping_method.calculate(basket)
surcharges = SurchargeApplicator(
self.request, submission
).get_applicable_surcharges(basket, shipping_charge=shipping_charge)
order_total = self.get_order_totals(
basket, shipping_charge=shipping_charge, surcharges=surcharges, **kwargs
)

payment_kwargs = {}
order_kwargs = {}

signals.post_payment.send_robust(sender=self, view=self)
logger.info("Order #%s: payment successful, placing order", order_number)

try:
return self.handle_order_placement(
order_number,
user,
basket,
shipping_address,
shipping_method,
shipping_charge,
billing_address,
order_total,
surcharges=surcharges,
**order_kwargs,
)
except UnableToPlaceOrder as e:
msg = str(e)
logger.error(
"Order #%s: unable to place order - %s",
order_number,
msg,
exc_info=True,
)
self.restore_frozen_basket()
return self.render_preview(self.request, error=msg, **payment_kwargs)
except Exception as e:
logger.exception(
"Order #%s: unhandled exception while placing order (%s)",
order_number,
e,
)
error_msg = "A problem occurred while placing this order. Please contact customer services."

self.restore_frozen_basket()
return self.render_preview(self.request, error=error_msg, **payment_kwargs)


Where I'm getting stuck:
I'm presuming that in my view it needs to finish off what the "oscar.apps.checkout.views.PaymentDetailsView.submit() method usually does from the

except RedirectRequired as e:

line on wards as due to the redirect the flow in this method doesn't continue.

This currently results in a RuntimeError:

No strategy class has been assigned to this basket. This is normally assigned to the incoming request in oscar.apps.basket.middleware.BasketMiddleware. Since it is missing, you must be doing something different. Ensure that a strategy instance is assigned to the basket!

So I know a basket strategy needs to be set. How does one find out and apply the same basket.strategy that was applied to basket earlier in the checkout?

Or am I over complicating things and there is indeed a simpler way to finalize the checkout after a payment provider redirect?

Thanks

Reply all
Reply to author
Forward
0 new messages