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 |
|
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:
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 remainsfalse
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 {
id
ready
errorMessage
nextActionUrl
checkout {
completedAt
}
}
}
}
For payments that don't require 3D Secure, there aren't any changes to the app or sales channel’s behavior:
nextActionUrl
always returnsNULL
. If you continue to poll the token, then theready
field eventually returnstrue
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 remainsNULL
, anderrorMessage
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
returnstrue
. If there is a value fornextActionUrl
, then your app or sales channel is responsible for redirecting the customer to it while continuing to poll the payment. - When
ready
istrue
, the payment has reached a final state and nothing further will change. At this point,completedAt
returns a time for a successful payment, orNULL
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.