Spreedly 3DS2 Global Guide

Spreedly 3DS2 Global is currently in beta. Documentation and API usage are subject to change before final release. Please contact Spreedly support if you encounter any problems with your Spreedly 3DS2 Global integration.

Before getting started on your integration, please visit the Introduction to Spreedly 3DS2 Global guide for more information on the entities involved in a Spreedly 3DS2 Global transaction. To recap the steps needed:

  1. Create a Merchant Profile in your production Spreedly environment.
  2. Create a Spreedly SCA Provider for that Merchant Profile and obtain an sca_authentication_token
  3. For any transaction that should be 3DS2 authenticated, provide the sca_authentication_token and all relevant device or browser info.
  4. Make sure your frontend is able to handle asynchronous 3DS2 flows.

Creating a Merchant Profile

To create a Merchant Profile that holds your SCA Provider, you can make a request to the following endpoint. All fields shown below are required per card brand, but not all card brands are required.

Note: For information on how to obtain the Merchant Profile fields, please see our Merchant Profile Onboarding guide here.

curl https://core.spreedly.com/v1/merchant_profiles.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "merchant_profile": {
          "description": "Spreedly",
          "visa": {
            "acquirer_merchant_id": "spreedlys_mid",
            "merchant_name": "Spreedly",
            "country_code": "840",
            "mcc": "5978"
          },
          "mastercard": {
            "acquirer_merchant_id": "spreedlys_mid",
            "merchant_name": "Spreedly",
            "country_code": "840",
            "mcc": "5978"
          },
          "amex": {
            "acquirer_merchant_id": "spreedlys_mid",
            "merchant_name": "Spreedly",
            "country_code": "840",
            "mcc": "5978"
          }
        }
      }'
curl https://core.spreedly.com/v1/merchant_profiles.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<merchant_profile>
          <description>Spreedly</description>
          <visa>
              <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
              <merchant_name>Spreedly</merchant_name>
              <country_code>840</country_code>
              <mcc>5978</mcc>
          </visa>
          <mastercard>
              <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
              <merchant_name>Spreedly</merchant_name>
              <country_code>840</country_code>
              <mcc>5978</mcc>
          </mastercard>
          <amex>
              <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
              <merchant_name>Spreedly</merchant_name>
              <country_code>840</country_code>
              <mcc>5978</mcc>
          </amex>
      </merchant_profile>'

If your request is successful, Spreedly responds with a new Merchant Profile object. The token field from this response is used in later steps as merchant_profile_key:

{
  "merchant_profile": {
    "token": "IIDQE4RpociNnWiUUqcng7BkHpZ",
    "description": "Spreedly",
    "created_at": "2020-11-09T18:48:01Z",
    "updated_at": "2020-11-09T18:48:01Z",
    "card_networks": {
      "visa": {
        "acquirer_merchant_id": "spreedlys_mid",
        "mcc": "5978",
        "merchant_name": "Spreedly",
        "country_code": "840"
      },
      "mastercard": {
        "acquirer_merchant_id": "spreedlys_mid",
        "mcc": "5978",
        "merchant_name": "Spreedly",
        "country_code": "840"
      },
      "amex": {
        "acquirer_merchant_id": "spreedlys_mid",
        "mcc": "5978",
        "merchant_name": "Spreedly",
        "country_code": "840"
      }
    }
  }
}
<merchant_profile>
  <card_networks>
    <visa>
      <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
      <mcc>5978</mcc>
      <merchant_name>Spreedly</merchant_name>
      <country_code>840</country_code>
    </visa>
    <mastercard>
      <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
      <mcc>5978</mcc>
      <merchant_name>Spreedly</merchant_name>
      <country_code>840</country_code>
    </mastercard>
    <amex>
      <acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
      <mcc>5978</mcc>
      <merchant_name>Spreedly</merchant_name>
      <country_code>840</country_code>
    </amex>
  </card_networks>
  <token>LsExVd1sJFsomL4zthCymHMj9hS</token>
  <description>Spreedly</description>
  <created_at type="dateTime">2020-11-09T18:48:01Z</created_at>
  <updated_at type="dateTime">2020-11-09T18:48:01Z</updated_at>
</merchant_profile>

Note: Mastercard does not offer auto-enrollment in order to register with 3DS1, manual enrollment is required. Please visit the Mastercard 3DS1 Manual Enrollment Guide for instructions on how to enroll.

Creating an SCA Provider

Using the Merchant Profile object created in the previous request, you can make a request to the following endpoint to build a Spreedly SCA Provider. Some things to note for this request:

  • There is currently only one type accepted: spreedly (case sensitive).
  • Spreedly highly recommends that new integrators start with a sandbox Spreedly SCA Provider to test their integration before trying their system in production. For more information on card values and scenarios to use with a Sandbox Spreedly SCA Provider, please see our Spreedly SCA Provider guide for details.
  • The merchant_password field is optional.
curl https://core.spreedly.com/v1/sca/providers.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "sca_provider": {
          "merchant_profile_key": "Ke4Ybltto744p0mdSnXmaOxBeeK",
          "type": "spreedly",
          "sandbox": true,
          "mastercard": {
              "acquirer_bin": "4444444444",
              "merchant_url": "https://spreedly.com",
              "merchant_password": "optional"
          },
          "visa": {
              "acquirer_bin": "4444444444",
              "merchant_url": "https://spreedly.com",
              "merchant_password": "optional"
          },
          "amex": {
              "acquirer_bin": "4444444444",
              "merchant_url": "https://spreedly.com",
              "merchant_password": "optional"
          }
        }
      }'
curl https://core.spreedly.com/v1/sca/providers.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<sca_provider>
        <merchant_profile_key>Ke4Ybltto744p0mdSnXmaOxBeeK</merchant_profile_key>
        <type>spreedly</type>
        <sandbox>true</sandbox>
        <mastercard>
            <acquirer_bin>4444444444</acquirer_bin>
            <merchant_url>https://spreedly.com</merchant_url>
            <merchant_password>optional</merchant_password>
        </mastercard>
        <visa>
            <acquirer_bin>4444444444</acquirer_bin>
            <merchant_url>https://spreedly.com</merchant_url>
            <merchant_password>optional</merchant_password>
        </visa>
        <amex>
            <acquirer_bin>4444444444</acquirer_bin>
            <merchant_url>https://spreedly.com</merchant_url>
            <merchant_password>optional</merchant_password>
        </amex>
    </sca_provider>'

If the request is successful, Spreedly responds with an SCA Provider object that contains a token field. This token should be stored to be used in future 3DS2 authentications as the sca_provider_key.

{
  "sca_provider": {
    "token": "K4uIC4CJEmnQzuwcpUy5XthiQJn",
    "sandbox": true,
    "mastercard": {
      "acquirer_bin": "4444444444",
      "merchant_url": "https://spreedly.com",
      "merchant_password": "optional"
    },
    "visa": {
      "acquirer_bin": "4444444444",
      "merchant_url": "https://spreedly.com",
      "merchant_password": "optional"
    },
    "amex": {
      "acquirer_bin": "4444444444",
      "merchant_url": "https://spreedly.com",
      "merchant_password": "optional"
    },
    "created_at": "2020-11-12T15:29:05Z",
    "updated_at": "2020-11-12T15:29:05Z",
    "type": "spreedly"
  }
}
<sca_provider>
  <token>WbwuMzFP1ZNLs93Jh5F5SWoCl5L</token>
  <sandbox type="boolean">true</sandbox>
  <mastercard>
    <acquirer_bin>4444444444</acquirer_bin>
    <merchant_url>https://spreedly.com</merchant_url>
    <merchant_password>optional</merchant_password>
  </mastercard>
  <visa>
    <acquirer_bin>4444444444</acquirer_bin>
    <merchant_url>https://spreedly.com</merchant_url>
    <merchant_password>optional</merchant_password>
  </visa>
  <amex>
    <acquirer_bin>4444444444</acquirer_bin>
    <merchant_url>https://spreedly.com</merchant_url>
    <merchant_password>optional</merchant_password>
  </amex>
  <created_at type="dateTime">2020-11-12T15:29:04Z</created_at>
  <updated_at type="dateTime">2020-11-12T15:29:05Z</updated_at>
  <type>spreedly</type>
</sca_provider>

How to utilize your SCA Provider Key

Now that you have created your sca_provider_key, you can use it to complete a 3DS2 authentication. As you may recall, an SCA Authentication can be completed as a standalone action or as part of a Gateway’s authorize or purchase actions.

Here’s a sample authentication request:

curl https://core.spreedly.com/v1/sca/providers/Ke4Ybltto744p0mdSnXmaOxBeeK/authenticate.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction": {
        "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
        "currency_code": "EUR", 
        "amount": 100,
        "browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
    }
}'
curl https://core.spreedly.com/v1/sca/providers/Ke4Ybltto744p0mdSnXmaOxBeeK/authenticate.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <currency_code>EUR</currency_code>
        <amount>100</amount>
        <browser_info>
          eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
        </browser_info>
      </transaction>'

Where the alphanumeric string between /providers/ and /authenticate.json is the sca_provider_key obtained in a previous step.

Once a 3DS2 Authentication is complete, the response contains the SCA authentication token under the field token in the transaction object. Sample response:

{
  "transaction": {
    "created_at": "2021-06-29T18:37:19Z",
    "updated_at": "2021-06-29T18:37:20Z",
    "succeeded": true,
    "state": "succeeded",
    "token": "X0oXoqJent2pZCgtTBA5e8WusAd",
    "flow_performed": "frictionless",
    "message": null,
    "sca_provider_key": "8jr4M2mMlYNFTR3NuyLt1k6Jqu2",
    "three_ds_version": "2.2.0",
    "ecommerce_indicator": "02",
    "authentication_value": "xgSECdpMAAAAAAAAAAAAAAAAAAAA",
    "directory_server_transaction_id": "230a7860-0323-4dd6-9b6b-694fc752ea67",
    "authentication_value_algorithm": null,
    "directory_response_status": "Y",
    "authentication_response_status": "Y",
    "required_action": null,
    "acs_reference_number": null,
    "acs_rendering_type": null,
    "acs_signed_content": null,
    "acs_transaction_id": "aec1094a-57c9-474f-8922-22d91c9d07a6",
    "sdk_transaction_id": null,
    "challenge_form": null,
    "challenge_form_embed_url": null,
    "three_ds_server_trans_id": "e0902923-34c1-471a-93e0-29c56eac27dc",
    "xid": null,
    "enrolled": "true",
    "transaction_type": "Sca::Authentication",
    "gateway_transaction_key": null,
    "callback_url": null
  }
}
<transaction>
  <created_at>2021-06-29T18:37:19Z</created_at>
  <updated_at>2021-06-29T18:37:20Z</updated_at>
  <succeeded>true</succeeded>
  <state>succeeded</state>
  <token>X0oXoqJent2pZCgtTBA5e8WusAd</token>
  <flow_performed>frictionless</flow_performed>
  <message></message>
  <sca_provider_key>8jr4M2mMlYNFTR3NuyLt1k6Jqu2</sca_provider_key>
  <three_ds_version>2.2.0</three_ds_version>
  <ecommerce_indicator>02</ecommerce_indicator>
  <authentication_value>xgSECdpMAAAAAAAAAAAAAAAAAAAA</authentication_value>
  <directory_server_transaction_id>230a7860-0323-4dd6-9b6b-694fc752ea67</directory_server_transaction_id>
  <authentication_value_algorithm></authentication_value_algorithm>
  <directory_response_status>Y</directory_response_status>
  <authentication_response_status>Y</authentication_response_status>
  <required_action></required_action>
  <acs_reference_number></acs_reference_number>
  <acs_rendering_type></acs_rendering_type>
  <acs_signed_content></acs_signed_content>
  <acs_transaction_id>aec1094a-57c9-474f-8922-22d91c9d07a6</acs_transaction_id>
  <sdk_transaction_id></sdk_transaction_id>
  <challenge_form></challenge_form>
  <challenge_form_embed_url></challenge_form_embed_url>
  <three_ds_server_trans_id>e0902923-34c1-471a-93e0-29c56eac27dc</three_ds_server_trans_id>
  <xid></xid>
  <enrolled>true</enrolled>
  <transaction_type>Sca::Authentication</transaction_type>
  <gateway_transaction_key></gateway_transaction_key>
  <callback_url></callback_url>
</transaction>

Notes

  1. browser_info is required, because the transaction is in PSD2 scope
  2. For a complete overview on all potential authentication scenarios refer to our End to end flow diagram
  3. If you do not already have a token for Payment Method, you’ll have to create one using our solution that best fits your integration scenario:

a

How to utilize an Authentication token

Once you have obtained and saved the token from the authentication response, you can use it immediately to execute a purchase or authorize with the same payment method used for the authentication request. You pass the Authentication token with the sca_authentication_token field like this:

curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "sca_authentication_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "ip": "127.0.0.1",
          "browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
        }
      }'
curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <sca_authentication_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</sca_authentication_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <ip>127.0.0.1</ip>
        <browser_info>
          eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
        </browser_info>
      </transaction>'

Providing an sca_authentication_token to a purchase or authorize will automatically fill in the payment method and third-party 3DS fields on the gateway transaction. Please see our Third Party 3DS2 Guide for a list of gateways that accept these fields. If a user submits an sca_authentication_token to a non-supported gateway, the gateway will accept it and the transaction is attempted without a liability shift since the fields cannot be applied.

You can also store the authentication token for future use on any purchase or authorize transaction.

b

The response looks similar to other purchase and authorize requests with one key difference: there is now an sca_authentication object included in the response that details the 3DS2 authentication. These fields are passed into the gateway transaction automatically and shown here for informational purposes only.

{
  "transaction": {
    "on_test_gateway": false,
    "created_at": "2020-11-12T15:28:15Z",
    "updated_at": "2020-11-12T15:28:16Z",
    "succeeded": false,
    "state": "pending",
    "token": "VvplgnvtAWAoa38801a7e24qAHI",
    "transaction_type": "Purchase",
    "order_id": null,
    "ip": "127.0.0.1",
    "description": null,
    "email": null,
    "merchant_name_descriptor": null,
    "merchant_location_descriptor": null,
    "gateway_specific_fields": null,
    "gateway_specific_response_fields": {
    },
    "gateway_transaction_id": null,
    "gateway_latency_ms": null,
    "stored_credential_initiator": null,
    "stored_credential_reason_type": null,
    "warning": null,
    "amount": 100,
    "currency_code": "USD",
    "retain_on_success": false,
    "payment_method_added": false,
    "smart_routed": false,
    "message_key": "messages.transaction_pending",
    "message": "Pending",
    "gateway_token": "T11bJAANtTWnxl36GYjKWvbNK0g",
    "gateway_type": "test",
    "shipping_address": {
      "name": "Newfirst Newlast",
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null
    },
    "api_urls": [
      {
        "referencing_transaction": [

        ]
      },
      {
        "failover_transaction": [

        ]
      }
    ],
    "attempt_3dsecure": false,
    "payment_method": {
      "token": "1rpKvP8zOUhj4Y9EDrIoIYQzzD5",
      "created_at": "2017-06-26T17:04:38Z",
      "updated_at": "2020-11-10T19:38:14Z",
      "email": "joey@example.com",
      "data": {
        "my_payment_method_identifier": "448",
        "extra_stuff": {
          "some_other_things": "Can be anything really"
        }
      },
      "storage_state": "retained",
      "test": true,
      "metadata": {
        "key": "string value"
      },
      "callback_url": null,
      "last_four_digits": "1111",
      "first_six_digits": "411111",
      "card_type": "visa",
      "first_name": "Newfirst",
      "last_name": "Newlast",
      "month": 3,
      "year": 2032,
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null,
      "company": null,
      "full_name": "Newfirst Newlast",
      "eligible_for_card_updater": true,
      "shipping_address1": null,
      "shipping_address2": null,
      "shipping_city": null,
      "shipping_state": null,
      "shipping_zip": null,
      "shipping_country": null,
      "shipping_phone_number": null,
      "payment_method_type": "credit_card",
      "errors": [

      ],
      "fingerprint": "e3cef43464fc832f6e04f187df25af497994",
      "verification_value": "",
      "number": "XXXX-XXXX-XXXX-1111"
    },
    "sca_authentication": {
      "created_at": "2020-11-12T15:28:15Z",
      "updated_at": "2020-11-12T15:28:16Z",
      "succeeded": false,
      "state": "pending",
      "token": "INP4rU2jLObOPm1tnzXfGo2tuH1",
      "flow_performed": "challenge",
      "message": null,
      "sca_provider_key": "6JXUReoA9KgnYoSchcJU0OAA6N0",
      "three_ds_version": "2.2.0",
      "ecommerce_indicator": null,
      "authentication_value": null,
      "directory_server_transaction_id": "5c06e665-3675-494e-9ccf-cc078ebd8dc9",
      "authentication_value_algorithm": null,
      "directory_response_status": "C",
      "authentication_response_status": "C",
      "required_action": "challenge",
      "acs_reference_number": null,
      "acs_rendering_type": null,
      "acs_signed_content": null,
      "acs_transaction_id": null,
      "sdk_transaction_id": null,
      "challenge_form": "<form action=\"https://testds3.seglan.com/server/authentication/load\" method=\"POST\">\n  <input name=\"browserChallengeToken\" value=\"b3055a53-7c4d-4f71-bb33-742af0daa96f\" type=\"hidden\"/>\n</form>",
      "challenge_form_embed_url": null,
      "three_ds_server_trans_id": "b3055a53-7c4d-4f71-bb33-742af0daa96f",
      "xid": null,
      "enrolled": null,
      "transaction_type": "Sca::Authentication"
    }
  }
}
<transaction>
  <on_test_gateway type="boolean">false</on_test_gateway>
  <created_at type="dateTime">2020-11-12T15:10:37Z</created_at>
  <updated_at type="dateTime">2020-11-12T15:10:38Z</updated_at>
  <succeeded type="boolean">false</succeeded>
  <state>pending</state>
  <token>X3WSJdOofHm4tJL84l3ZW8dtDal</token>
  <transaction_type>Purchase</transaction_type>
  <order_id nil="true"></order_id>
  <ip>127.0.0.1</ip>
  <description nil="true"></description>
  <email nil="true"></email>
  <merchant_name_descriptor nil="true"></merchant_name_descriptor>
  <merchant_location_descriptor nil="true"></merchant_location_descriptor>
  <gateway_specific_fields nil="true"></gateway_specific_fields>
  <gateway_specific_response_fields>
  </gateway_specific_response_fields>
  <gateway_transaction_id nil="true"></gateway_transaction_id>
  <gateway_latency_ms nil="true"></gateway_latency_ms>
  <stored_credential_initiator nil="true"></stored_credential_initiator>
  <stored_credential_reason_type nil="true"></stored_credential_reason_type>
  <warning nil="true"></warning>
  <amount type="integer">100</amount>
  <currency_code>USD</currency_code>
  <retain_on_success type="boolean">false</retain_on_success>
  <payment_method_added type="boolean">false</payment_method_added>
  <smart_routed type="boolean">false</smart_routed>
  <message key="messages.transaction_pending">Pending</message>
  <gateway_token>T11bJAANtTWnxl36GYjKWvbNK0g</gateway_token>
  <gateway_type>test</gateway_type>
  <shipping_address>
    <name>Newfirst Newlast</name>
    <address1 nil="true"></address1>
    <address2 nil="true"></address2>
    <city nil="true"></city>
    <state nil="true"></state>
    <zip nil="true"></zip>
    <country nil="true"></country>
    <phone_number nil="true"></phone_number>
  </shipping_address>
  <api_urls>
  </api_urls>
  <payment_method>
    <token>1rpKvP8zOUhj4Y9EDrIoIYQzzD5</token>
    <created_at type="dateTime">2017-06-26T17:04:38Z</created_at>
    <updated_at type="dateTime">2020-11-10T19:38:14Z</updated_at>
    <email>joey@example.com</email>
    <data>
      <my_payment_method_identifier>448</my_payment_method_identifier>
      <extra_stuff>
        <some_other_things>Can be anything really</some_other_things>
      </extra_stuff>
    </data>
    <storage_state>retained</storage_state>
    <test type="boolean">true</test>
    <metadata>
      <key>string value</key>
    </metadata>
    <callback_url nil="true"></callback_url>
    <last_four_digits>1111</last_four_digits>
    <first_six_digits>411111</first_six_digits>
    <card_type>visa</card_type>
    <first_name>Newfirst</first_name>
    <last_name>Newlast</last_name>
    <month type="integer">3</month>
    <year type="integer">2032</year>
    <address1 nil="true"></address1>
    <address2 nil="true"></address2>
    <city nil="true"></city>
    <state nil="true"></state>
    <zip nil="true"></zip>
    <country nil="true"></country>
    <phone_number nil="true"></phone_number>
    <company nil="true"></company>
    <full_name>Newfirst Newlast</full_name>
    <eligible_for_card_updater type="boolean">true</eligible_for_card_updater>
    <shipping_address1 nil="true"></shipping_address1>
    <shipping_address2 nil="true"></shipping_address2>
    <shipping_city nil="true"></shipping_city>
    <shipping_state nil="true"></shipping_state>
    <shipping_zip nil="true"></shipping_zip>
    <shipping_country nil="true"></shipping_country>
    <shipping_phone_number nil="true"></shipping_phone_number>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value></verification_value>
    <number>XXXX-XXXX-XXXX-1111</number>
    <fingerprint>e3cef43464fc832f6e04f187df25af497994</fingerprint>
  </payment_method>
  <sca_authentication>
    <created_at type="dateTime">2020-11-12T15:10:37Z</created_at>
    <updated_at type="dateTime">2020-11-12T15:10:38Z</updated_at>
    <succeeded type="boolean">false</succeeded>
    <state>pending</state>
    <token>IemZcePeA1wuhZh3IVJpFZLN1JB</token>
    <flow_performed>challenge</flow_performed>
    <message nil="true"></message>
    <sca_provider_key>6JXUReoA9KgnYoSchcJU0OAA6N0</sca_provider_key>
    <three_ds_version>2.2.0</three_ds_version>
    <ecommerce_indicator nil="true"></ecommerce_indicator>
    <authentication_value nil="true"></authentication_value>
    <directory_server_transaction_id>b307301e-5ddc-476e-b4da-586327cfe9e9</directory_server_transaction_id>
    <authentication_value_algorithm nil="true"></authentication_value_algorithm>
    <directory_response_status>C</directory_response_status>
    <authentication_response_status>C</authentication_response_status>
    <required_action>challenge</required_action>
    <acs_reference_number nil="true"></acs_reference_number>
    <acs_rendering_type nil="true"></acs_rendering_type>
    <acs_signed_content nil="true"></acs_signed_content>
    <acs_transaction_id nil="true"></acs_transaction_id>
    <sdk_transaction_id nil="true"></sdk_transaction_id>
    <challenge_form>&lt;form action="https://testds3.seglan.com/server/authentication/load" method="POST"&gt;
  &lt;input name="browserChallengeToken" value="116e1940-c712-4b78-9f2c-0a6f976184d7" type="hidden"/&gt;
&lt;/form&gt;</challenge_form>
    <challenge_form_embed_url nil="true"></challenge_form_embed_url>
    <three_ds_server_trans_id>116e1940-c712-4b78-9f2c-0a6f976184d7</three_ds_server_trans_id>
    <xid nil="true"></xid>
    <enrolled nil="true"></enrolled>
    <transaction_type>Sca::Authentication</transaction_type>
  </sca_authentication>
  <attempt_3dsecure type="boolean">false</attempt_3dsecure>
</transaction>

Performing SCA authentication as part of Authorize or Purchase

When the sca_provider_key, (the token field in the SCA Provider object) is included on an authorize or purchase transaction, Spreedly performs a 3DS2 authentication with the provider before performing the gateway transaction. There are three possible outcomes:

  1. The authentication succeeds without the need for a challenge. Spreedly will apply the authentication values to the gateway transaction and make a request to the gateway immediately. Spreedly 3DS2 Global Successful Request
  2. The authentication fails immediately without the need for a challenge. In this case, Spreedly automatically fails the gateway transaction and will not reach out to the gateway. It is the Merchant’s responsibility to retry the transaction in the case of failure.
  3. The authentication requires a challenge and is put in a pending state. Once the user completes this challenge:
    • Spreedly performs the gateway transaction in the case of success. If the authentication fails, Spreedly does not attempt the transaction at the gateway and marks the transaction as failed. It is up to the Merchant to try again if applicable.
    • Spreedly performs a callback if a callback_url was provided in the transaction.
    • Spreedly’s Lifecycle object emits an event that denotes that the transaction has completed.

It is also important to note that the sca_provider_key field is mutually exclusive with the attempt_3dsecure flag. The sca_provider_key is used to run 3DS2 authentication with a third party 3DS server and pass those results into the gateway. The attempt_3dsecure flag is used to run 3DS authentication on the gateway itself during the transaction.

In addition to the sca_provider_key, the Spreedly SCA Provider requires the IP address of a customer as well as a browser_info field for web or a device_info field for mobile. Information on collecting these fields can be found in our Spreedly 3DS2 Global Integration Guide for Web.

curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "sca_provider_key": "6JXUReoA9KgnYoSchcJU0OAA6N0",
          "amount": 100,
          "currency_code": "USD",
          "ip": "127.0.0.1",
          "browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
        }
      }'
curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <sca_provider_key>6JXUReoA9KgnYoSchcJU0OAA6N0</sca_provider_key>
        <ip>127.0.0.1</ip>
        <browser_info>
          eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
        </browser_info>
      </transaction>'

The response looks similar to other purchase and authorize requests with one key difference: there is now an sca_authentication object included in the response that details the state of the 3DS2 authentication. For a successful authentication, it shows the 3DS2 (or 3DS1 if the transaction had to fallback) authentication information from the 3DS Server. These fields are passed into the gateway transaction automatically and shown here for informational purposes only.

Note: If you are performing a 3DS2 Global transaction separate from the purchase/authorization and the SCA Authentication fails, you can use the ignore_failed_authentication_result field to follow through on the transaction. See here for more details.

{
  "transaction": {
    "on_test_gateway": false,
    "created_at": "2020-11-12T15:28:15Z",
    "updated_at": "2020-11-12T15:28:16Z",
    "succeeded": false,
    "state": "pending",
    "token": "VvplgnvtAWAoa38801a7e24qAHI",
    "transaction_type": "Purchase",
    "order_id": null,
    "ip": "127.0.0.1",
    "description": null,
    "email": null,
    "merchant_name_descriptor": null,
    "merchant_location_descriptor": null,
    "gateway_specific_fields": null,
    "gateway_specific_response_fields": {
    },
    "gateway_transaction_id": null,
    "gateway_latency_ms": null,
    "stored_credential_initiator": null,
    "stored_credential_reason_type": null,
    "warning": null,
    "amount": 100,
    "currency_code": "USD",
    "retain_on_success": false,
    "payment_method_added": false,
    "smart_routed": false,
    "message_key": "messages.transaction_pending",
    "message": "Pending",
    "gateway_token": "T11bJAANtTWnxl36GYjKWvbNK0g",
    "gateway_type": "test",
    "shipping_address": {
      "name": "Newfirst Newlast",
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null
    },
    "api_urls": [
      {
        "referencing_transaction": [

        ]
      },
      {
        "failover_transaction": [

        ]
      }
    ],
    "attempt_3dsecure": false,
    "payment_method": {
      "token": "1rpKvP8zOUhj4Y9EDrIoIYQzzD5",
      "created_at": "2017-06-26T17:04:38Z",
      "updated_at": "2020-11-10T19:38:14Z",
      "email": "joey@example.com",
      "data": {
        "my_payment_method_identifier": "448",
        "extra_stuff": {
          "some_other_things": "Can be anything really"
        }
      },
      "storage_state": "retained",
      "test": true,
      "metadata": {
        "key": "string value"
      },
      "callback_url": null,
      "last_four_digits": "1111",
      "first_six_digits": "411111",
      "card_type": "visa",
      "first_name": "Newfirst",
      "last_name": "Newlast",
      "month": 3,
      "year": 2032,
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null,
      "company": null,
      "full_name": "Newfirst Newlast",
      "eligible_for_card_updater": true,
      "shipping_address1": null,
      "shipping_address2": null,
      "shipping_city": null,
      "shipping_state": null,
      "shipping_zip": null,
      "shipping_country": null,
      "shipping_phone_number": null,
      "payment_method_type": "credit_card",
      "errors": [

      ],
      "fingerprint": "e3cef43464fc832f6e04f187df25af497994",
      "verification_value": "",
      "number": "XXXX-XXXX-XXXX-1111"
    },
    "sca_authentication": {
      "created_at": "2020-11-12T15:28:15Z",
      "updated_at": "2020-11-12T15:28:16Z",
      "succeeded": false,
      "state": "pending",
      "token": "INP4rU2jLObOPm1tnzXfGo2tuH1",
      "flow_performed": "challenge",
      "message": null,
      "sca_provider_key": "6JXUReoA9KgnYoSchcJU0OAA6N0",
      "three_ds_version": "2.2.0",
      "ecommerce_indicator": null,
      "authentication_value": null,
      "directory_server_transaction_id": "5c06e665-3675-494e-9ccf-cc078ebd8dc9",
      "authentication_value_algorithm": null,
      "directory_response_status": "C",
      "authentication_response_status": "C",
      "required_action": "challenge",
      "acs_reference_number": null,
      "acs_rendering_type": null,
      "acs_signed_content": null,
      "acs_transaction_id": null,
      "sdk_transaction_id": null,
      "challenge_form": "<form action=\"https://testds3.seglan.com/server/authentication/load\" method=\"POST\">\n  <input name=\"browserChallengeToken\" value=\"b3055a53-7c4d-4f71-bb33-742af0daa96f\" type=\"hidden\"/>\n</form>",
      "challenge_form_embed_url": null,
      "three_ds_server_trans_id": "b3055a53-7c4d-4f71-bb33-742af0daa96f",
      "xid": null,
      "enrolled": null,
      "transaction_type": "Sca::Authentication"
    }
  }
}
<transaction>
  <on_test_gateway type="boolean">false</on_test_gateway>
  <created_at type="dateTime">2020-11-12T15:10:37Z</created_at>
  <updated_at type="dateTime">2020-11-12T15:10:38Z</updated_at>
  <succeeded type="boolean">false</succeeded>
  <state>pending</state>
  <token>X3WSJdOofHm4tJL84l3ZW8dtDal</token>
  <transaction_type>Purchase</transaction_type>
  <order_id nil="true"></order_id>
  <ip>127.0.0.1</ip>
  <description nil="true"></description>
  <email nil="true"></email>
  <merchant_name_descriptor nil="true"></merchant_name_descriptor>
  <merchant_location_descriptor nil="true"></merchant_location_descriptor>
  <gateway_specific_fields nil="true"></gateway_specific_fields>
  <gateway_specific_response_fields>
  </gateway_specific_response_fields>
  <gateway_transaction_id nil="true"></gateway_transaction_id>
  <gateway_latency_ms nil="true"></gateway_latency_ms>
  <stored_credential_initiator nil="true"></stored_credential_initiator>
  <stored_credential_reason_type nil="true"></stored_credential_reason_type>
  <warning nil="true"></warning>
  <amount type="integer">100</amount>
  <currency_code>USD</currency_code>
  <retain_on_success type="boolean">false</retain_on_success>
  <payment_method_added type="boolean">false</payment_method_added>
  <smart_routed type="boolean">false</smart_routed>
  <message key="messages.transaction_pending">Pending</message>
  <gateway_token>T11bJAANtTWnxl36GYjKWvbNK0g</gateway_token>
  <gateway_type>test</gateway_type>
  <shipping_address>
    <name>Newfirst Newlast</name>
    <address1 nil="true"></address1>
    <address2 nil="true"></address2>
    <city nil="true"></city>
    <state nil="true"></state>
    <zip nil="true"></zip>
    <country nil="true"></country>
    <phone_number nil="true"></phone_number>
  </shipping_address>
  <api_urls>
  </api_urls>
  <payment_method>
    <token>1rpKvP8zOUhj4Y9EDrIoIYQzzD5</token>
    <created_at type="dateTime">2017-06-26T17:04:38Z</created_at>
    <updated_at type="dateTime">2020-11-10T19:38:14Z</updated_at>
    <email>joey@example.com</email>
    <data>
      <my_payment_method_identifier>448</my_payment_method_identifier>
      <extra_stuff>
        <some_other_things>Can be anything really</some_other_things>
      </extra_stuff>
    </data>
    <storage_state>retained</storage_state>
    <test type="boolean">true</test>
    <metadata>
      <key>string value</key>
    </metadata>
    <callback_url nil="true"></callback_url>
    <last_four_digits>1111</last_four_digits>
    <first_six_digits>411111</first_six_digits>
    <card_type>visa</card_type>
    <first_name>Newfirst</first_name>
    <last_name>Newlast</last_name>
    <month type="integer">3</month>
    <year type="integer">2032</year>
    <address1 nil="true"></address1>
    <address2 nil="true"></address2>
    <city nil="true"></city>
    <state nil="true"></state>
    <zip nil="true"></zip>
    <country nil="true"></country>
    <phone_number nil="true"></phone_number>
    <company nil="true"></company>
    <full_name>Newfirst Newlast</full_name>
    <eligible_for_card_updater type="boolean">true</eligible_for_card_updater>
    <shipping_address1 nil="true"></shipping_address1>
    <shipping_address2 nil="true"></shipping_address2>
    <shipping_city nil="true"></shipping_city>
    <shipping_state nil="true"></shipping_state>
    <shipping_zip nil="true"></shipping_zip>
    <shipping_country nil="true"></shipping_country>
    <shipping_phone_number nil="true"></shipping_phone_number>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value></verification_value>
    <number>XXXX-XXXX-XXXX-1111</number>
    <fingerprint>e3cef43464fc832f6e04f187df25af497994</fingerprint>
  </payment_method>
  <sca_authentication>
    <created_at type="dateTime">2020-11-12T15:10:37Z</created_at>
    <updated_at type="dateTime">2020-11-12T15:10:38Z</updated_at>
    <succeeded type="boolean">false</succeeded>
    <state>pending</state>
    <token>IemZcePeA1wuhZh3IVJpFZLN1JB</token>
    <flow_performed>challenge</flow_performed>
    <message nil="true"></message>
    <sca_provider_key>6JXUReoA9KgnYoSchcJU0OAA6N0</sca_provider_key>
    <three_ds_version>2.2.0</three_ds_version>
    <ecommerce_indicator nil="true"></ecommerce_indicator>
    <authentication_value nil="true"></authentication_value>
    <directory_server_transaction_id>b307301e-5ddc-476e-b4da-586327cfe9e9</directory_server_transaction_id>
    <authentication_value_algorithm nil="true"></authentication_value_algorithm>
    <directory_response_status>C</directory_response_status>
    <authentication_response_status>C</authentication_response_status>
    <required_action>challenge</required_action>
    <acs_reference_number nil="true"></acs_reference_number>
    <acs_rendering_type nil="true"></acs_rendering_type>
    <acs_signed_content nil="true"></acs_signed_content>
    <acs_transaction_id nil="true"></acs_transaction_id>
    <sdk_transaction_id nil="true"></sdk_transaction_id>
    <challenge_form>&lt;form action="https://testds3.seglan.com/server/authentication/load" method="POST"&gt;
  &lt;input name="browserChallengeToken" value="116e1940-c712-4b78-9f2c-0a6f976184d7" type="hidden"/&gt;
&lt;/form&gt;</challenge_form>
    <challenge_form_embed_url nil="true"></challenge_form_embed_url>
    <three_ds_server_trans_id>116e1940-c712-4b78-9f2c-0a6f976184d7</three_ds_server_trans_id>
    <xid nil="true"></xid>
    <enrolled nil="true"></enrolled>
    <transaction_type>Sca::Authentication</transaction_type>
  </sca_authentication>
  <attempt_3dsecure type="boolean">false</attempt_3dsecure>
</transaction>

Preparing your Frontend for Spreedly 3DS2 Global

While those are all of the requests required for a 3DS2 transaction, additional work is required on the frontend for handling asynchronous 3DS2 transactions. The guides below cover frontend integrations for different platforms:

Additional information on the Spreedly SCA Provider can be found below:

Requesting Exemptions

Spreedly 3DS2 Global supports the ability to request low value exemptions.

Set the sca_authentication_parameters.three_ds_requestor_challenge_ind field to 05 in addition to sending in your sca_provider_key.

See how this field can be used in SCA Authenticate calls or Purchase calls in our API reference.

curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "sca_provider_key": "6JXUReoA9KgnYoSchcJU0OAA6N0",
          "sca_authentication_parameters": {
            "three_ds_requestor_challenge_ind": "05"
          },
          "amount": 100,
          "currency_code": "USD",
          "ip": "127.0.0.1",
          "browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
        }
      }'
curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <sca_provider_key>6JXUReoA9KgnYoSchcJU0OAA6N0</sca_provider_key>
        <sca_authentication_parameters>
          <three_ds_requestor_challenge_ind>05</three_ds_requestor_challenge_ind>
        </sca_authentication_parameters>
        <ip>127.0.0.1</ip>
        <browser_info>
          eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
        </browser_info>
      </transaction>'

For more information on how to use the three_ds_requestor_challenge_ind field and the possible values, please see the EMVco spec.

FAQs

See a list of all 3DS frequently asked questions in the Help Center.