Spreedly 3D2 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. To recap the steps needed:
- Create a
Merchant Profile
in your production Spreedly environment. - Create a Spreedly
SCA Provider
on thatMerchant Profile
. - 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 will hold 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": {
"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>
<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 will respond with a new Merchant Profile
object. The token
field from this response will be used in later steps:
{
"merchant_profile": {
"token": "IIDQE4RpociNnWiUUqcng7BkHpZ",
"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>
<created_at type="dateTime">2020-11-09T18:48:01Z</created_at>
<updated_at type="dateTime">2020-11-09T18:48:01Z</updated_at>
</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 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 will respond with an SCA Provider
object that can now be used to run 3DS2 authentication as part of purchase
and authorize
gateway actions.
{
"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>
Using an SCA Provider On Gateway Transactions
The inclusion of an sca_provider_key
on an authorize
or purchase
transaction tells Spreedly to perform a 3DS2 authentication with that provider before performing the gateway transaction. There are three possible outcomes for the initial message:
- 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. This is equivalent to supplying third-party 3DS2 values via the Third Party 3DS2 feature.
- 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 will perform the gateway transaction in the case of success. If the authentication failed, Spreedly will fail the gateway transaction and it is up to the Merchant to try again if applicable.
- Spreedly will perform a callback if a
callback_url
was provided in the transaction. - Spreedly’s Lifecycle object will emit 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",
"amount": 100,
"currency_code": "USD",
"sca_provider_key": "6JXUReoA9KgnYoSchcJU0OAA6N0",
"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 will look 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 will also show 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.
{
"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><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:
Additional information on the Spreedly SCA Provider can be found below: