Oscar-api Order Placement issue
theArsalanM opened this issue · comments
From Django-oscar's code, an Order is placed by calling handle_order_placement(...)
from apps/checkout
.
def handle_order_placement(self, order_number, user, basket,
shipping_address, shipping_method,
shipping_charge, billing_address, order_total,
**kwargs):
order = self.place_order(
order_number=order_number, user=user, basket=basket,
shipping_address=shipping_address, shipping_method=shipping_method,
shipping_charge=shipping_charge, order_total=order_total,
billing_address=billing_address, **kwargs)
basket.submit()
return self.handle_successful_order(order)
This works perfectly fine for oscar, but in django-oscar-api's implementation of Order placement, I wonder why place_order(...)
is called directly instead of sticking to oscar's default approach? Maybe we need to create oscar-api's own OrderPlacementMixin to rewrite Restful structure for handle_successful_order()
.
Oscar API places order by calling place_order()
directly from serializers/checkout
.
The problem? It ends up with 2 issues:
- Order Confirmation email is not being sent when Order placed via API
- Basket status remains
Frozen
even after order placement. It should have been changed toSubmitted
I wanted to understand is it intentionally left behind for developers to implement on their own, or can we add it to core code?
One of the reasons that we can't use Oscar's handler_order_placement
is that the handle_successful_order
method is not really generic:
# Flush all session data
self.checkout_session.flush()
# Save order id in session so thank-you page can load it
self.request.session['checkout_order_id'] = order.id
response = HttpResponseRedirect(self.get_success_url())
In the API we don't use a session, nor is the HttpResponseRedirect
a desired response.
Next to that, the flow of OscarAPI is a bit different. There is a possibility that payment fails for example, or that a user cancels one of the payment methods. Then you would want to resubmit your basket again with another payment method. That's why we don't set the status to submitted at this point and do not send a confirmation email yet.
This is also explained in a note in the documentation: https://django-oscar-api.readthedocs.io/en/latest/topics/communicate_with_the_api.html#place-an-order-checkout
It's up to the developer what to do from here. It can be as easy a registering a receiver
for the oscarapi_post_checkout
signal and you call the methods you would like to call:
@receiver(oscarapi_post_checkout)
def post_checkout(sender, **kwargs):
# send email, do some checks, submit basket etc.
See also the oscar-api-checkout plugin which continues where oscarpi stops, including a nice wrapper for sending the confirmation email.