daffodil icon indicating copy to clipboard operation
daffodil copied to clipboard

[FEAT] Support for Modern Payment Providers in Checkout

Open damienwebdev opened this issue 5 years ago • 9 comments

:bulb: Feature request

Feature Name

Modern Payment Method Support (PCI A/A-EP)

The Desired Behavior

Currently, we don't have any supported payment methods in the @daffodil/checkout. We should support some modern payment providers.

Your Use Case

As a user, I would like to pay for my order. As a small sample, we should support at a bare minimum:

  • [ ] Stripe (via Stripe.js) (cc: @thorsten-stripe)
  • [ ] Paypal (via Braintree Payments) (cc: @crookedneighbor)
  • [x] Paypal (via Paypal Express)
  • [x] Authorize.net (via Accept.js) (cc: @brianmc)
  • [ ] Cybersource (via Flex Microform) (cc: @brianmc)

Others

I'll (@damienwebdev) be taking on the bulk of the implementation work. Some key considerations:

  1. Library consumers shouldn't have to import the payment modules that they don't use.
  2. Obviously not all ecommerce systems support all these providers, but we should at least cover the frontend side of the libraries.
  3. In the case of Shopify, we'll have to ensure that we have good enough clarity that you shouldn't be using these libraries.

I've cc'd some devs from these companies that I can find on Github, as I think while we can probably implement this ourselves, having the original authors will probably we super helpful.

To the cc'd devs, you can ignore the cc if you'd like, but if you're curious, I'm using this to help get some uptake of your library!

damienwebdev avatar Mar 25 '19 17:03 damienwebdev

@damienwebdev thanks for the tag. A couple thoughts and questions:

  1. For Shopify you're probably best of using: https://shopify.github.io/js-buy-sdk/ . See an implementation of this here: https://github.com/gatsbyjs/store.gatsbyjs.org
  2. For Magento 2, are you looking to use the Magento Checkout, or bypass it and only use the product/order endpoints?
  3. In-Memory Backend: any more details on this? Server-side language; Hosting options; etc?

For Stripe, my recommendation is to use our new hosted Checkout product, which will give you many payment methods with one simple integration in the future: https://stripe.com/docs/payments/checkout

Hope this helps, and looking forward to hearing back from you.

thorsten-stripe avatar Mar 25 '19 20:03 thorsten-stripe

@thorsten-stripe

  1. Yeah, awesome never saw that, thanks for the pointer. I suspect that we may end-up doing just that. My original thought was to utilize the storefront API and work from there, but this may be a neat little way to short-circuit a lot of that development effort. My only concern here is determining how much of the library that we don't use we can tree-shake out with the compiler. If the bundle is too large, I may just write a thin layer between the frontend and the Storefront API via Apollo.

  2. The plan here is to use the Magento REST Checkout APIs and directly work with the Order/Quote endpoints. Long term here the goal would be to utilize the GraphQL endpoints described here: https://devdocs.magento.com/guides/v2.3/graphql/

  3. Our in-memory backend is just a simple "In Browser" memory store for quickly mocking data for a store. It's for devs only, not something a customer would ever see, so nothing to consider hosting. It serves to mock our driver calls when we're just working locally.

Re: https://stripe.com/docs/payments/checkout I think that may be an option to consider, but my concern with that is that the point of this project is to provide a business consumer full control of the UX of the store. Stripe Checkout seems a bit antithetical to the goal, thus my feeling to go with Stripe.js.

damienwebdev avatar Mar 25 '19 20:03 damienwebdev

So would a checkout driver implementation just have to implement the interface DaffCheckoutServiceInterface here with only one method: placeOrder. Is that correct?

griest024 avatar Jan 04 '20 03:01 griest024

Is it assumed that the products will be added through an external service? The product service interface doesn't have methods for adding products.

Checking out with stripe through their REST API necessitates creating order items in the stripe DB. This would make sense to do through a stripe product driver if the service declared product creation methods.

From there you run into issues of data integrity when mixing and matching drivers; if the client chose shopify to manage their products, the library would have to ensure that changes through the shopify driver would be reflected in the stripe DB.

How should I proceed? Should I implement the stripe checkout driver agnostically and assume that the available data has what I need to checkout with stripe or should I implement additional drivers and modify service interfaces as needed?

griest024 avatar Jan 04 '20 20:01 griest024

@griest024 The flow here basically follows like this:

Typically, a user will generate a cart (handled by other @daffodil/modules with their particular platform of choice (e.g. Magento, Shopify, etc). Our process will be to use a particular processor's library (Stripe, Authorize.net, Cybersource, etc., Braintree, etc) to generate a credit card token during checkout,

We'll pass this information, along with a "cart" object to the particular platform, where the cart will be converted to an order and processed. This does imply that the "ecommerce" aspects of the system will all have to be orchestrated together, e.g. if you want to use Shopify, you'll only be able to use Payment processors supported by Shopify.

At the moment, the packages that all have to be bound to the same platform for the ecommerce packages to work are:

  1. @daffodil/product
  2. @daffodil/cart
  3. @daffodil/checkout

Unfortunately, at this moment, we haven't modeled exactly how we'd want this to work generically and Demo's implementation is hardly sufficient to use as a basis.

@lderrickable is currently working on an Authorize.net implementation of this payment process that would be able to "slot" into a generic checkout, so he may be the deepest in the weeds (and therefore the most knowledgeable) at the moment on the generic part of this.

At the very least to proceed on this we likely need a architecture blueprint on how this would work. This would involve:

  1. Defining an API for a generic Payment processor to implement that would allow a developer to use the payment processor agnostic to the platform (currently undefined)
  2. Defining an API for a generic Payment processor to hook into the @dafffodil/checkout module.

damienwebdev avatar Jan 05 '20 02:01 damienwebdev

@damienwebdev @lderrickable let me know if you have any questions or need any help on the Authorize.Net or CyberSource implementation. For CyberSource I would recommend the latest version of flex.js which has a transient token much more in line with Authorize.Net & Stripe. Also recommend the CyberSource REST APIs over any of the older SOAP versions. Apologies for missing this thread until now.

brianmc avatar Jan 05 '20 12:01 brianmc

@damienwebdev It looks like @daffodil/cart is also missing driver implementations, should I start by implementing some cart drivers?

griest024 avatar Jan 05 '20 19:01 griest024

@griest024 The cart driver is currently being worked on by @damienwebdev so probably don't make any changes there. In terms of

How should I proceed? Should I implement the stripe checkout driver agnostically and assume that the available data has what I need to checkout with stripe or should I implement additional drivers and modify service interfaces as needed?

A lot of the checkout driver is incomplete right now (I'll start doing a lot of work on it in the following couple of weeks), so probably just implement the stripe driver and assume that the available data will be there. When you're developing, try to keep in mind that the strip driver will need to follow an interface that will be as similar as possible to the interface that will be used by all other payment processors, but don't worry about following the DaffCheckoutServiceInterface because that is incomplete. Honestly, neither of us have done much thinking yet on what a payment processor will need, because we haven't worked through developing a driver for one yet (like @damienwebdev said, I'll be working on the Authorize.net one soon. Hopefully this week). So you could use your best judgement if you want to start on it now, or you could wait till I do the authorize.net driver when I'll have a bit more insight.

lderrickable avatar Jan 06 '20 17:01 lderrickable

@brianmc I've spent some time reviewing the Magento 2 Marketplace Module cybersource/[email protected] and it appears to have:

  1. No support for the Flex.js library at all
  2. No Magento 2 REST API Support
  3. No Magento 2 GraphQl Support

You have anyone who you can point me to for more information?

damienwebdev avatar Feb 07 '20 21:02 damienwebdev