Search code examples
e-commercepayment-gatewaydjango-oscar

Handling an order before/after redirecting to a form-based payment gateway


I'm using an e-commerce framework django-oscar (Oscar). In Oscar the checkout process is laid out like this:

  1. Collect shipping information.
  2. Select a payment method and collect payment details.
  3. Preview an order and confirm.
  4. Freeze the basket (to prevent manipulation), process the payment and place the order.

I'm integrating a form-based payment gateway (requires posting a form with payment details) and now the checkout process becomes messy:

  • a. Collect shipping information.

    b. Select payment method.

    c. Preview an order and confirm.

    d. Freeze the basket and place an unpaid order.

    e. Redirect to a payment gateway.

    f. On return mark the order as paid.

I'm stuck with these issues:

1) (c) and (d) have to be done in one step because there is no interaction between the site and a user before (e) - I can't POST-redirect the customer to a payment gateway so clicking 'confirm' moves him/her there directly. And as the order is already placed by the time the preview page is displayed it is impossible for the customer to go back from there - the basket will be empty. I can put another page between the preview and a payment gateway but that doesn't look like an elegant solution. Is there another one?

2) Placing an order means allocating items and removing them from the stock (other customers would not be able to buy them), otherwise by the time the customer returns from a payment gateway some items may become unavailable. Inevitably some orders will be left unpaid so items will be left reserved. When and how should they be 'unreserved' and moved back into the stock?

It seems to me that these problems are not Oscar specific so what are the best practices dealing with them?

Thanks!

P.S. I found some discussions of integrating form-based payment gateway in Oscar (https://groups.google.com/forum/#!topic/django-oscar/ccClzX6M9To , Integrating a redirection-included method of payment in django-oscar) but nothing about outlined issues.


Solution

  • remove the products from inventory after the transaction has completed. and display the new order number for the customer.

    let the customer know they are going to get an email with all of the relevant details including the products they just ordered.

    take the cart items and insert them to an order items database table. in other words the public cart table should be completely separate from the table you use to hold the order items. then you don't have to be concerned about 'freezing' the cart table, etc.

    What if the products become unavailable while the customer is on a payment gateway (some one else buys them faster)?

    for most merchants this will not happen very often. but in the course of normal business there are going to be different conditions why a product is not in stock. the merchant then contacts the customer to see if there is another item that is suitable or they refund the transaction.

    that said if you have a product like concert tickets for specific seats or limited edition prints that sell out in a few minutes, then you need a different system.

    basically you would tell the customer up front that you are going to hold the item for say 5 minutes - enough time for them to complete the transaction. and you are reminding them at each step that if they don't complete the purchase they could lose the item.