Spreedly.ThreeDS.Lifecycle Documentation

Working with asynchronous 3DS transactions can be complex, especially for merchants who need to interact with multiple 3DS providers. Just like Spreedly’s API allows our customers to have a common way to transact on many gateways with minimal changes, our iFrame and Express JavaScript libraries provide a common frontend interface for working with 3DS. The Spreedly.ThreeDS JavaScript object helps our customers integrate with both Spreedly 3DS2 Global and Spreedly 3DS Gateway Specific flows interchangeably.

Our Spreedly 3DS2 Global Integration Guide for Web and Gateway Specific 3DS2 Guide documents contain a pragmatic approach to integrating with our 3DS frontend helpers, but we often get questions about what is happening behind the scenes. This guide aims to provide additional information about our Spreedly.ThreeDS.Lifecycle object so that merchants can better approach their frontend 3DS integrations.

Initializing Spreedly.ThreeDS.Lifecycle

When the lifecycle object is started, it reaches out to the Spreedly server and gets the state of a transaction. Lifecycle interacts with a special transaction endpoint that shows only basic information about a transaction’s state but does not require authentication.

Initial Request Network Diagram

Based on the state and required_action of the transaction, Lifecycle will perform the next required action:

  • If required_action is device_fingerprint, Lifecycle will inject an iFrame that performs the fingerprint.
  • If required_action is challenge, Lifecycle will inject an iFrame that allows the cardholder to perform their challenge with the ACS.
  • If required_action is redirect, Lifecycle will fully redirect the cardholder’s browser to perform their challenge with the ACS.

Each of these flows is explored in more detail below.

Device Fingerprint Flow

Fingerprint Flow Network Diagram

When a device fingerprint is required, Lifecycle will create an iFrame in the cardholder’s browser. The iFrame is injected with a form that collects device information and submits it to the 3DS Server. Since neither the merchant frontend nor Lifecycle can see what is happening in the iFrame, Lifecycle polls the Spreedly server looking for transaction updates. Depending on the 3DS Server, this phase ends in one of two ways:

  • Spreedly is notified that the device fingerprint stage was completed and updates the transaction state. Lifecycle will see the updated state and fire a challenge event.
  • Spreedly is not notified that the device fingerprint stage was completed. Lifecycle will continue polling for ~10 seconds, and if no updates were received, will fire a trigger-completion event.

Since the trigger-completion event is emitted because of a timeout, we require integrators to perform an authenticated request to our transaction complete endpoint upon receipt. This call manually checks the transaction’s status with the 3DS Server and allows us to update the status and advance its required action or fully complete the transaction.

The transaction complete endpoint requires authentication, so integrators will need to implement their own completion endpoint that they can call to proxy the Spreedly complete endpoint. Once the complete call has returned the most recent status, it is up to the integrator to use the response to continue the transaction:

Trigger Completion Decision Diagram

  • If the response is success or failure, the transaction is finished and you may show success or failure to your customer.
  • If the response is pending, a challenge is required and it is the responsibility of our integrators to call event.finalize(data) to kick off the challenge process (shown below).

Challenge Flow

Challenge Flow Network Diagram

When the required action for a transaction is challenge, Lifecycle will create an iFrame and inject it with a form that begins the challenge sequence with the 3DS Server. The iFrame is injected into the challengeIframeLocation element provided by our integrators during its creation.

Lifecycle will fire a challenge event when the element is ready to be displayed. Integrators can use this event to display their challenge element to the user.

Since neither the merchant frontend nor Lifecycle can see what is happening in the iFrame, Lifecycle polls the Spreedly server looking for transaction updates. This can end one of two ways:

  • The transaction completes and fires a complete or error event.
  • After a set number of polling attempts equal to 10-15 minutes of polling, Lifecycle will fire a finalization-timeout event. It is recommended that integrators use their complete endpoint to attempt to update the status; it is likely that the challenge has expired and requires the cardholder to try again.

Fallback Flow

Fallback Flow Network Diagram

The fallback flow is different from the other flows in that the user is fully redirected to the 3DS Server and then the ACS to complete their challenge. The event handler will not receive any events in this flow since the cardholder is being fully redirected to another page.

When the cardholder finishes their challenge, they will be redirected to the merchant’s page via the redirect_url specified in the original transaction along with a ?transaction_token=<token> query parameter. Merchants can use this parameter or their redirect url to then query Spreedly’s transaction endpoint to get the completion status of the transaction and continue the order process.

Lifecycle Endpoint Checklist

Please consider the following items that are needed for a complete integration with our Spreedly.ThreeDS.Lifecycle object:

  • Include the iFrame or Express libraries in your frontend.
  • Upon receiving a pending transaction from Spreedly, initialize and start the Spreedly.ThreeDS.Lifecycle object.
  • Create a transaction complete endpoint on your backend that allows your frontend to make an authenticated request to the Spreedly transaction complete endpoint.
  • Create a status update handler that can handle succeeded, error, challenge, trigger-completion, and finalization-timeout events.
  • (Conditionally required) Create an endpoint on your backend that users can be redirected to in the case of a redirect for some 3DS Gateway Specific integrations.
  • If you plan to run multiple 3DS2 authentications without a full page reload or redirect:
    • The Spreedly.on('3ds:status', statusUpdates) function should only be invoked once. Invoking it multiple times will register the event handlers multiple times leading to duplicate events being received.
    • Make sure to call lifecycle.start() as soon as possible after receiving a pending status for a given transaction, as there is a 30 second timeout between the authentication response and challenge load specified as part of the 3DS V2 spec, see EMVco Spec 2.2.0, 5.5