Skip to content
payrocdevelopers

Run a sale with 3-D Secure

Run a card sale with 3-D Secure authentication by sending an MPI request to verify the cardholder's identity, then submitting the MPI reference in a POST request to the Payments endpoint.

Prerequisites: Authentication

Use our 3-D Secure feature to verify a cardholder’s identity during an e-Commerce transaction.

Integration steps

Step 1. Sign up for 3-D Secure.
Step 2. Convert the cardholder’s payment details into a single-use token.
Step 3. Send a

merchant plug-in (MPI)

request.
Step 4. Include the MPI reference in a payment request.

Before you begin

Authenticate your requests before making API calls. If your request fails, see Errors.

Step 1. Sign up for 3-D Secure

To sign up for 3-D Secure, contact our Customer Support team at cs@payroc.com.

We use request forwarding to send you the results of the 3-D Secure check. When you sign up for 3-D Secure, provide a URL that we forward the requests to.

Step 2. Convert the cardholder’s payment details into a single-use token

Before you can send a request to our MPI service, you need to convert the cardholder’s payment details into a single-use token.

To create a single-use token, you can use Hosted Fields or you can use our tokenization feature in our API.

Step 3. Send an MPI request

Send the single-use token to our MPI service with information about the transaction in the query parameters.

EnvironmentURL
Testhttps://payments.uat.payroc.com/merchant/mpi
Productionhttps://payments.payroc.com/merchant/mpi

Query parameters

ParameterTypeRequired?Description
processingTerminalIdstringYesUnique identifier that we assigned to the terminal.
singleUseTokenstringYesUnique token that the gateway assigned to the payment details.
emailstringYesCardholder’s email address.
amountnumber <double>YesTotal amount of the transaction, which includes surcharges. The value is in the currency’s lowest denomination, for example, cents.
currencystringYesISO-4217 currency code of the transaction.
orderIdstringYesUnique identifier that the merchant assigns to the order.
cardholderChallengestringNoIndicates if the merchant wants the issuing bank to challenge the cardholder. Send one of the following values: • REQUIRED - Merchant wants the issuing bank to challenge the cardholder. • OPTIONAL - Issuing bank decides whether to challenge the cardholder.

Example request

https://payments.payroc.com/merchant/mpi?processingTerminalId=4479001&amount=100&currency=EUR&orderId=25&email=joe%40adomain.com&singleUseToken=1a8731f50b02e287ac0529fbce352317c089d4adc1178c1867d65114078791d3c3e13962cbab6b574769dfe9ad5397a5aa67a529ceb0b7be17751f076bbe0e4d

Response fields

If your request is successful, we send a GET request to your MPI receipt URL with the results of the 3-D Secure check and the MPI reference. The response fields are in the query parameters of the GET request.

FieldDescription
resultIndicates the result of the 3-D Secure check. We return one of the following values: • A - The issuing bank approved the transaction. • D - The issuing bank declined the transaction.
mpiReferenceMPI reference of the 3-D Secure check.
orderIdUnique identifier that the merchant assigned to the order.
statusStatus of the 3-D Secure check. We return one of the following values: • A - Issuing bank attempted to authenticate the cardholder’s identity. • N - Issuing bank didn’t attempt to authenticate the cardholder’s identity. • U - Issuing bank was unable to authenticate the cardholder’s identity. • Y - Issuing bank authenticated the cardholder’s identity.
eciResponse code from 3-D Secure. We return one of the following values: • 05 - Issuing bank used 3-D Secure to authenticate the cardholder. • 06 - Issuing bank or cardholder is not enrolled for 3D Secure. • 07 - 3-D Secure check failed.

Example response

https://{MPI_RECEIPT_URL}?result=A&status=A&eci=06&mpiReference=d01656cf0ec3e62e3754&orderId=25

Step 4. Run a sale

To run a sale, send a POST request to our Payments endpoint.

EnvironmentURL
Testhttps://api.uat.payroc.com/v1/payments
Productionhttps://api.payroc.com/v1/payments

In your request, send the following parameters in the threeDSecure object:

  • serviceProvider – Provide a value of gateway.
  • mpiReference – Provide the MPI reference that we sent your MPI receipt URL in Step 2.

Request parameters

To create the body of your request, use the following parameters:

Schema (request.body)

Request body schema for POST /payments

Example request

Request

POST https://api.payroc.com/v1/payments

curl
curl -X POST https://api.payroc.com/v1/payments \
     -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "channel": "web",
  "processingTerminalId": "1234001",
  "order": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "currency": "USD",
    "description": "Large Pepperoni Pizza"
  },
  "paymentMethod": {
    "type": "card",
    "cardDetails": {
      "entryMethod": "keyed",
      "keyedData": {
        "dataFormat": "plainText",
        "cardNumber": "4539858876047062",
        "device": {
          "model": "paxA80",
          "serialNumber": "WPC202833004712"
        },
        "expiryDate": "1230"
      }
    }
  },
  "operator": "Jane",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2",
      "address3": "Example Address Line 3"
    },
    "shippingAddress": {
      "recipientName": "Sarah Hopper",
      "address": {
        "address1": "1 Example Ave.",
        "city": "Chicago",
        "state": "Illinois",
        "country": "US",
        "postalCode": "60056",
        "address2": "Example Address Line 2",
        "address3": "Example Address Line 3"
      }
    }
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}'

Card Payment

Python
import requests

url = "https://api.payroc.com/v1/payments"

payload = {
    "channel": "web",
    "processingTerminalId": "1234001",
    "order": {
        "orderId": "OrderRef6543",
        "amount": 4999,
        "currency": "USD",
        "description": "Large Pepperoni Pizza"
    },
    "paymentMethod": {
        "type": "card",
        "cardDetails": {
            "entryMethod": "keyed",
            "keyedData": {
                "dataFormat": "plainText",
                "cardNumber": "4539858876047062",
                "device": {
                    "model": "paxA80",
                    "serialNumber": "WPC202833004712"
                },
                "expiryDate": "1230"
            }
        }
    },
    "operator": "Jane",
    "customer": {
        "firstName": "Sarah",
        "lastName": "Hopper",
        "billingAddress": {
            "address1": "1 Example Ave.",
            "city": "Chicago",
            "state": "Illinois",
            "country": "US",
            "postalCode": "60056",
            "address2": "Example Address Line 2",
            "address3": "Example Address Line 3"
        },
        "shippingAddress": {
            "recipientName": "Sarah Hopper",
            "address": {
                "address1": "1 Example Ave.",
                "city": "Chicago",
                "state": "Illinois",
                "country": "US",
                "postalCode": "60056",
                "address2": "Example Address Line 2",
                "address3": "Example Address Line 3"
            }
        }
    },
    "customFields": [
        {
            "name": "yourCustomField",
            "value": "abc123"
        }
    ]
}
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())

Card Payment

JavaScript
const url = 'https://api.payroc.com/v1/payments';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"channel":"web","processingTerminalId":"1234001","order":{"orderId":"OrderRef6543","amount":4999,"currency":"USD","description":"Large Pepperoni Pizza"},"paymentMethod":{"type":"card","cardDetails":{"entryMethod":"keyed","keyedData":{"dataFormat":"plainText","cardNumber":"4539858876047062","device":{"model":"paxA80","serialNumber":"WPC202833004712"},"expiryDate":"1230"}}},"operator":"Jane","customer":{"firstName":"Sarah","lastName":"Hopper","billingAddress":{"address1":"1 Example Ave.","city":"Chicago","state":"Illinois","country":"US","postalCode":"60056","address2":"Example Address Line 2","address3":"Example Address Line 3"},"shippingAddress":{"recipientName":"Sarah Hopper","address":{"address1":"1 Example Ave.","city":"Chicago","state":"Illinois","country":"US","postalCode":"60056","address2":"Example Address Line 2","address3":"Example Address Line 3"}}},"customFields":[{"name":"yourCustomField","value":"abc123"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}

Card Payment

go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/payments"

	payload := strings.NewReader("{\n  \"channel\": \"web\",\n  \"processingTerminalId\": \"1234001\",\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"currency\": \"USD\",\n    \"description\": \"Large Pepperoni Pizza\"\n  },\n  \"paymentMethod\": {\n    \"type\": \"card\",\n    \"cardDetails\": {\n      \"entryMethod\": \"keyed\",\n      \"keyedData\": {\n        \"dataFormat\": \"plainText\",\n        \"cardNumber\": \"4539858876047062\",\n        \"device\": {\n          \"model\": \"paxA80\",\n          \"serialNumber\": \"WPC202833004712\"\n        },\n        \"expiryDate\": \"1230\"\n      }\n    }\n  },\n  \"operator\": \"Jane\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\",\n      \"address3\": \"Example Address Line 3\"\n    },\n    \"shippingAddress\": {\n      \"recipientName\": \"Sarah Hopper\",\n      \"address\": {\n        \"address1\": \"1 Example Ave.\",\n        \"city\": \"Chicago\",\n        \"state\": \"Illinois\",\n        \"country\": \"US\",\n        \"postalCode\": \"60056\",\n        \"address2\": \"Example Address Line 2\",\n        \"address3\": \"Example Address Line 3\"\n      }\n    }\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Card Payment

ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/payments")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"channel\": \"web\",\n  \"processingTerminalId\": \"1234001\",\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"currency\": \"USD\",\n    \"description\": \"Large Pepperoni Pizza\"\n  },\n  \"paymentMethod\": {\n    \"type\": \"card\",\n    \"cardDetails\": {\n      \"entryMethod\": \"keyed\",\n      \"keyedData\": {\n        \"dataFormat\": \"plainText\",\n        \"cardNumber\": \"4539858876047062\",\n        \"device\": {\n          \"model\": \"paxA80\",\n          \"serialNumber\": \"WPC202833004712\"\n        },\n        \"expiryDate\": \"1230\"\n      }\n    }\n  },\n  \"operator\": \"Jane\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\",\n      \"address3\": \"Example Address Line 3\"\n    },\n    \"shippingAddress\": {\n      \"recipientName\": \"Sarah Hopper\",\n      \"address\": {\n        \"address1\": \"1 Example Ave.\",\n        \"city\": \"Chicago\",\n        \"state\": \"Illinois\",\n        \"country\": \"US\",\n        \"postalCode\": \"60056\",\n        \"address2\": \"Example Address Line 2\",\n        \"address3\": \"Example Address Line 3\"\n      }\n    }\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body

Card Payment

Java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/payments")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"channel\": \"web\",\n  \"processingTerminalId\": \"1234001\",\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"currency\": \"USD\",\n    \"description\": \"Large Pepperoni Pizza\"\n  },\n  \"paymentMethod\": {\n    \"type\": \"card\",\n    \"cardDetails\": {\n      \"entryMethod\": \"keyed\",\n      \"keyedData\": {\n        \"dataFormat\": \"plainText\",\n        \"cardNumber\": \"4539858876047062\",\n        \"device\": {\n          \"model\": \"paxA80\",\n          \"serialNumber\": \"WPC202833004712\"\n        },\n        \"expiryDate\": \"1230\"\n      }\n    }\n  },\n  \"operator\": \"Jane\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\",\n      \"address3\": \"Example Address Line 3\"\n    },\n    \"shippingAddress\": {\n      \"recipientName\": \"Sarah Hopper\",\n      \"address\": {\n        \"address1\": \"1 Example Ave.\",\n        \"city\": \"Chicago\",\n        \"state\": \"Illinois\",\n        \"country\": \"US\",\n        \"postalCode\": \"60056\",\n        \"address2\": \"Example Address Line 2\",\n        \"address3\": \"Example Address Line 3\"\n      }\n    }\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}")
  .asString();

Card Payment

PHP
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/payments', [
  'body' => '{
  "channel": "web",
  "processingTerminalId": "1234001",
  "order": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "currency": "USD",
    "description": "Large Pepperoni Pizza"
  },
  "paymentMethod": {
    "type": "card",
    "cardDetails": {
      "entryMethod": "keyed",
      "keyedData": {
        "dataFormat": "plainText",
        "cardNumber": "4539858876047062",
        "device": {
          "model": "paxA80",
          "serialNumber": "WPC202833004712"
        },
        "expiryDate": "1230"
      }
    }
  },
  "operator": "Jane",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2",
      "address3": "Example Address Line 3"
    },
    "shippingAddress": {
      "recipientName": "Sarah Hopper",
      "address": {
        "address1": "1 Example Ave.",
        "city": "Chicago",
        "state": "Illinois",
        "country": "US",
        "postalCode": "60056",
        "address2": "Example Address Line 2",
        "address3": "Example Address Line 3"
      }
    }
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();

Card Payment

C#
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/payments");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"channel\": \"web\",\n  \"processingTerminalId\": \"1234001\",\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"currency\": \"USD\",\n    \"description\": \"Large Pepperoni Pizza\"\n  },\n  \"paymentMethod\": {\n    \"type\": \"card\",\n    \"cardDetails\": {\n      \"entryMethod\": \"keyed\",\n      \"keyedData\": {\n        \"dataFormat\": \"plainText\",\n        \"cardNumber\": \"4539858876047062\",\n        \"device\": {\n          \"model\": \"paxA80\",\n          \"serialNumber\": \"WPC202833004712\"\n        },\n        \"expiryDate\": \"1230\"\n      }\n    }\n  },\n  \"operator\": \"Jane\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\",\n      \"address3\": \"Example Address Line 3\"\n    },\n    \"shippingAddress\": {\n      \"recipientName\": \"Sarah Hopper\",\n      \"address\": {\n        \"address1\": \"1 Example Ave.\",\n        \"city\": \"Chicago\",\n        \"state\": \"Illinois\",\n        \"country\": \"US\",\n        \"postalCode\": \"60056\",\n        \"address2\": \"Example Address Line 2\",\n        \"address3\": \"Example Address Line 3\"\n      }\n    }\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Card Payment

swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "channel": "web",
  "processingTerminalId": "1234001",
  "order": [
    "orderId": "OrderRef6543",
    "amount": 4999,
    "currency": "USD",
    "description": "Large Pepperoni Pizza"
  ],
  "paymentMethod": [
    "type": "card",
    "cardDetails": [
      "entryMethod": "keyed",
      "keyedData": [
        "dataFormat": "plainText",
        "cardNumber": "4539858876047062",
        "device": [
          "model": "paxA80",
          "serialNumber": "WPC202833004712"
        ],
        "expiryDate": "1230"
      ]
    ]
  ],
  "operator": "Jane",
  "customer": [
    "firstName": "Sarah",
    "lastName": "Hopper",
    "billingAddress": [
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2",
      "address3": "Example Address Line 3"
    ],
    "shippingAddress": [
      "recipientName": "Sarah Hopper",
      "address": [
        "address1": "1 Example Ave.",
        "city": "Chicago",
        "state": "Illinois",
        "country": "US",
        "postalCode": "60056",
        "address2": "Example Address Line 2",
        "address3": "Example Address Line 3"
      ]
    ]
  ],
  "customFields": [
    [
      "name": "yourCustomField",
      "value": "abc123"
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/payments")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```nse fields

If your request is successful, we create the payment and return a response. The response contains the following fields:

### Schema (`response.body`)

[Response body schema for `POST /payments`](/api/payment)

le response

### Response (201)

```json
{
  "paymentId": "M2MJOG6O2Y",
  "processingTerminalId": "1234001",
  "order": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "currency": "USD",
    "dateTime": "2024-07-02T15:30:00Z",
    "description": "Large Pepperoni Pizza"
  },
  "card": {
    "type": "MasterCard",
    "entryMethod": "keyed",
    "cardNumber": "453985******7062",
    "expiryDate": "1230",
    "securityChecks": {
      "cvvResult": "M",
      "avsResult": "Y"
    }
  },
  "transactionResult": {
    "status": "ready",
    "responseCode": "A",
    "type": "sale",
    "approvalCode": "OK3",
    "authorizedAmount": 4999,
    "currency": "USD",
    "responseMessage": "OK3"
  },
  "operator": "Jane",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "address2": "Example Address Line 2",
      "address3": "Example Address Line 3",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056"
    },
    "shippingAddress": {
      "recipientName": "Sarah Hopper",
      "address": {
        "address1": "1 Example Ave.",
        "address2": "Example Address Line 2",
        "address3": "Example Address Line 3",
        "city": "Chicago",
        "state": "Illinois",
        "country": "US",
        "postalCode": "60056"
      }
    }
  },
  "supportedOperations": [
    "capture",
    "fullyReverse",
    "partiallyReverse",
    "incrementAuthorization",
    "adjustTip",
    "setAsPending"
  ],
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}

Browse guides

Search documentation

API reference169
Guides118
Knowledge38
legal1
Solutions32
Workflows74
↑↓highlight↵openView all search results

Menu

Theme

Sign out

Your saved plans remain in your organization. This browser’s private draft and account view will be cleared.

Talk to an engineer