Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strong Customer Authentication #122

Closed
mikedoubintchik opened this issue Apr 30, 2019 · 31 comments · Fixed by #128
Closed

Strong Customer Authentication #122

mikedoubintchik opened this issue Apr 30, 2019 · 31 comments · Fixed by #128

Comments

@mikedoubintchik
Copy link

Stripe is going to be requiring Strong Customer Authentication (SCA): https://stripe.com/guides/strong-customer-authentication

Will this library support it?

@darylp041
Copy link

It would be good to know if this will be supported or not.

@aelvan
Copy link

aelvan commented May 16, 2019

+1 Some feedback on whether this is being worked on or not would be great.

@mmikkel
Copy link

mmikkel commented May 22, 2019

+1, feedback on this would be much appreciated.

@nilsnh
Copy link

nilsnh commented Jun 3, 2019

This issue seems related to this one: #79.

For a fix to this issue we might look to how Craft Commerce has added Stripe 3d Secure support: https://github.com/craftcms/commerce-stripe ?

@th0rn0
Copy link

th0rn0 commented Jun 13, 2019

Any updates on how this is progressing if at all?

The cut off for the SCA on EU cards is approaching...

@samdb
Copy link

samdb commented Jun 21, 2019

It would be good to know if anyone has already started work on this before I look at doing a PR.

@munagurung
Copy link

any update?

@DidoMarchet
Copy link

+1

1 similar comment
@stefanomarodin
Copy link

+1

@darylp041
Copy link

@samdb given how quiet it is, it's unlikely. More than happy to help (if needed).

@andris-sevcenko
Copy link
Contributor

@samdb Did you manage to get something going on the PR? I'm planning to start a PR that adds a Gateway that utilizes Payment Intents API, but if you've already started then duplicating work seems silly.

@barryvdh am I safe in assuming that there's no other effort to make this package work with SCA in progress (that you know of)?

@samdb
Copy link

samdb commented Jul 8, 2019

No, to be honest I was playing chicken to see if anyone jumped in first. If I can help pay for some dev hours let me know as this will be useful for me.

@dankingsley
Copy link

Also interested in knowing about the future of this...

@m2de
Copy link

m2de commented Jul 15, 2019

Ok, really need to get something moving on this or we'll have to switch to Stripe's own wrapper. Would be nice to have some response from the package maintainers on this, even if it's a "we have no plans to look at this"? @barryvdh @amacneil

This also covers #118 to switch to the PaymentIntent API which is required for the SCA implementation. Furthermore, there are discussions on other Drivers relating to this, e.g. thephpleague/omnipay-sagepay#135.

For anyone who has not looked into the details, I'm quite sure that this won't be a simple "Upgrade to the latest version of OmniPay" upgrade to your codebase. There are definitely process changes required for SCA compatibility, client and server side!

So my understanding of the PaymentIntent/SCA implementation is that it offers an Automatic and a Manual confirmation option. The Manual option seems to be more suitable for implementing with OmniPay as it doesn't require Webhooks to be used. https://stripe.com/docs/payments/payment-intents/quickstart#manual-confirmation-flow

From what I can tell, one additional (new) step will be required, which is to check if additional authentication is required from the Client. I imagine where one would usually check $response->isSuccessful(), an additional check for $response->requiresClientAuthorisation() or similar would then allow for passing data back to the client to open the 3D Secure process? After this it would post back into the same/old loop to check for successful payment.

Due to my lack of knowledge of the OmniPay codebase / process I'm unsure exactly how something like this would be implemented whilst maintaining compatibility with other payment gateway implementation? Would this require a change to the OmniPay core or just the Stripe implementation?

Any input would be greatly appreciated to determine if I'm wasting my time looking at implementing a solution or if OmniPay is simply not compatible with the new SCA legislations?

@barryvdh
Copy link
Member

See #79 (comment)

I currently have no plans to support this myself as I'm not using Stripe and am not sure about the implications.

@andris-sevcenko
Copy link
Contributor

I'm currently working on a PR for this.

It's not small and definitely not trivial. Thankfully, I'm in the final stretch and expect to wrap it up by the end of this week at which point I'll squash it and open a PR.

There are some potential friction points I'd like to address:

  • Realistically, there will be bugs and I hope that the community will pitch in with fixing them, since the bulk of the work will be complete already.
  • It will probably not be a feature complete gateway for Payment Intents - some advanced features (for example, SetupIntents) will be missing, but it will cover 99% of the needs and will be a decent enough of a temporary solution to last for the foreseeable future.
  • To help out all the stragglers who are stuck on Omnipay 2.x, once this is opened and merged, I'll open a new PR which will be a slightly modified version for the 2.x branch. The reason for this is that there are platforms out there that use both Stripe and a gateway that does not have an Omnipay 3.x version, so they'd be stuck without SCA. I hope that nobody has qualms about making a 2.x release as well.

@andris-sevcenko
Copy link
Contributor

(ping #79)

@m2de
Copy link

m2de commented Jul 15, 2019

Thanks @barryvdh for the response, apologies I did not see the response on the other issue.

That's great news @andris-sevcenko . Could you share some details about the confirmation you are implementing (e.g. Automatic or Manual) and what the final process would look like?

If there's anything I can do to help please let me know. Have projects on stand-by which I can use for testing the implementation.

@andris-sevcenko
Copy link
Contributor

andris-sevcenko commented Jul 16, 2019

@m2de I'm definitely going with the manual confirmation. Using automatic confirmation would needlessly complicate implementing this package for people and there's a lot of reluctance for webhooks out there, still, which might deter people.

The final process, hopefully, is probably ending up something like this:

  1. Create the payment method using Stripe.js. (Step one here)
  2. Create a payment method
$paymentIntent = $gateway->authorize(array(
    'amount' => '10.00',
    'currency' => 'USD',
    'description' => 'This is a test purchase transaction.',
    'paymentMethod' => $paymentMethod,
    'returnUrl' => $completePaymentUrl,
    'confirm' => true,
));
$response = $paymentIntent->send();
  1. If confirm was not set to true, then manually confirm the transaction (skip this step, otherwise)
$confirmation = $gateway->confirm(array(
    'returnUrl' => $completePaymentUrl
    'paymentIntentReference' => $response->getPaymentIntentReference(),
));
$response = $confirmation->send();
  1. Take note of the payment intent ID from the response.
  2. If $response->isSuccessful(), congrats, no 3DS 2.0! Otherwise, if $response->isRedirect(), redirect accordingly.
  3. In your endpoint that $completePaymentUrl refers to, retrieve the ID of the payment intent you stored.
  4. Check if we're good
$intentData = array(
    'paymentIntentReference' => $paymentIntentReference,
);

$paymentIntent = $gateway->fetchPaymentIntent($intentData);
$response = $paymentIntent->send();

if ($response->requiresConfirmation()) {
    $response = $gateway->confirm($intentData);
}

if ($response->isSuccessful()) {
    // All done.
}
  1. If not successful, go back to step 1.

Edit: Modified step 7 to reflect that the payment intent has to be confirmed in the very end.

@barryvdh
Copy link
Member

But isn't the new way just a basic off-site payment request, which is redirected and must be completed there, after which the notify url is called?

@barryvdh
Copy link
Member

@andris-sevcenko
Copy link
Contributor

@barryvdh not entirely. Checkout is entirely off-site. Payment Intents is on-site, except for 3DS 2.0 step (if it's required). Also, it allows avoiding the notify url flow, which reduces the implementation friction.

Also, as far as step 7 in the above flow goes, the fetching of payment status is not necessary.

I'll submit a PR today, so we can definitely continue the conversation there. Seeing as this is my first time writing anything for Omnipay, there'll probably be some changes needed in my code. Can't expect to get it all right on the first try.

@barryvdh
Copy link
Member

FYI, I have merged #128 which you can now test with the 3.1@dev version (alias to dev-master)

@prodigeris
Copy link

prodigeris commented Jul 22, 2019

@andris-sevcenko Payment Intents are used for off-session payments as well. You just need to use Setup Intent flow beforehand to prepare the payment method.

@andris-sevcenko
Copy link
Contributor

@prodigeris Sure. Seemed a bit out of scope for "can we get something in Omnipay Stripe that supports SCA", though.

I still feel like the first priority was to get something in so that people can use it before deadline hits. All the bells and whistles can come after.

@prodigeris
Copy link

I completely understand and I really appreciate your work!

Just wanted to point out for someone who may be in the same boat as me that SetupIntent is needed in those cases when you want to authenticate the payment method and use it for later charges.

@paulfazz
Copy link

I'd argue that MIT/off-session based payments are pretty common so SetupIntent support isn't something I'd bucket as "bells and whistles". However I appreciate that supporting the most common use case as a priority is what's most important right now.

For our usage we're probably going to have to switch to Stripe's own lib while support for this is being baked into omnipay-stripe. We were passing tokens to the backend and using omnipay for the actual authorisation/payment anyway so we have to pretty much revamp the whole flow as part of this....

@andris-sevcenko
Copy link
Contributor

andris-sevcenko commented Jul 22, 2019

Just wanted to point out for someone who may be in the same boat as me that SetupIntent is needed in those cases when you want to authenticate the payment method and use it for later charges. (@prodigeris)

I'd argue that MIT/off-session based payments are pretty common so SetupIntent support isn't something I'd bucket as "bells and whistles". However, I appreciate that supporting the most common use case as a priority is what's most important right now. (@paulfazz)

I completely agree with both of you, but there are a bunch of implications here which all stem from how much Stripe is driving the expectations for 3rd party gateway libs.

SetupIntent is definitely used in the context of subscriptions. This repository had subscriptions support added a while back via a pull-request, however, subscriptions vary so wildly between, for example, Stripe and Brain Tree, it's virtually impossible to define the structure for them in Omnipay Common. This drives a wedge between Omnipay Stripe and Omnipay Common.

Piling on top of that just makes the separation even more obvious and at some point, you have to decide who is the authority on all of that. @barryvdh said he doesn't use Stripe so, as the feature set expands, it's going to make smaller and smaller sense for him to be vetting code he himself doesn't use and, by extension, doesn't test in the field.

I mean, I guess, what I'm saying is, that I think this gateway might have feature-creeped past what Omnipay defines itself to be - a "payment processing library". This is rapidly starting to feel like a "billing platform". And I'm pretty glad I'm not on the spot to make any decisions here :)

Edit: readability.

@barryvdh
Copy link
Member

IMHO Omnipay mostly makes sense if you're mostly doing what 90% of gateways can do, eg. accept payments. Things like recurring/subscriptions etc are hard to unify so not sure it make a whole lot sense.
If I was building on specific Stripe functionality, I would always just use Stripe.
If I'm just building a checkout for my products, I'd use Omnipay.

@prodigeris
Copy link

@barryvdh Payment Intents and Setup Intents definitely are Stripe functionality, however, what comes underneath it -- is not.
It's called 3D Secure 2.0 and most payment gateways that work with the EU already have this functionality implemented due to SCA.
However, the Stripe decided to change their API to a new one while most other gateways kept the same.

@andris-sevcenko
Copy link
Contributor

It's called 3D Secure 2.0 and most payment gateways that work with the EU already have this functionality implemented due to SCA.

To be fair, most payment gateways are off-site and nothing really had to change there for site developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.