Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know that 3D Secure 2 authentication works after upgrading to stripe.js version 3

I have updated a site so it uses latest stripe-php (6.39.0) and it now loads stripe.js version 3. I’ve made all the necessary changes to my code so that my credit card fields are now displayed using Stripe Elements. Test transactions work and I have updated the live site and real payments are being excepted.

The reason I made this update was because I was informed by stripe that I needed to upgrade the site so that its stripe integration will work with Strong Customer Authentication (SCA) which is required in the EU by September 2019.

Stripe has different credit card test numbers you can use to test things that arise when processing payments. This numbers can be found here: https://stripe.com/docs/testing#cards

4000000000003220 simulates a transactions where 3D Secure 2 authentication must be completed. But when I use this code stripe turns down payment and returns the message:

"Your card was declined. This transaction requires authentication. Please check your card details and try again."

Does this mean that 3D Secure 2 is working or not?

In the real world it would open a window with an interface from the customer's card issuer. So I not sure wether my integration is working or not. As said before payments are being excepted butI need to ready when Strong Customer Authentication is required in September.

like image 510
lomokev Avatar asked Jun 25 '19 18:06

lomokev


People also ask

How do I turn on 3D Secure authentication stripe?

Step 1: The customer enters their card details. Step 2: The customer's bank assesses the request and can complete 3D Secure at this step. Step 3: If required by their bank, the customer completes an additional authentication step.

How do I validate 3D Secure?

For extra fraud protection, 3D Secure (3DS) requires customers to complete an additional verification step with the card issuer when paying. Typically, you direct the customer to an authentication page on their bank's website, and they enter a password associated with the card or a code sent to their phone.

How do I know if my card has 3D Secure?

Chances are that your bank automatically enrolled your card in 3D Secure when it was issued. If you've never made an online purchase with your card and you're unsure if your card is registered, it's best to contact your bank directly to check.

Why is 3D Secure not working?

This means that the cardholder hasn't entered their details correctly. A 3D secure authentication error could be due to everything from a mistyped card number to an incorrect expiration date. If the error continues, the cardholder will need to contact their credit card issuer for assistance.


Video Answer


1 Answers

It seems you have an integration problem with the JS part. For a simple charge (the following example does not work for subscription), this is the way you have to implement it:

First you have to create a Payment intent (doc here: https://stripe.com/docs/api/payment_intents/create):

\Stripe\PaymentIntent::create([
  "amount" => 2000,
  "currency" => "usd",
  "payment_method_types" => ["card"],
]);

Once your PaymentIntent response is returned, you will have a client_secret key (doc here : https://stripe.com/docs/api/payment_intents/object). You can see that your payment status is "requires_payment_method"

{
  "id": "pi_1Dasb62eZvKYlo2CPsLtD0kn",
  "object": "payment_intent",
  "amount": 1000,
  "amount_capturable": 0,
  "amount_received": 0,
  ...
  "client_secret": "pi_1Dasb62eZvKYlo2CPsLtD0kn_secret_6aR6iII8CYaFCrwygLBnJW8js",
  ...
  "status": "requires_payment_method",
  ...
}

On your server side you have to save this object. You can now show your payment form with the JS part with the previous client_secret key (doc here : https://stripe.com/docs/payments/payment-intents/verifying-status). The idea is that you have to call the Js function on click on the submit button but do not submit ! Wait for the response to submit. With some jquery this should like this:

var $mySubmitButton = $('#my-submit-button'),
    $myPaymentForm = $('#my-payment-form'),
    clientSecret = $cardButton.data('client-secret'); // put your client-secret somewhere

$mySubmitButton.on('click', function(e) {
  
    e.preventDefault();

    // Disable button to disallow multiple click
    $(this).attr("disabled", true);

    stripe.handleCardPayment(
        clientSecret,
        {
            payment_method: clientMethod, // if you have a clientMethod
        }
    ).then(function(result) {
        if (result.error) {
            // show error message
            // then enable button
            $mySubmitButton.attr("disabled", false);
        } else {
            // Submit form
            $myPaymentForm.submit();
        }
    });
});

If everything goes right, when you click your submit button, you will have a test 3D secure popin with the options to "success" or "fail" the security test. If you click on success button, your form is submitted and you have to wait for the webhook "charged.success" to confirm transaction.

Once received, change you server object status and notify user about the transaction.

In my case, once the form submitted, I show a loader and check with ajax call every second to see if my payment intent status have changed (through the webhook). For your test environnement, you can use http://requestbin.net and Postman.

Beware: some cards referenced on this page will not work properly (you can't add them) https://stripe.com/docs/testing#cards (section 3D Secure test card numbers and tokens). Confirmed with their support.

If you work with saved card, you can test only with these cards: https://stripe.com/docs/payments/cards/charging-saved-cards#testing

like image 186
ArGh Avatar answered Sep 28 '22 08:09

ArGh