Start 3D Secure authentication

Credentials

Overview

Starts 3D Secure 2 authentication for a card on an existing sale, without charging it. Use it when another gateway processes the payment and you need the 3DS values (eci, cavv, xid) from PayMe's MPI. The whole flow: Standalone 3D Secure: process flow.

Call it from the buyer's browser with the seller's public key in the PayMe-Public-Key header. The sale must belong to that seller. Send the browser data that PayMe's JS library collected (meta_data_jwt); see 3DS integration using JS API.

The response has one of two outcomes:

The seller must have the 3D Secure service active.

Errors

HTTP Code When
400 670 meta_data_jwt (or meta_data) is missing or can't be read.
400 4 The sale uses another payment method.
400 720 3D Secure was blocked for this card.
500 720 3D Secure isn't available for this card, or the seller has no 3D Secure service.
500 350 No sale has this ID.
500 Card error code The card number or expiry is invalid, for example 356 for the expiry.
401 — The PayMe-Public-Key header is missing or unknown.
403 163 The seller isn't active.

Parameters

Name In Type Required Description
payme_sale_id path string yes The sale to authenticate (payme_sale_id). It must belong to the seller of the public key.
PayMe-Public-Key header string yes The seller's public key. Safe to use in the browser.

Request body

Content type: application/json

Field Type Required Description
payment object yes The card to authenticate.
payment.method string yes credit-card.
payment.card_number string no Card number. Required unless you send buyer_key.
payment.card_expiry string no Card expiry, MMYY. Required unless you send buyer_key.
payment.buyer_key string no A saved buyer token of this seller, instead of card_number and card_expiry.
customer object no Card holder details. Ignored when you send payment.buyer_key.
customer.name string no Card holder's name.
customer.email string no Card holder's email.
customer.phone string no Card holder's mobile number.
customer.social_id string no Card holder's national ID.
customer.zip_code string no Zip code.
customer.country string no Two-letter ISO country code.
customer.state string no State or region.
customer.city string no City.
customer.line1 string no Address line 1.
customer.line2 string no Address line 2.
meta_data_jwt string no The browser data from PayMe's JS library. Send this or meta_data; without either, the call fails with error 670.
meta_data object no The browser data as a plain object, instead of meta_data_jwt. PayMe adds the buyer's IP and Accept header from the request, so send it from the buyer's browser.
meta_data.browser object yes Browser details: userAgent, language, colorDepth, screen (height, width), timezone, javaEnabled and javaScriptEnabled.
language string no Language of error messages: he (default), en, es, ru or ar.

Request example

{
  "payment": {
    "method": "credit-card",
    "card_number": "4111111111111111",
    "card_expiry": "1230"
  },
  "customer": {
    "name": "Israel Israeli",
    "email": "buyer@example.com",
    "phone": "0500000000"
  },
  "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY"
}

Code samples

curl

curl -X POST 'https://sandbox.payme.io/api/sales/<payme_sale_id>/3ds' \
  -H 'Content-Type: application/json' \
  -H 'PayMe-Public-Key: <PayMe-Public-Key>' \
  --data-raw '{
  "payment": {
    "method": "credit-card",
    "card_number": "4111111111111111",
    "card_expiry": "1230"
  },
  "customer": {
    "name": "Israel Israeli",
    "email": "buyer@example.com",
    "phone": "0500000000"
  },
  "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY"
}'

Node.js

const response = await fetch("https://sandbox.payme.io/api/sales/<payme_sale_id>/3ds", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "PayMe-Public-Key": "<PayMe-Public-Key>",
  },
  body: JSON.stringify({
    "payment": {
      "method": "credit-card",
      "card_number": "4111111111111111",
      "card_expiry": "1230"
    },
    "customer": {
      "name": "Israel Israeli",
      "email": "buyer@example.com",
      "phone": "0500000000"
    },
    "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY"
  }),
});

console.log(await response.text());

Python

import requests

response = requests.post(
    "https://sandbox.payme.io/api/sales/<payme_sale_id>/3ds",
    headers={
        "PayMe-Public-Key": "<PayMe-Public-Key>",
    },
    json={
        "payment": {
            "method": "credit-card",
            "card_number": "4111111111111111",
            "card_expiry": "1230",
        },
        "customer": {
            "name": "Israel Israeli",
            "email": "buyer@example.com",
            "phone": "0500000000",
        },
        "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY",
    },
)

print(response.text)

PHP

<?php

$body = <<<'BODY'
{
  "payment": {
    "method": "credit-card",
    "card_number": "4111111111111111",
    "card_expiry": "1230"
  },
  "customer": {
    "name": "Israel Israeli",
    "email": "buyer@example.com",
    "phone": "0500000000"
  },
  "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY"
}
BODY;

$ch = curl_init('https://sandbox.payme.io/api/sales/<payme_sale_id>/3ds');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'PayMe-Public-Key: <PayMe-Public-Key>',
    ],
    CURLOPT_POSTFIELDS => $body,
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

Responses

200 — Frictionless approval (0) or a challenge (5). (success)

Field Type Description
status_code integer 0 frictionless approval: hash_3dsecure is returned. 5 challenge: send the buyer to redirect_url.
hash_3dsecure string The encrypted 3DS result, when status_code is 0. Resolve it with Resolve a 3D Secure hash.
status_message string A message you can show the buyer while redirecting, when status_code is 5.
redirect_url string The issuer's challenge page, when status_code is 5. Open it with GET in the buyer's browser.
{
  "status_code": 5,
  "status_message": "Generating validation page, please wait",
  "redirect_url": "https://sandbox.payme.io/3ds/redirect/SALE1700-000000AA-EXAMPLE1-SALE0001?pa=REDACTED"
}

400 — Browser data is missing, the sale uses another payment method, or 3D Secure was blocked. Codes: 4, 670, 720. (error)

Field Type Description
status_code integer 1 on failure.
status_error_details string What went wrong, in the language you asked for (Hebrew by default).
status_additional_info string The field or value concerned. Can be null.
status_error_code integer PayMe error code. See the error table above and Errors.
session string PayMe session ID. Quote it when you contact support.
{
  "status_code": 1,
  "status_error_details": "Meta data details are missing",
  "status_additional_info": null,
  "status_error_code": 670,
  "session": "a1B2c3D4"
}

500 — 3D Secure isn't available, the sale wasn't found, or the card data is invalid. See the error table. (error)

Field Type Description
status_code integer 1 on failure.
status_error_details string What went wrong, in the language you asked for (Hebrew by default).
status_additional_info string The field or value concerned. Can be null.
status_error_code integer PayMe error code. See the error table above and Errors.
session string PayMe session ID. Quote it when you contact support.
{
  "status_code": 1,
  "status_error_details": "Invalid credit card expiry",
  "status_additional_info": "1221f",
  "status_error_code": 356,
  "session": "a1B2c3D4"
}