All Tutorials

Authenticating payments with 3D Secure

All Tutorials

Authenticating payments with 3D Secure

Authenticating payments with 3D Secure

On September 14, 2019, the Revised Payment Service Directive, also known as PSD2, was introduced in all countries in the European Economic Area (EEA) and United Kingdom. PSD2 requires most online transactions within the EEA and United Kingdom to have customer authentication. There is an expected 18-month transition period for online stores in the affected countries to become compliant with PSD2. To be compliant, Shopify processes credit card transactions in the EEA by using 3D Secure, which is a payment authentication method.

This guide describes the steps that you can take to update your Shopify apps so that they fully support payment authentication by using 3D Secure. The changes that you need to make depend on whether you're using the REST API or the Storefront API.

3D Secure overview

When a customer attempts to make a purchase, the payment gateway might require them to complete the 3D Secure authentication process. This consists of multiple steps, many of which are automated by the payment gateway and abstracted away from both the merchant and their customers.

As part of the authentication process, some customers are presented with a challenge. This step requires an action by the customer to verify their identity. It's possible for the customer to either pass (by authenticating successfully) or fail the challenge. The challenge can also fail due to either technical or security reasons.

There are multiple things that can go wrong while a payment is undergoing the 3D Secure authentication process. Shopify considers most of these cases to be "errors," which are not the same as "failures." A failure occurs when a customer fails to successfully pass the challenge. An error is anything else that might go wrong during the 3D Secure authentication process, such as an issue with the payment gateway, or the API client failing to redirect the user to the URL.

In general, Shopify does its best to charge the customer in the event of an error. However, if the customer has failed authentication, then they won't be charged.

REST API changes

The changes described in this section apply if you're updating an app that uses either the REST Admin API or the Checkout API.

Payment properties

Shopify is introducing a new property called next_action to the Payment resource. The field returns an object that includes the redirect_url attribute, which is a URL string.

Property Description
"next_action": {
  "redirect_url": ""
Specifies the URL that your app or sales channel needs to send the customer to so that they can authenticate their payment.

If your app or sales channel is building a non-web integration using the Checkout API, then you must surface a web interface (such as a WebView for mobile apps) for the customers. After a customer completes the authentication, your app or sales channel must handle redirecting them back to your app or sales channel.

These changes are currently available in the release candidate for version 2019-10 of the Checkout API, and are scheduled to be included in the 2019-10 release.

HTTP response status

When your app polls the payment (GET /api/unstable/checkouts/:checkout_token/payments/:id.json), the response remains as 202 ACCEPTED until the the customer has been authenticated and the payment has been successfully processed (the customer will either succeed or fail in authenticating). After the authentication is completed, the customer is redirected to a processing page. Your app or sales channel is responsible for closing the page or web view after the payment endpoint returns a 200 OK response.

Expected authentication flow

The following diagram shows how the customer authentication process works in the context of completing a checkout:

Workflow diagram that shows the payment process

GraphQL Storefront API changes

In the Payment object, a new field has been added and the behavior of an existing field has changed:

  • nextActionUrl (string): The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. This is a new field.
  • ready (boolean): Whether the payment is still processing asynchronously. This is an existing field whose behavior has changed. If a nextActionUrl is present, then this field remains false until authentication is completed.

When your app or sales channel attempts to complete a payment by using the checkoutCompleteWithCreditCardV2 mutation, it's provided with a token that can be used to poll the payment. Polling the payment with the following query informs you if your payment has completed processing successfully:

query {
  node(id: "#{payment_token}") {
    ... on Payment {
      checkout {

For payments that don't require 3D Secure, there aren't any changes to the app or sales channel’s behavior:

  • nextActionUrl always returns NULL. If you continue to poll the token, then the ready field eventually returns true when the payment has completed its asynchronous processing.
  • If the payment successfully is successfully completed, then the checkout's completedAt field is updated with the time of completion.
  • If the payment fails, then the checkout's completedAt field remains NULL, and errorMessage contains a payment processing error message.

For cases where payments need to enter the 3D Secure authentication flow:

  • We expect your app or sales channel to poll until ready returns true. If there is a value for nextActionUrl, then your app or sales channel is responsible for redirecting the customer to it while continuing to poll the payment.
  • When ready is true, the payment has reached a final state and nothing further will change. At this point, completedAt returns a time for a successful payment, or NULL for a payment that fails to be completed. If the payment fails, then an error message is returned.

Handling API timeouts for 3D Secure

If your app or sales channel uses the correct API version (2019-10) and includes a redirect URL but doesn't handle the redirect within 10 minutes, then Shopify marks the authentication as an error, and returns an error message. The error message contains a link to this guide.

Handling non-compliant API versions for 3D Secure

If your app or sales channel uses an older API version (such as 2019-07) and includes a redirect URL, then two use cases are possible:

  • Non-compliant handling: If your app or sales channel doesn’t have access to the next action URL, then Shopify marks the authentication as an error, and returns an error message. Shopify includes a deprecation header with a link to this migration guide.
  • Using Cardinal for authentication: For payments that use Cardinal, Shopify attempts the charge regardless of the authentication.