Spreedly 3DS2 Global guide
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. Spreedly currently supports Visa, MasterCard, Amex, and Discover for 3DS2 transactions. To recap the steps needed:
- Create a
Merchant Profile
in your production Spreedly environment. - Create a Spreedly
SCA Provider
for thatMerchant Profile
and obtain ansca_provider_key
- For any transaction that should be 3DS2 authenticated, provide the
sca_provider_key
and all relevant device or browser info. - 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"
},
"discover": {
"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>
<discover>
<acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
<merchant_name>Spreedly</merchant_name>
<country_code>840</country_code>
<mcc>5978</mcc>
</discover>
</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": "LXeWiT9QNMPbLeZC7Z86ep4xh6s",
"description": "Spreedly",
"created_at": "2023-05-31T19:28:04Z",
"updated_at": "2023-05-31T19:28:04Z",
"sub_merchant_key": null,
"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"
},
"discover": {
"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>
<discover>
<acquirer_merchant_id>spreedlys_mid</acquirer_merchant_id>
<mcc>5978</mcc>
<merchant_name>Spreedly</merchant_name>
<country_code>840</country_code>
</discover>
</card_networks>
<token>6b3rjLugxUfuJGrZ9XteMHyROBk</token>
<description>Spreedly</description>
<created_at type="dateTime">2023-05-31T19:28:04Z</created_at>
<updated_at type="dateTime">2023-05-31T19:28:04Z</updated_at>
<sub_merchant_key nil="true"></sub_merchant_key>
</merchant_profile>
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 are currently two
type
field values accepted:spreedly
andtest
(case sensitive). - Spreedly highly recommends that new integrators start with a Test SCA Provider to test their integration before trying their system in production. For more information on scenarios to use with a Test SCA Provider, please see our Test SCA Provider guide for details.
- The
merchant_password
andmerchant_brand_id
fields are optional.
curl https://core.spreedly.com/v1/sca/providers.json \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/json' \
-d '{
"sca_provider": {
"merchant_profile_key": "4pJUW6X81w6OtOLi0dI3W6DD9sY",
"type": "test",
"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",
"merchant_brand_id": "optional"
},
"amex": {
"acquirer_bin": "4444444444",
"merchant_url": "https://spreedly.com",
"merchant_password": "optional"
},
"discover": {
"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>4pJUW6X81w6OtOLi0dI3W6DD9sY</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>
<merchant_brand_id>optional</merchant_brand_id>
</visa>
<amex>
<acquirer_bin>4444444444</acquirer_bin>
<merchant_url>https://spreedly.com</merchant_url>
<merchant_password>optional</merchant_password>
</amex>
<discover>
<acquirer_bin>4444444444</acquirer_bin>
<merchant_url>https://spreedly.com</merchant_url>
<merchant_password>optional</merchant_password>
</discover>
</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": "6EskuBYV5DVyN7Mmy1pV41FqgbN",
"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",
"merchant_brand_id": "optional"
},
"amex": {
"acquirer_bin": "4444444444",
"merchant_url": "https://spreedly.com",
"merchant_password": "optional"
},
"discover": {
"acquirer_bin": "4444444444",
"merchant_url": "https://spreedly.com",
"merchant_password": "optional"
},
"created_at": "2023-06-06T18:02:26Z",
"updated_at": "2023-06-06T18:02:26Z",
"type": "test"
}
}
<sca_provider>
<token>ZKJUqtvImgwulsR4akwBNlJBNMk</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>
<merchant_brand_id>optional</merchant_brand_id>
</visa>
<amex>
<acquirer_bin>4444444444</acquirer_bin>
<merchant_url>https://spreedly.com</merchant_url>
<merchant_password>optional</merchant_password>
</amex>
<discover>
<acquirer_bin>4444444444</acquirer_bin>
<merchant_url>https://spreedly.com</merchant_url>
<merchant_password>optional</merchant_password>
</discover>
<created_at type="dateTime">2023-06-06T18:02:25Z</created_at>
<updated_at type="dateTime">2023-06-06T18:02:26Z</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
, purchase
, or verify
actions.
Here’s a sample authentication request:
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/authenticate.json \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/json' \
-d '{
"transaction": {
"payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
"currency_code": "EUR",
"amount": 100,
"test_scenario": {
"scenario": "authenticated"
},
"browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
}
}'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/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>
<test_scenario><scenario>authenticated</scenario></test_scenario>
<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": "2022-06-03T13:12:42Z",
"updated_at": "2022-06-03T13:12:42Z",
"succeeded": true,
"state": "succeeded",
"token": "CY6TZIcvWYLObGlBvfkUQ11MVQo",
"flow_performed": "frictionless",
"message": "High confidence",
"sca_provider_key": "ZI0HsrLtnvzvNry7f3HARhnOXbA",
"amount": 100,
"currency_code": "EUR",
"ip": null,
"email": null,
"order_id": null,
"three_ds_version": "2.2.0",
"ecommerce_indicator": "05",
"authentication_value": "IShIhfLJeekndsGbtRkiMTFMRjiq",
"directory_server_transaction_id": "9957db40-48dc-4f08-b371-f20c5067738b",
"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": "4fad8992-2c22-4106-807e-6f95a535fc08",
"sdk_transaction_id": null,
"challenge_form": null,
"challenge_form_embed_url": null,
"three_ds_server_trans_id": "6ffac88e-cde7-4b60-8db5-0e8c44e7fa61",
"xid": null,
"enrolled": "true",
"transaction_type": "Sca::Authentication",
"gateway_transaction_key": null,
"callback_url": null,
"test_scenario": {
"scenario": "authenticated"
},
"three_ds_requestor_challenge_ind": null,
"trans_status_reason": "17",
"exemption_type": null,
"acquiring_bank_fraud_rate": null,
"warning": null
}
}
<transaction>
<created_at type="dateTime">2022-05-11T19:35:17Z</created_at>
<updated_at type="dateTime">2022-05-11T19:35:17Z</updated_at>
<succeeded type="boolean">true</succeeded>
<state>succeeded</state>
<token>1mZp4jhdmLIcAQWd93ra0JfTIUw</token>
<flow_performed>frictionless</flow_performed>
<message>High confidence</message>
<sca_provider_key>DvubDdpnYxH4lo5JE9oQ8QOSLxX</sca_provider_key>
<amount type="integer">100</amount>
<currency_code>EUR</currency_code>
<ip nil="true"></ip>
<email nil="true"></email>
<order_id nil="true"></order_id>
<three_ds_version>2.2.0</three_ds_version>
<ecommerce_indicator>05</ecommerce_indicator>
<authentication_value>qkDLcAhUgatiGQAUGQbpqIOPQris</authentication_value>
<directory_server_transaction_id>523e7dd9-fcad-459f-8b28-61532eca05c4</directory_server_transaction_id>
<authentication_value_algorithm nil="true"></authentication_value_algorithm>
<directory_response_status>Y</directory_response_status>
<authentication_response_status>Y</authentication_response_status>
<required_action nil="true"></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>00791065-8b80-40e4-82dd-ce8884018de3</acs_transaction_id>
<sdk_transaction_id nil="true"></sdk_transaction_id>
<challenge_form nil="true"></challenge_form>
<challenge_form_embed_url nil="true"></challenge_form_embed_url>
<three_ds_server_trans_id>d410087c-e672-43b4-a825-c58b3383733e</three_ds_server_trans_id>
<xid nil="true"></xid>
<enrolled>true</enrolled>
<transaction_type>Sca::Authentication</transaction_type>
<gateway_transaction_key nil="true"></gateway_transaction_key>
<callback_url nil="true"></callback_url>
<test_scenario>
<scenario>authenticated</scenario>
</test_scenario>
<three_ds_requestor_challenge_ind nil="true"></three_ds_requestor_challenge_ind>
<trans_status_reason>17</trans_status_reason>
<exemption_type nil="true"></exemption_type>
<acquiring_bank_fraud_rate nil="true"></acquiring_bank_fraud_rate>
<warning nil="true"></warning>
</transaction>
Notes
browser_info
is required, because the transaction is in PSD2 scope
Please refer to our Spreedly 3DS2 Global Integration Guide for Web, to learn how to include ourLifecycle.js
library and gather the browser info data usingSpreedly.ThreeDS.serialize
method.- For a complete overview on all potential authentication scenarios refer to our End to end flow diagram
- 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: iFrame Payments Form or Payments Methods API
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
, authorize,
or verify
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"
}
}'
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
, authorize
, or verify
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
, authorize
, or verify
transaction.
The response looks similar to other purchase,
authorize
, and verify
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": "[email protected]",
"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>[email protected]</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><form action="https://testds3.seglan.com/server/authentication/load" method="POST">
<input name="browserChallengeToken" value="116e1940-c712-4b78-9f2c-0a6f976184d7" type="hidden"/>
</form></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, Purchase, or Verify
When the sca_provider_key
, (the token
field in the SCA Provider
object) is included on an authorize
, purchase
, or verify
transaction, Spreedly performs a 3DS2 authentication with the provider before performing the gateway transaction. There are three possible outcomes:
- 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.
- 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.
- 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 the browser_info
field.
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
, authorize
, and verify
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 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": "[email protected]",
"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>[email protected]</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><form action="https://testds3.seglan.com/server/authentication/load" method="POST">
<input name="browserChallengeToken" value="116e1940-c712-4b78-9f2c-0a6f976184d7" type="hidden"/>
</form></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:
- Spreedly 3DS2 Global for Web
- Spreedly 3DS2 Global for Mobile Webview
Additional information on the Spreedly SCA Provider can be found below:
- Merchant Profile Onboarding Guide
- Testing your 3DS2 Global Integration
Performing a non-payment authentication
Spreedly 3DS2 Global supports the ability for merchants to perform a non-payment sca authentication with a specific payment method. When attempting this flow, Spreedly will indicate to the ACS server that this a non-payment authentication for cardholder verification. Note: challenges may still be requested by the issuer in this flow.
There are currently two ways to complete this flow, by performing a standalone authentication or passing in relevant data during a verify
transaction.
To perform a standalone non-payment authentication merchants may follow the standard authentication request while omitting the amount
and currency_code
fields.
To perform a non-payment authentication as part of a verify
you may pass in the sca_provider_key
on your verify
gateway transaction as demonstrated in the performing SCA authentication as part of Authorize
, Purchase
, or Verify
.
Requesting Exemptions
Spreedly 3DS2 Global supports the ability for merchants to request low value and Transaction Risk Analysis (TRA) exemptions to reduce the likelihood of a transaction being challenged by the issuing bank and create a more frictionless experience for the cardholder.
Low Value Exemptions
Transactions under 30 euros are considered “low value” and are exempt from strong customer authentication (SCA). It is recommended to leverage this exemption type to help reduce friction in the checkout flow. In order to request a low value exemption, the exemption_type
field should be set to low_value_exemption
.
The exemption_type
field can be included at the transaction level for standalone SCA authentications, but for Purchases and Authorizations, it should be included as a field in the sca_authentication_parameters
hash.
If you are using the
sca_authentication_parameters.three_ds_requestor_challenge_ind
parameter and setting it to05
to request low value exemptions that will continue to work. However, we encourage you to begin using theexemption_type
parameter noted above.
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": "ZI0HsrLtnvzvNry7f3HARhnOXbA",
"sca_authentication_parameters": {
"test_scenario": {
"scenario": "authenticated"
},
"exemption_type": "low_value_exemption"
},
"amount": 100,
"currency_code": "EUR",
"ip": "127.0.0.1",
"browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
}
}'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/authenticate.json \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/json' \
-d '{
"transaction": {
"payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
"currency_code": "EUR",
"amount": 100,
"exemption_type": "low_value_exemption",
"test_scenario": {
"scenario": "authenticated"
},
"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>EUR</currency_code>
<sca_provider_key>ZI0HsrLtnvzvNry7f3HARhnOXbA</sca_provider_key>
<sca_authentication_parameters>
<exemption_type>low_value_exemption</exemption_type>
<test_scenario><scenario>authenticated</scenario></test_scenario>
</sca_authentication_parameters>
<ip>127.0.0.1</ip>
<browser_info>
eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
</browser_info>
</transaction>'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/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>
<exemption_type>low_value_exemption</exemption_type>
<test_scenario><scenario>authenticated</scenario></test_scenario>
<browser_info>
eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
</browser_info>
</transaction>'
Transaction Risk Analysis Exemption
The Transaction Risk Analysis (TRA) exemption is a process that allows the issuing bank to make a determination if the merchant typically struggles with fraud or not. If the merchant’s fraud rate is below a certain threshold then it is less likely for friction to be introduced into the checkout flow.
In order to request a TRA exemption the below fields must be sent:
exemption_type
parameter should include the transaction_risk_analysis_exemption valueacquiring_bank_fraud_rate
parameter should be set to one of three values:
- If your fraud rate is less than .01% then use the value level_one
- If it falls between .01% and .06% then use the value level_two
- If it falls between .06% and .13%, then use the value level_three
- If you are unsure of your fraud rate, ask your acquirer or calculate it on your own using the following guidance per Article 19 of the Delegated Regulation:
“The overall fraud rate for each type of transaction shall be calculated as the total value of unauthorised or fraudulent remote transactions, whether the funds have been recovered or not, divided by the total value of all remote transactions for the same type of transactions, whether authenticated with the application of strong customer authentication or executed under any exemption referred to in Articles 13 to 18 on a rolling quarterly basis (90 days).”
Spreedly is not liable for any repercussions that may result from submitting an inaccurate fraud rate.
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": "ZI0HsrLtnvzvNry7f3HARhnOXbA",
"sca_authentication_parameters": {
"test_scenario": {
"scenario": "authenticated"
},
"exemption_type": "transaction_risk_analysis_exemption",
"acquiring_bank_fraud_rate": "level_one"
},
"amount": 100,
"currency_code": "EUR",
"ip": "127.0.0.1",
"browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
}
}'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/authenticate.json \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/json' \
-d '{
"transaction": {
"payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
"currency_code": "EUR",
"amount": 100,
"exemption_type": "transaction_risk_analysis_exemption",
"acquiring_bank_fraud_rate": "level_one",
"test_scenario": {
"scenario": "authenticated"
},
"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>EUR</currency_code>
<sca_provider_key>ZI0HsrLtnvzvNry7f3HARhnOXbA</sca_provider_key>
<sca_authentication_parameters>
<exemption_type>transaction_risk_analysis_exemption</exemption_type>
<acquiring_bank_fraud_rate>level_one</acquiring_bank_fraud_rate>
<test_scenario><scenario>authenticated</scenario></test_scenario>
</sca_authentication_parameters>
<ip>127.0.0.1</ip>
<browser_info>
eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
</browser_info>
</transaction>'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/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>
<exemption_type>transaction_risk_analysis_exemption</exemption_type>
<acquiring_bank_fraud_rate>level_one</acquiring_bank_fraud_rate>
<test_scenario><scenario>authenticated</scenario></test_scenario>
<browser_info>
eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
</browser_info>
</transaction>'
Visa DAF
Spreedly supports using Visa’s Digital Authentication Framework (DAF) when completing a 3DS2 Global authentication. To use DAF you must have a Visa brand id, obtained from Visa.
You may then pass this value in via the merchant_brand_id field
in the visa
subhash when creating an SCA Provider.
When completing an sca_authentication
with a sca_provider
that has this value, the 3DS server may or may not utilize Visa’s framework. To force the use of DAF you may send force_daf: true
in the authenticate
transaction request.
Here’s a sample authentication request:
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/authenticate.json \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
-H 'Content-Type: application/json' \
-d '{
"transaction": {
"payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
"currency_code": "EUR",
"amount": 100,
"force_daf": true,
"test_scenario": {
"scenario": "authenticated"
},
"browser_info": "eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ=="
}
}'
curl https://core.spreedly.com/v1/sca/providers/ZI0HsrLtnvzvNry7f3HARhnOXbA/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>
<force_daf>true</force_daf>
<test_scenario><scenario>authenticated</scenario></test_scenario>
<browser_info>
eyJ3aWR0aCI6MjEzMywiaGVpZ2h0IjoxMjAwLCJkZXB0aCI6MjQsInRpbWV6b25lIjozMDAsInVzZXJfYWdlbnQiOiJTcHJlZWRseSBBZ2VudCIsImphdmEiOmZhbHNlLCJsYW5ndWFnZSI6ImVuLVVTIiwiYnJvd3Nlcl9zaXplIjoiMDQiLCJhY2NlcHRfaGVhZGVyIjoidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2Uvd2VicCwqLyo7cT0wLjgifQ==
</browser_info>
</transaction>'
All sca_authentications will have a field daf that serves as a Boolean to inform if the framework was used in the authentication flow.
FAQs
See a list of all 3DS frequently asked questions in the Help Center.
Updated 12 days ago