Cloudkibo / KiboPush

0 stars 1 forks source link

Explore and apply for Shopify Sales Channel SDK to create orders using Chatbot #10723

Open ImranBinShoukat opened 3 years ago

ImranBinShoukat commented 3 years ago

This task is to add payment method options in WhatsApp & Messenger ecommerce chatbots. After proceed to checkout, it should ask which payment method do you want to select. Cash on Delivery (COD) or E-Payment.

If customer selects E-Payment then we will generate the checkout link and ask him to complete the transaction using this link.

If customer selects Cash on Delivery then we should place the order and provide order number back to customer.

sojharo commented 3 years ago

I am currently reading on the shopify about Sales Channel SDK and we have to separately apply for this to get approval. Once we have this Sales Channel SDK approval, only then we can create the order using their API and get order number from shopify.

In the meantime, on our chatbot level, we can add the message blocks to ask payment method and if it is COD, then we will give the fake order number (which is not actually created on shopify) and store the cart information so that when customer asks for order status using order number, we can give that from our mongodb. I am opening separate issue for this for baqar https://github.com/Cloudkibo/KiboPush/issues/10735

In the meantime, I am today reading more on Sales Channel SDK and applying for it as it is little bit complex. I will update more here today once I complete reading on this. For now, it is not letting me apply for Sales Channel SDK so I am reading and understanding the requirements. The reason that they are giving is that we already have stores installed on our app so we can't apply for Sales Channel SDK.

Screenshot 2020-12-22 at 15 34 11

I am reading up more on the following links and contacting their support to let us apply. I will also create the duplicate app so that I can remove installs from this app and apply for Sales Channel SDK.

https://shopify.dev/tutorials/build-a-sales-channel-onboarding-and-account-connection-flow https://shopify.dev/concepts/channels https://shopify.dev/tutorials/build-a-sales-channel-with-the-checkout-api https://shopify.dev/tutorials/sell-through-the-checkout-api https://shopify.dev/docs/admin-api/rest/reference/sales-channels/checkout

I am updating the title of this task to explore and apply for shopify sales channel SDK.

sojharo commented 3 years ago

I have filled the form to apply for Shopify Sales Channel SDK so that we can create orders on Shopify using API instead of redirecting to checkout link where Shopify UI is used to create shopify order. I have read the requirements and sales channel types before filling the form so that it only talks about our specific use case.

https://docs.google.com/forms/d/e/1FAIpQLSet3NDZ2mGSJhTa31-c9aOf13grbDnmtHQ40ycgmFkxsQVu5Q/viewform

I have thoroughly investigated and understood the Shopify Sales Channel SDK. Here are the main points that are useful for our discussion:

After reading on shopify docs, I was able to understand that manual payment methods such as cash on delivery methods are not available on test shopify stores. Therefore, we also had to switch to bogus gateway credit card payment system on our test store. I think they need to have a paid store in order to allow cash on delivery payment method. Previously, it used to allow the cash on delivery on our test store, but then they changed it so I had added the bogus gateway.

They talk more about this on the following link: https://shopify.dev/tutorials/manage-test-orders-with-rest-admin-api

I have found the way around this after reading couple of APIs and understanding the workflow. We will just create an order in Shopify store without giving any payment method to it. To the shopify, the order will always be incomplete as we have not attached the payment method (neither COD or credit card) but for our use case it will be enough that order will be created and we will get the order number.

However, in order to have complete experience of letting the customer see the order status, we will have to go through complete checkout experience where we need to attach payment methods and shipping information so that customer will be able to track order status correctly. For this, I have applied to shopify to get access to Sales Channel SDK which opens up the Checkout API and Payment method API for us.

Checkout remains incomplete until the following things are done:

  1. Items added in cart
  2. Payment method selected
  3. Shipping method provided
  4. Addresses provided
  5. Complete the checkout to create order number

In our workaround that I am going to do following on the API layer:

  1. Items added in cart (we do this on our database level currently, we will not change this, in order to do this on shopify database, we need checkout api)
  2. Create the order directly (without providing payment method or shipping method information)

This will not create the order with correct payment method (COD in our case) in shopify backend, however for our demo purposes it will work. In the meantime, we will get approved from shopify for sales channel sdk and also we will create basic paid store so that we can add COD payment method.

I am going to add this workaround in our api layer code and will update here once done.

sojharo commented 3 years ago

I have completed the workaround code in this as per above discussion. I am assigning @bjafri5 to test this. Api layer work is complete for this. @bjafri5 can continue the chatbot layer work in #10735

bjafri5 commented 3 years ago

Tested on staging

sojharo commented 3 years ago

Today's meeting minutes around this task:

We need to explore and understand following two payment workflows for credit card

Priority:

  1. Do COD first using paid account
  2. Do the credit debit card work

We will later do same work for bigcommerce

jekram commented 3 years ago

what is the update?

bjafri5 commented 3 years ago

@sojharo It does not create an order (it returns an empty object) for the following payload when doing COD:

{"id":"3399829389375"} (commerceCustomer) [{"variant_id":"33276318744639","quantity":2}] (lineItems)

please look into it

sojharo commented 3 years ago

@bjafri5 I think you are not accessing the response object correctly. I was able to see multiple orders created by you appearing in shopify admin UI.

Screenshot 2020-12-25 at 10 10 23

Also, I tried creating the order with your given customer id and I was able to create the order and get the response from the API layer:

Screenshot 2020-12-25 at 10 30 51

This is how this new order looks like in shopify merchant web site:

Screenshot 2020-12-25 at 10 40 45

I was also able to create new order on your complete payload given in above comment. This is the response and order was created:

Screenshot 2020-12-25 at 10 44 20

Please show me your chatbot side logic on Monday.

bjafri5 commented 3 years ago

I have made the change with how the response was being accessed. This is working fine now

sojharo commented 3 years ago

I have read further on Shopify about payments using credit and debit card. I have summarized it below:

For Credit Cart payments, Shopify support two types of payments providers: direct payment providers and external payment providers.

Direct payment providers

A direct payment provider is a form of payment that is included on the Shopify checkout. A customer completes their payment on the Shopify checkout, and is not redirected at any time during the checkout process.

External payment providers

An external payment provider integrates with Shopify. When your customer completes their order, they are redirected away from the Shopify checkout to complete their payment with the external payment provider. When payment is complete, your customer is redirected back to your store to view their order summary and confirmation page.

Customer Credit Card Information

Sales channel SDK approved apps can use the Checkout API to send the customers' credit card information to Shopify and complete their payments using API. Currently, we are using Shopify's web checkout which lets customers add their credit card information in Shopify UI and shopify charges it on order completion.

In order to do direct payments by asking customer credit card information and then sending it to shopify, we need to have our chatbot / app have higher PCI compliance scope. Shopify recommends:

You can reduce your PCI scope by using a third-party service, like Stripe or Spreedly, to send the card information.

We can use a third-party service to tokenize your customers' credit card information and send it to Shopify. By tokenizing this information, we reduce the PCI compliance scope for payments using our sales channel app (chatbot).

We will have to understand what it takes to get PCI compliance and following website may help us:

https://www.pcisecuritystandards.org

Here is the flow for how we can send the credit card information directly to shopify using their Checkout API from our app:

Screenshot 2020-12-25 at 16 27 41

Flow diagram description:

  1. The customer initates the checkout process.
  2. Our sales channel app (chatbot) uses the Checkout API to create a checkout object in Shopify.
  3. Shopify returns the checkout information to our sales channel app (chatbot).
  4. Our sales channel app (chatbot) passes the credit card information to Shopify's PCI compliant card server.
  5. Shopify's card server returns a payment session ID to our sales channel app (chatbot).
  6. Our sales channel app uses the Checkout API to pass the payment session ID to Shopify.
  7. Shopify processes the payment using the merchant's payment gateway.

Card Vaulting

Our app needs to submit the credit card information to Shopify Card Vaulting to ensure customer confidentiality. These vault processing is done on separate endpoints and return the session id that our app can use to create payment for the credit card.

Completing the purchase

In order to make the payment, we will now use the session id that we need to obtain in above paragraph. This will complete the purchase on the store.

Requirements

Only requirement to use the Checkout API is to get listed as Sales Channel with Shopify.

Endpoints

STORE CREDIT CARD INFO IN VAULT

Credit cards cannot be sent to the Checkout API directly. They must be sent to the card vault, which in response will return a session ID. This session ID can then be used when calling the POST #{token}/payments.json endpoint.

https://shopify.dev/docs/admin-api/rest/reference/sales-channels/payment#create_payment_session-2020-10

MAKE A PAYMENT USING SESSION ID

Creates a payment on a checkout using the session ID returned by the card vault

https://shopify.dev/docs/admin-api/rest/reference/sales-channels/payment#create_payment-2020-10

Getting the existing customer credit card information from Shopify

It is not possible to directly get the customer's existing credit card information from shopify unless customer has done any order in the past and we have access to that order (only last 60 days order can be retrieved, we can apply to remove this restriction). Customers credit cards can't be directly retrieved by giving customer id to the api. We need to go through the orders table and transactions table to get previous order transactions. These transactions will contain the credit card information of the customer.

https://www.highviewapps.com/kb/how-can-i-retrieve-the-credit-card-information-that-was-used-to-place-the-order/ https://shopify.dev/docs/admin-api/rest/reference/orders/transaction

References

https://help.shopify.com/en/manual/payments/third-party-providers/direct-and-external-providers https://shopify.dev/tutorials/complete-a-sales-channel-payment-with-checkout-api https://shopify.dev/tutorials/sell-through-the-checkout-api#card-vaulting https://shopify.dev/tutorials/sell-through-the-checkout-api#completing-the-purchase https://shopify.dev/docs/admin-api/rest/reference/sales-channels/payment

sojharo commented 3 years ago

As per our discussion, I read up more on external payment providers and API to use them. This is not complete yet and I need to read a bit more and see some tutorials to understand it. My most time was spent on chatbot work yesterday.

sojharo commented 3 years ago

I have completed reading on external payment providers and how to use them using api to charge our customers:

There are two external payment providers on which Shopify documentation give details. Stripe and Spreedly.

Stripe:

I am focusing on Stripe here as this is common and we have also used it. Work from shopify API side is same for both stripe and spreedly. Just creating accounts and connections on these payment providers differ from each other.

In order to use Stripe as third party payment provider between KiboPush and Shopify, we need to create a Stripe platform account with Connect integration, to process credit cards as a Shopify channel app.

Flow:

Screenshot 2021-01-07 at 09 23 56
  1. Customer initiates checkout.
  2. Kibo Chatbot uses the Checkout API to create a checkout.
  3. Shopify returns the shopify_payments_account_id.
  4. Kibo Chatbot sends the merchant's managed account id and the customer's credit card information to Stripe to generate a token.
  5. Kibo Chatbot uses the Checkout API to create a payment transaction, and it passes the token from Stripe to Shopify.
  6. Shopify processes the payment using Shopify Payments.

Uptil now, there are few things which are confusing me in this that I am trying to understand more i.e. why we still need to send card information to stripe. I think I will have to read up on Stripe connect and understand how it works. Shopify has explained there flow but not how we will go and get token from Stripe.

I will read up from stripe side and update more on this.

References

https://stripe.com/docs/connect https://stripe.com/docs/connect#register-platform

sojharo commented 3 years ago

After reading more on shopify plus stripe, I came to learn that shopify integration with stripe is for the purpose so that merchant gets payment in their Stripe account.

Requirements for payment processing with Stripe

This should be read after above comment.

From the documentations and stripe, I think there are two things which are becoming obvious.

  1. Stripe integration is not for end customers but it is to integrate with merchants stripe account. i.e. If merchant has account in Stripe and he has enabled Shopify Payments then he can integrate his Stripe with Shopify.
  2. We (KiboPush chatbot) still has to ask customer for credit card information and send it to Stripe with merchant's stripe id. Stripe will then return us back the create access token for that merchant against customer credit card.

Initially, I was thinking that customer (purchaser) will be redirected to Stripe and do the payment.

We will have to individually integrate with merchant's stripe account once we have integrated with Stripe. This is same as we do with Facebook login where admin's let our app access to their account. Similarly, we will let the merchants integrate their Stripe account with our application just like they integrated Shopify with us.

The diagram in above comment also implies that we have to get shopify merchant payment accounts id and then send it to Stripe along with credit card information of end customer.

For the end customer, I think we need to fetch the credit card information from them in any secure way and then send it to Stripe. We should not store this information and just get it securely and transfer it securely to payment providers. I think this is the reason that shopify asks for separate request submission for Shopify Sales Channel SDK.

Once we have access to merchant's Stripe account, then we can create and store customers in that merchant account. So, next time if same customer is making purchase on that merchant, we will not ask for credit card information again. We will know that this customer's credit card is already sent by us on merchant's stripe. So we will just fetch the customer id and then complete the checkout process. So this time, we will send the customer id to stripe to charge instead of credit card information.

So in this case, instead of vaulting in shopify vault, we are vaulting customer's credit card in stripe vault so that stripe will save it securely there. And we will not have to store or ask the credit card infomation again and again. Asking the credit card information on whatsapp or messenger is not safe because it will remain in chat history. I think we will have to think of some secure way to obtain customer credit card for the first time.

One other thing that we can do is that we will first check if that customer is already created on merchant's stripe account, if so then we will just call stripe apis to charge the merchant and in return create successful order with payment in shopify.

Stripe api itself has lots of things in their API, i.e. from customers to products and orders to checkouts. I think we only need the part of their API where we send them customer information and card information once and then token will be given us for that customer instead of using card.

https://stripe.com/docs/api/tokens/create_card

I think the reason for this is that end customers usually don't have accounts on stripe or paypal therefore we can't redirect end customer to stripe. We can let the merchant connect their stripe account with us and then we can redirect customer to the stripe payment page or shopify checkout page. There are payment integrations available from Stripe for client side to get customer credit card information securely. https://stripe.com/docs/payments

Let's discuss this tomorrow and things will become more clear.

Reference:

https://shopify.dev/tutorials/complete-a-sales-channel-payment-with-checkout-api https://shopify.dev/tutorials/authenticate-a-public-app-with-oauth#request-payment-processing

jekram commented 3 years ago

@sojharo what is the next step here?

sojharo commented 3 years ago

I had done the investigation on external payment integration with shopify on this and discussed. We can just discuss this and decide the next step. I will bring this in status meeting to discuss. I think I had sent it on slack but forgot to discuss this in status meeting