Below you will find answers to some of the most commonly asked questions about utilizing 3D Secure with Spreedly. If you don’t find the answer to your question below, feel free to contact us at support@spreedly.com.
Should customers receive a callback for every 3DS2 transaction, regardless of state?
Spreedly will not send events if the transaction comes back in a failure state or a success state before the lifecycle is created. The transaction state should be checked before creating a lifecycle event per Step 6 of the implementation guide.
Why am I receiving the error, “message”:“Callback url is not a valid url”?
The URL must be a valid https URL that is public and using port 443. If it is local, Spreedly cannot reach it. If there are concerns about security of the callback_url, you may add Spreedly’s IPs to your list of valid IPs.
Your 3DS2 guide states we are required to pass in the transaction data from the completion call. Do I have to pass in the whole transaction to this method?**
At a minimum, the following fields would need to be included in the data
: state
, token
, required_action
, checkout_form
, checkout_url
, device_fingerprint_form
, challenge_url
, and challenge_form
We do however recommend sending the full response as in the future it will allow us to make enhancements without requiring changes on your end. You can send only the required fields for the time being. Should we decide to change something in the future, we’ll be sure to communicate such changes well in advance.
Is it possible to challenge multiple times in a single transaction request?
There are multiple types of challenges. The 3DS2 flow will handle the escalation of the challenges automatically.
Why don’t I see checkout_form populated?
checkout_form
will only be used in the case of a 3DS1 fallback. The field should still be passed but a null
value will work in this case. Spreedly will not try to validate it unless the required_action
is redirect.
If I already have my own 3DS1 solution, is it possible to intercept a 3DS1 fallback and handle it on my own?
Yes, you can. You’ll know a fall back is necessary based the transaction being in a pending state and the required action is redirect, and you would not create the lifecycle object in that case.
Can the 3DS1 fallback, described here be configured to run inside an iframe?
Spreedly does not advise embedding 3DS 1 redirects in an iframe as it can lead to unexpected behavior in combination with the 3DS2 functionality.
Is there anything with a 3DS1 implementation that would conflict with 3DS2?
No, Spreedly’s 3DS1 and 3DS2 solutions are compatible.
Should we collect browser_info for all transactions, even if the card is already stored?
We recommended always collecting browser_info as certain gateways might require this in order to process an exemption.
Where should the javascript be placed?
The javascript should be placed on the page that hosts the checkout form.
Your documentation recommends sending browser_info, attempt_3dsecure: true and three_ds_version: “2”. In which cases should we send those parameters? For all transactions/merchants/regions/gateways?
These fields should only be passed when the transaction is in PSD2 scope and where Spreedly supports 3DS2 on the gateway.
What will happen if we pass three_ds_version: “2” to Spreedly for a gateway that only supports 3DS1?
Spreedly will process the transaction as V1.
How will I know if the transaction is falling back to 3ds1?
This is based on a checkout_form or checkout_url being present on the transaction. Spreedly will emit a “fallback” event from Spreedly javascript when this occurs which you can listen to: Spreedly.on(‘3ds:status’, statusUpdates) (See also //Setup event handling
section of 3DS2 Step 7)
What happens if a user closes the browser after the challenge is complete but before Step 7?
There are two attributes we can look at: required_action
, or where the transaction is in the 3DS flow and transaction state
- pending
, succeeded
, gateway_processing_failed
. Spreedly will handle the scenario in which a user hits refresh, however, to redirect a user to a specific page to complete a checkout you will want to make sure the required_action
is not none
and the transaction is in a pending
state.
How can we submit the form in a reliable way for every bank, without the user having to click the Authorise button?
The user should not have to click a button, you should submit the form using javascript.
Can I use my sca_authentication_token on a 3DS Gateway Specific implementation?
No, it is only compatible with 3DS2 Global.
Which gateways support standalone authentication?
Standalone authentication (SCA not tied to an `authorize` or `purchase`) is compatible with all 3DS2 Global supported gateways and does not have to be expanded on a gateway by gateway basis.
Do I need to send the payment method token when I want to perform a purchase or authorize call?
No, sca_authentication_token is used in place of a payment_method_token when sending in a purchase or authorize call. You will receive an error message if you attempt to send in a payment_method_token and an sca_authentication_token.
How long can I store the authentication results before I have to use it for a purchase/authorize?
This is dependent on the rules of card networks. Visa and the European Banking Authority (EBA) provide guidance that a merchant should perform an additional account verification and address CAVV expiry if a transaction is delayed by more than 90 days. Mastercard indicates that AAVs are valid for a maximum of 30 days but a 30 day extension can be requested.
How does standalone authentication work with merchant initiated transactions (MIT)?
When requesting a MIT, assuming that proper setup occurred during the CIT, then the sca_authentication_token will be sent in during the purchase or authorize call along with the proper stored credential fields( stored_credential_initiator , stored_credential_reason_type)
When using standalone authentication with PMD, which fields from the SCA Authentication Response Object need to be sent in the request to the receiver?
It is up to you to build the request and determine how much to include from the Authentication response. How much you include will likely be dependent on the receiver.