3DS2 integration
3DS2 must be activated by MANGOPAY on your account. Before we can do this, you must:
- Ensure users are redirected to SecureModeRedirectUrl if SecureModeNeeded=TRUE
- Integrate BrowserInfo and IpAddress as parameters on all Card Direct PayIns and PreAuthorizations
Once these integrations are complete, please contact support@mangopay.com.
1. SecureMode redirection
What has changed
Previously, a transaction (PayIn or PreAuthorization) would generally not be subject to strong customer authentication if SecureMode=DEFAULT
and the payment amount was inferior to your 3DS limit. Since 1st January 2021, we can no longer guarantee this frictionless payment experience – including on low amount transactions for card verification.
Mandatory integration
Therefore, your website or app must be able to handle a redirection to the 3DS protocol on any Card Direct PayIn or PreAuthorization. An issuer can apply SCA to any transaction, even to flows on 3DS1 servers (which remain PSD2 compliant).
If SecureModeNeeded=TRUE
, redirect the user to SecureModeRedirectUrl
.
Scope
The scope of this change applies to the following endpoints:
For Card Web PayIns the 3DS redirection is handled collected automatically by the payment page. If your implementation only uses Card Web PayIns, no action is mandatory. The optional transaction data (Billing
and Shipping
) is applicable to Card Web PayIns.
Full SecureMode flow
- Your app or website creates a PayIn or PreAuthorization API call
- 3DS is triggered in one of three ways:
- You select
SecureMode=FORCE
in the API call - MANGOPAY triggers
SecureMode=FORCE
automatically because the transaction is superior to your Maximum Frictionless Amount (previously known as the 3DS limit) - The issuer applies SCA to the transaction, regardless of the
SecureMode
value. This trigger is new from 1st January 2021.
- You select
- When 3DS is triggered, the response of the API call will display
SecureModeNeeded=TRUE
- When
SecureModeNeeded=TRUE
, you redirect the user to theSecureModeRedirectUrl
. This redirection is mandatory for the payment to succeed. - Once the authentication phase is completed, the user is returned to the
SecureModeReturnUrl
you provide
SecureMode values under 3DS2
MANGOPAY will not change the logic of SecureMode
on 3DS1 flows. Once we have activated your flows on 3DS2 (which requires the mandatory transaction data outlined on this page), the following SecureMode
values will be available, including the new NO_CHOICE value.
SecureMode (3DS2) value | Are you (the client) liable for the transaction? | You are explicitly requesting: |
---|---|---|
DEFAULT | Yes | An exemption to SCA (and therefore the possibility of a frictionless payment) |
NO_CHOICE | No | Neither SCA nor an exemption |
FORCE | No | SCA |
MANGOPAY agrees a Maximum Frictionless Amount (previously 3DS Limit) with each client, above which we automatically set SecureMode=FORCE
. By default this limit is €50.
Below this limit, your options are:
-
Keep DEFAULT (following the same logic as on 3DS1)
- Liability remains on your side (as on 3DS1)
- Rate of frictionless payments should be close to what it is on 3DS1
-
Replace DEFAULT with NO_CHOICE (new option for 3DS2)
- Liability is no longer on your side
- The frictionless rate will depend on market readiness
2. Transaction data
Mandatory integration
Scope
The parameters BrowserInfo
and IpAddress
must be included on all calls to the following endpoints:
For Card Web PayIns the BrowserInfo
and IpAddress
are collected automatically by the payment page. If your implementation uses only Card Web PayIns, no action is mandatory. The optional transaction data (Billing
and Shipping
) is applicable to Card Web PayIns.
2.1. BrowserInfo
Please note that this information is collected:
- On a website: directly by the user’s browser.
- On a mobile app: a webview needs to be opened to collect information on the browser before proceeding to the payment. Once this is done, proceed in the same way as for a website.
{
"BrowserInfo": {
"AcceptHeader" : "application/json,text/javascript,*/*;q=0.01<",
"JavaEnabled": true,
"Language":"fr",
"ColorDepth": 32,
"ScreenHeight": 667,
"ScreenWidth": 375,
"TimeZoneOffset": "-120",
"UserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
"JavascriptEnabled": true
}
What to send
Field | Description |
---|---|
AcceptHeader | Exact content of the HTTP accept headers as sent to the merchant from the shopper’s browser |
JavaEnabled | Whether the user browser has Java enabled |
Language | Language of the browser of the user |
ColorDepth | Value representing the bit depth of the colour palette for displaying images, in bits per pixel |
ScreenHeight | The height of the screen in pixels |
ScreenWidth | The width of the screen in pixels |
TimeZoneOffset | UTC time offset in minutes |
UserAgent | Exact content of the HTTP user-agent header |
JavascriptEnabled | Whether the browser is Javascript enabled |
What to collect
AcceptHeader | |
---|---|
Format | string |
Mandatory | Yes |
Validations | Max Length: 2048 |
Example | text/html, application/xhtml+xml, application/xml;q=0.9, /;q=0.8 |
Javascript Sample | Collected server side |
JavaEnabled | |
---|---|
Format | boolean |
Mandatory | Yes |
Validations | |
Example | true |
Javascript Sample | navigator.javaEnabled() |
Language | |
---|---|
Format | string |
Mandatory | Yes |
Validations | Max Length: 6 |
Example | FR-FR |
Javascript Sample | navigator.language || navigator.userLanguage |
ColorDepth | |
---|---|
Format | int |
Mandatory | Yes |
Validations | Allowed values: 1, 4, 8, 15, 16, 24, 30, 32, 48 |
Example | 4 |
Javascript Sample | screen.colorDepth |
ScreenHeight | |
---|---|
Format | int |
Mandatory | Yes |
Validations | Range allowed [1,999999] |
Example | 1800 |
Javascript Sample | screen.height |
ScreenWidth | |
---|---|
Format | int |
Mandatory | Yes |
Validations | Range allowed [1,999999] |
Example | 400 |
Javascript Sample | screen.width |
TimeZoneOffset | |
---|---|
Format | int |
Mandatory | Yes |
Validations | Numeric range [-9999, +9999] |
Example | +60 |
Javascript Sample | new Date().getTimezoneOffset() |
UserAgent | |
---|---|
Format | string |
Mandatory | Yes |
Validations | Max Length: 2048 |
Example | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 |
Javascript Sample | navigator.userAgent |
JavascriptEnabled | |
---|---|
Format | boolean |
Mandatory | Yes |
Validations | |
Example | true |
Javascript Sample | true |
2.2. IpAddress
What to send
IP address (V4 or V6) of the end user.
Field | Description |
---|---|
Format | string |
Mandatory | Yes |
Validations | IPV4 or IPV6 format |
Example | 192.168.1.1 |
Javascript Sample | Can be collected server side by calling a IP lookup web service such as Cloudfare or IPIFY (Jquery example below)$.ajax({ |
2.3. Objects: Billing / Shipping
Optional integration
As an exemption to SCA is granted based on a risk analysis, the more transaction data sent with each call, the higher the likelihood that an exemption will be granted.
Scope
The objects Billing
and Shipping
may be included on all calls to the following endpoints:
Considerations
The objects Billing
and Shipping
contain information relating to the user’s billing and shipping address respectively.
- If both the
Billing
andShipping
objects are empty, we will automatically complete them with the information from theUser
object before the call is sent to the issuer. - If the
Billing
is supplied but theShipping
is empty, we will automatically complete theShipping
object with the fields supplied forBilling
. - If the
Shipping
is supplied but theBilling
is empty, we will automatically complete theBilling
object with the fields supplied forShipping
.
In any case, the values sent by MANGOPAY will be available in the call response and via the GET call.
Format (same for both)
Field | Format | Validation |
---|---|---|
FirstName | String | [0,100] |
LastName | String | [0,100] |
Address | Object | |
Address.AddressLine1 | String | string [1,255] |
Address.AddressLine2 | String | string [0,255] |
Address.City | String | string [1,255] |
Address.Region | String | string [0,255] |
Address.PostalCode | String | string [0,255] |
Address.Country | string | ISO 3166-1 alpha-2 format |