How 3D Secure works on PayMe
Prerequisites
- The 3D Secure service active on the seller's account (PayMe enables it)
Related
- Create a sale with 3D Secure
- 3DS with Hosted Fields
- 3D Secure as a service
- Standalone 3D Secure service
- Pay a sale
- Accept Google Pay
- Test Cards and Payment Methods
- Callbacks
- Errors
- Understand the sale lifecycle
3D Secure (3DS) asks the card issuer to confirm that the buyer is the cardholder before the card is charged. PayMe runs 3D Secure 2 (version 2.2.0). The issuer either approves without asking the buyer anything (frictionless), or shows a challenge, such as a one-time code.
This page explains when PayMe runs 3D Secure, what each integration has to do, how to test it, and how to read the result. The step-by-step pages it links to have the full request and response fields.
When 3D Secure runs
A card payment gets 3D Secure when all three conditions hold. Google Pay has its own rule, described below.
- The seller's account has the 3D Secure service. PayMe enables it. An account that has never had it gets no 3D Secure.
- The card brand is supported. PayMe's 3D Secure provider doesn't support Discover, JCB or Isracard cards, so those cards are charged without 3D Secure.
- A rule selects the payment. Any one of these is enough:
- PayMe's system rules: a card issued in a country other than the seller's registered country; 3 or more installments; or an amount of at least the account's 3D Secure threshold. The amount rule compares
sale_pricein minor units with the threshold, without converting currencies, so the same number applies to every currency. - Rules of your own, which PayMe sets on the account. Ask your onboarding manager before you go live.
- The per-sale setting described below.
- PayMe's system rules: a card issued in a country other than the seller's registered country; 3 or more installments; or an amount of at least the account's 3D Secure threshold. The amount rule compares
3D Secure applies to card payments: credit-card, a card the buyer chose on a multi page, and Google Pay cards saved in the buyer's Google account (see Google Pay). It runs on authorize sales as well as on ordinary sales.
These payments never go through 3D Secure:
- A charge on a saved card with
buyer_keyongenerate-sale(see Save a card with a token sale). - Subscription charges.
- A token sale (
sale_type: token), which saves the card without charging it.
Turn it on or off for one sale
Send services with the 3DSecure service when you create the sale with Create a sale with 3D Secure:
{
"services": [{"name": "3DSecure", "settings": {"active": true}}]
}
"active": trueforces 3D Secure on this sale, while the account's 3D Secure service is turned on."active": falseturns off your account's own rules for this sale. PayMe's system rules still apply: a foreign card, 3 or more installments or an amount at or above the threshold still gets 3D Secure. You can't skip them for a single sale, for example a phone order. Only PayMe can switch the system rules off for the account.- Turning the 3D Secure service off doesn't take the account out of 3D Secure: PayMe's system rules still apply, and the per-sale setting has no effect.
- Each entry needs
settings: an entry without it returns error1after the sale has already been created. A setting for a service the account doesn't have is ignored, without an error.
What each integration does
| Integration | Who collects the browser data | How the challenge reaches the buyer | Details |
|---|---|---|---|
Hosted payment page (sale_url) |
PayMe's page | PayMe's page shows it | Below |
| Hosted Fields | PayMe.clientData() in your page, sent as meta_data_jwt |
pay-sale returns status_code: 5 and redirect_url |
3DS with Hosted Fields |
Direct API (pay-sale with card fields) |
You, sent as meta_data_jwt |
status_code: 5 and redirect_url |
Below |
Google Pay (googleSale()) |
PayMe's library | paymentCompleted gets status_code: 5 and redirect_url |
Accept Google Pay |
| Standalone 3D Secure | PayMe's JS library | status_code: 5 and redirect_url |
Standalone 3D Secure |
Hosted payment page
There's nothing extra to build. When a rule selects the payment, PayMe's page collects the browser data and shows the challenge. 3D Secure also works when you show sale_url in an iframe, but some issuing banks block their own challenge screen inside an iframe, so keep a fallback that opens the page in a full window. See Hosted Payment Page options.
- The buyer passes: PayMe charges the card and sends
sale-complete(orsale-authorizedfor anauthorizesale) withsale_3dsset to1. The buyer lands on the sale's return URL. - The buyer fails the challenge: the sale becomes
failedand PayMe sendssale-failurewithstatus_error_code21017. If the sale has a return URL (sale_return_url, or your partner's default), the buyer lands there withpayme_status=errorandstatus_error_code=21017. Without a return URL, the buyer goes tocancel_urlif you sent one, and otherwise back to the payment page to try another card.
A failed attempt doesn't close the sale: sale_url stays payable until the sale is paid, or until sale_expiry_seconds passes if you set it. See Understand the sale lifecycle.
Hosted Fields
Follow 3DS with Hosted Fields. In short:
- Tokenize the card with Hosted Fields.
- In the same page, call
PayMe.clientData(testMode)and send thehashit returns to your server. - Create the sale with
generate-salewithout abuyer_key, and setsale_callback_urlandsale_return_urlthere. - Call
pay-salewith thepayme_sale_id, the token asbuyer_key, and the hash asmeta_data_jwt. - Handle the result:
status_code5means send the buyer's browser toredirect_url;0paid;1declined.
Always send meta_data_jwt. Without it, pay-sale charges the token without 3D Secure, and nothing in the response tells you so.
Direct API (pay-sale)
The Direct API (PCI DSS Level 1 partners only) sends the card fields to pay-sale. PayMe runs 3D Secure inside the same call when a rule selects the payment:
- Send the buyer's browser data as
meta_data_jwt, collected in the buyer's browser withPayMe.clientData(). Without browser data, the card is charged without 3D Secure. Themeta_dataobject takes the IP address andAcceptheader from the request itself, so use it only on a call made from the buyer's browser. status_code5withredirect_urlmeans the issuer wants a challenge. Send the buyer's browser (the top window) toredirect_url;status_messageis a message you can show meanwhile. The result arrives in the sale callback, and the buyer lands onsale_return_url.status_code0means paid, andsale_3dstells you whether 3D Secure ran.status_code1is a decline, returned with HTTP 200.- If you already ran 3D Secure with another provider, send its
xid,eci,cavvand3ds_version. PayMe then doesn't run its own.
Google Pay
Whether 3D Secure runs on a Google Pay payment depends on the card, not on the rules or the device:
- A card stored on the buyer's device (Google's
CRYPTOGRAM_3DS) is charged directly, without PayMe's 3D Secure. - A card saved in the buyer's Google account (
PAN_ONLY) always goes through PayMe's 3D Secure, whatever the rules and the per-sale setting say. This needs the seller's 3D Secure service. Without it, or when 3D Secure can't run for the card, the payment fails with error21017"Verification failed, please try again".
With the googleSale() button, a payment that needs a challenge calls paymentCompleted(null, sale) with sale.status_code 5 and sale.redirect_url. The sale isn't paid yet: send the buyer to redirect_url. See Accept Google Pay.
Standalone 3D Secure
Use it to authenticate a card without charging it: when another gateway processes the payment, or when you authenticate now and charge later. The flow is on Standalone 3D Secure: process flow, and the background on 3D Secure as a service:
- Collect the browser data with PayMe's JS library and create a card sale.
- From the browser, call Start 3D Secure authentication. A frictionless approval returns
hash_3dsecure; a challenge returnsstatus_code5andredirect_url. - From your server, call Resolve a 3D Secure hash to get
eci,cavvandxidfor your gateway. If authentication failed, the result has a non-nullstatusand nocavv.
The seller needs the 3D Secure service (otherwise error 720), and the call needs the browser data (otherwise error 670).
Test it in the sandbox
The sandbox applies the same rules as production, so a rule must select the sale. 4918914107195005 is issued abroad, so the foreign-card rule selects it at any amount. For the other two cards, make sure a rule selects the sale, for example by forcing 3D Secure with services ("active": true). All three cards use expiry 07/28 and CVV 123.
| Card | What happens | What you see |
|---|---|---|
4918914107195005 |
Challenge. Enter 555 to pass; any other code (for example 111) fails. |
Pass: completed, sale_3ds 1. Fail: failed, error 21017 |
4907639999909022 |
Frictionless approval, no challenge | completed, sale_3ds 1 |
5283901906612672 |
Frictionless decline, no challenge | failed, error 21017 |
The full sandbox list is on Test Cards and Payment Methods.
Read the result
| Where | Field | Meaning |
|---|---|---|
| Sale callback | sale_3ds |
1 when the payment went through 3D Secure |
pay-sale response |
sale_3ds |
true when the payment passed 3D Secure |
get-sales and get-transactions |
sale_is_3ds |
true if the payment used 3D Secure. Also a filter: "sale_is_3ds": true returns only those payments |
| Standalone: Resolve a 3D Secure hash | eci, cavv, xid |
The values to send to your gateway |
Before you fulfil an order, confirm the sale with the callback or with get-sales, as described on Callbacks.
Failures and error codes
| What happened | What you get |
|---|---|
| The buyer failed the challenge | The sale becomes failed. sale-failure with status_error_code 21017 ("Verification failed, please try again"). The return-URL redirect carries payme_status=error |
| The issuer declined without a challenge | pay-sale returns HTTP 200 with status_code 1 and status_error_code 21017. The sale becomes failed, and PayMe sends sale-failure |
| The card or its issuer can't run 3D Secure | By default PayMe charges the card without 3D Secure, and sale_3ds is 0. If PayMe has set your account to refuse such payments, or for a Google Pay PAN_ONLY card, the payment fails with 21017 |
No browser data on pay-sale |
No error: the card is charged without 3D Secure |
| 3D Secure is required, but no terminal on the account can run it | Error 420 with 3DS in status_additional_info. Contact PayMe support |
| Standalone: the seller has no 3D Secure service | Error 720 |
| Standalone: the browser data is missing or unreadable | Error 670 |
A failed 3D Secure attempt is an ordinary failed attempt: the buyer can try again on the same sale. Error codes and the HTTP status of each are on Errors.