DavidAJohn / PhotoPortfolio

Personal photo portfolio .NET web application which implements a Blazor and Tailwind CSS user interface with a MongoDb database, and includes integration with Stripe Checkout and Prodigi Print API
0 stars 1 forks source link

Shipping options #11

Closed DavidAJohn closed 1 year ago

DavidAJohn commented 1 year ago

At the moment, there is no option to choose different shipping methods. Standard delivery is assumed and hard coded when creating the quote and the order.

That was fine while developing the application and getting calls to Stripe and Prodigi working, but in production the application will need to give the customer options and assiciated costs, updating the quote from Prodigi if the choice changes.

DavidAJohn commented 1 year ago

This has now been changed so the shipping method can be chosen by the user. This is then used in the request sent to the Prodigi print API.

However, we need to pass this to the Stripe Checkout session (as a custom value?) so it is returned after a successful payment. It will need to be sent to Prodigi when we subsequently create an order.

DavidAJohn commented 1 year ago

Additional custom data can be passed to Stripe via 'metadata' fields. See the following StackOverflow discussion here:

https://stackoverflow.com/questions/55742393/is-it-possible-to-pass-custom-data-to-stripe-checkout

We will also need to send the product Sku and our own generated PhotoProduct id (to be sent to Prodigi later as MerchantReference).

DavidAJohn commented 1 year ago

I've hit a stumbling block around the metadata, which is going to mean making a significant change to the application's ordering process. Although on reflection, I think this will actually make the the process more robust. It's probably what I should have done in the first place.

The problem is that while you can pass data to Stripe in metadata fields, it appears that the metadata is not returned in a Checkout Session (via the webhook responses), unless it is stored in the root Metadata tag within the session. So you can supply line item metadata, for example and it will be visible in the Stripe Dashboard, but it is not included in the response even if you explicitly ask for line item details. My own testing confirms this.

I think the assumption from Stripe is that the client app will keep its own record of the line items before creating a checkout session, which is a legitimate assumption. Currently, this application only creates an order after receiving a successful payment response from Stripe. The idea was to avoid having redundant partial order entries, but this isn't neccessarily a bad thing if it allows abandoned orders to be tracked.

This will require some changes to be made, so now when a customer clicks 'Place Order' we need to create an order in the database first, including the verified basket contents and the delivery method chosen by the customer. The method that does this will need to return the auto-generated objectId string, which we will then send to Stripe in the checkout session metadata.

When the checkout session completes, we can then retrieve additional order details from the webhook response (name, email address, shipping address, etc.) and just update the existing order entry based on the Id.

That will give us a local database record of the order and more details available in the Stripe dashboard, allowing us to check for any possible discrepancies. It will make this initial part of the ordering process much more robust, before we ultimately place the order with Prodigi's print API.