COPYandPAY network tokens

Last updated: 2026-03-24

COPYandPAY securely collects card data from shoppers and initiates network token provisioning with the respective card network. You receive a merchant token to store for future use, such as recurring or one-click payments. The different ways to do this are:

📘
  • The Tokenisation page offers detailed information on network tokens.
  • For details on which acquirers support network tokens, contact support.

Tokenisation during payment

Collect card data from the customer via a widget and initiate tokenisation along with account verification (zero amount auth) or an initial purchase. A merchant token is synchronously provisioned and returned to you after the payment completes. You can use the merchant token in subsequent payments. In the background, the card network provisions a network token with the issuer involved in the token approval process. The payment authorises with real card data or the network token if it is available and active.

The two ways to store raw card details during a payment checkout:

  • Merchant-determined tokenisation: Add createRegistration=true in the checkout request.
  • Shopper-determined tokenisation: Add a checkbox to the COPYandPAY form to let the customer decide whether to store the raw card details.

1. Prepare the checkout

To start network token provisioning, perform a server-to-server POST request with createRegistration=true and all required payment and customer data, including payment type, amount, and currency. The response to a successful request returns an id, which you require in the second step to create the payment form.

Sample request:

curl https://sandbox-card.peachpayments.com/v1/checkouts \
 -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
 -d "customParameters[3DS2_enrolled]=true" \
 -d "customParameters[3DS2_flow]=challenge" \
 -d "testMode=EXTERNAL" \
 -d "**createRegistration=true**" \
 -d "amount=11.12" \
 -d "currency=EUR" \
 -d "paymentType=DB" \
 -d "standingInstruction.mode=INITIAL" \
 -d "standingInstruction.source=CIT" \
 -d "standingInstruction.type=UNSCHEDULED" \
 -d "customer.givenName=Smith" \
 -d "customer.ip=192.168.0.0" \
 -d "customer.surname=John" \
 -d "customer.language=DE" \
 -d "[email protected]" \
 -d "billing.city=MyCity" \
 -d "billing.country=DE" \
 -d "billing.postcode=712121" \
 -d "billing.state=DE" \
 -d "billing.street1=MyStreet" \
 -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&createRegistration=true**" +
        "&amount=11.12" +
        "&currency=EUR" +
        "&paymentType=DB" +
        "&standingInstruction.mode=INITIAL" +
        "&standingInstruction.source=CIT" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet";

    string url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    request.ContentType = "application/x-www-form-urlencoded";

    using (Stream postData = request.GetRequestStream()) {
        postData.Write(buffer, 0, buffer.Length);
    }

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var serializer = new JavaScriptSerializer();
        responseData = serializer.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }

    return responseData;
}

var description = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = """
    entityId=8ac7a4c98ab5c40a018ab810cbc803fc
    &customParameters[3DS2_enrolled]=true
    &customParameters[3DS2_flow]=challenge
    &testMode=EXTERNAL
    &**createRegistration=true**
    &amount=11.12
    &currency=EUR
    &paymentType=DB
    &standingInstruction.mode=INITIAL
    &standingInstruction.source=CIT
    &standingInstruction.type=UNSCHEDULED
    &customer.givenName=Smith
    &customer.ip=192.168.0.0
    &customer.surname=John
    &customer.language=DE
    &[email protected]
    &billing.city=MyCity
    &billing.country=DE
    &billing.postcode=712121
    &billing.state=DE
    &billing.street1=MyStreet
  """.trim()

  def url = "https://sandbox-card.peachpayments.com/v1/checkouts".toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  connection.doOutput = true
  connection.outputStream.withWriter { writer -> writer << data }

  def response = connection.inputStream.text
  def json = new JsonSlurper().parseText(response)
  
  return json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    String data = ""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&customParameters[3DS2_enrolled]=true"
        + "&customParameters[3DS2_flow]=challenge"
        + "&testMode=EXTERNAL"
        + "&createRegistration=true**"
        + "&amount=11.12"
        + "&currency=EUR"
        + "&paymentType=DB"
        + "&standingInstruction.mode=INITIAL"
        + "&standingInstruction.source=CIT"
        + "&standingInstruction.type=UNSCHEDULED"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet";

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(data);
    wr.flush();
    wr.close();

    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) {
        is = conn.getErrorStream();
    } else {
        is = conn.getInputStream();
    }

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    const path = '/v1/checkouts';
    const data = querystring.stringify({
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]': 'true',
        'customParameters[3DS2_flow]': 'challenge',
        'testMode': 'EXTERNAL',
        '**createRegistration**': '**true**',
        'amount': '11.12',
        'currency': 'EUR',
        'paymentType': 'DB',
        'standingInstruction.mode': 'INITIAL',
        'standingInstruction.source': 'CIT',
        'standingInstruction.type': 'UNSCHEDULED',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    });

    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length,
            'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };

    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        postRequest.on('error', reject);
        postRequest.write(data);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    $data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" .
            "&customParameters[3DS2_enrolled]=true" .
            "&customParameters[3DS2_flow]=challenge" .
            "&testMode=EXTERNAL" .
            "&createRegistration=true**" .
            "&amount=11.12" .
            "&currency=EUR" .
            "&paymentType=DB" .
            "&standingInstruction.mode=INITIAL" .
            "&standingInstruction.source=CIT" .
            "&standingInstruction.type=UNSCHEDULED" .
            "&customer.givenName=Smith" .
            "&customer.ip=192.168.0.0" .
            "&customer.surname=John" .
            "&customer.language=DE" .
            "&[email protected]" .
            "&billing.city=MyCity" .
            "&billing.country=DE" .
            "&billing.postcode=712121" .
            "&billing.state=DE" .
            "&billing.street1=MyStreet";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization:Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // this should be set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    if (curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts"
    data = {
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]': 'true',
        'customParameters[3DS2_flow]': 'challenge',
        'testMode': 'EXTERNAL',
        'createRegistration': 'true',
        'amount': '11.12',
        'currency': 'EUR',
        'paymentType': 'DB',
        'standingInstruction.mode': 'INITIAL',
        'standingInstruction.source': 'CIT',
        'standingInstruction.type': 'UNSCHEDULED',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    }
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
  uri = URI('https://sandbox-card.peachpayments.com/v1/checkouts')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Post.new(uri.path)
  req.set_form_data({
    'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
    'customParameters[3DS2_enrolled]' => 'true',
    'customParameters[3DS2_flow]' => 'challenge',
    'testMode' => 'EXTERNAL',
    'createRegistration' => 'true',
    'amount' => '11.12',
    'currency' => 'EUR',
    'paymentType' => 'DB',
    'standingInstruction.mode' => 'INITIAL',
    'standingInstruction.source' => 'CIT',
    'standingInstruction.type' => 'UNSCHEDULED',
    'customer.givenName' => 'Smith',
    'customer.ip' => '192.168.0.0',
    'customer.surname' => 'John',
    'customer.language' => 'DE',
    'customer.email' => '[email protected]',
    'billing.city' => 'MyCity',
    'billing.country' => 'DE',
    'billing.postcode' => '712121',
    'billing.state' => 'DE',
    'billing.street1' => 'MyStreet'
  })
  res = http.request(req)
  return JSON.parse(res.body)
end

puts request()
def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts"
  val data = ("" 
    + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
    + "&customParameters[3DS2_enrolled]=true"
    + "&customParameters[3DS2_flow]=challenge"
    + "&testMode=EXTERNAL"
    + "&createRegistration=true"
    + "&amount=11.12"
    + "&currency=EUR"
    + "&paymentType=DB"
    + "&standingInstruction.mode=INITIAL"
    + "&standingInstruction.source=CIT"
    + "&standingInstruction.type=UNSCHEDULED"
    + "&customer.givenName=Smith"
    + "&customer.ip=192.168.0.0"
    + "&customer.surname=John"
    + "&customer.language=DE"
    + "&[email protected]"
    + "&billing.city=MyCity"
    + "&billing.country=DE"
    + "&billing.postcode=712121"
    + "&billing.state=DE"
    + "&billing.street1=MyStreet"
  )
  val conn = new URL(url).openConnection()

  conn match {
    case secureConn: HttpsURLConnection => secureConn.setRequestMethod("POST")
    case _ => throw new ClassCastException
  }
  conn.setDoInput(true)
  conn.setDoOutput(true)
  IOUtils.write(data, conn.getOutputStream())
  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()
  if (conn.getResponseCode() >= 400) {
    return IOUtils.toString(conn.getErrorStream())
  } else {
    return IOUtils.toString(conn.getInputStream())
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts"
    Dim data As String = "" +
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&createRegistration=true" +
        "&amount=11.12" +
        "&currency=EUR" +
        "&paymentType=DB" +
        "&standingInstruction.mode=INITIAL" +
        "&standingInstruction.source=CIT" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "POST"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
    req.ContentLength = byteArray.Length
    Dim dataStream As Stream = req.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    reader.Close()
    resStream.Close()
    res.Close()
    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)

    Return dict
End Function

responseData = Request()("result")("description")
{
  "result":{
    "code":"000.200.100",
    "description":"successfully created checkout"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 15:49:58+0000",
  "ndc":"8BAA6308D373155E3A786D1CCFAA69A8.uat01-vm-tx03",
  "id":"8BAA6308D373155E3A786D1CCFAA69A8.uat01-vm-tx03",
  "integrity":"sha384-vm7PCynkXLx+9PVd6gj+FcDzaK/j45U70n2glX7i5+px3h2dgTUcJEbkMIP1CPk2"
}

2. Create the payment form

Create the payment form by adding the following lines of HTML/JavaScript to your page:

  • With the checkoutId received from first step:
    <script  
      src="https://sandbox-card.peachpayments.com/v1/paymentWidgets.js?checkoutId={checkout_id}"  
      integrity="{integrity}"  
      crossorigin="anonymous">  
    </script>
  • With the shopperResultUrl as the page on your site where the customer redirects after completing the payment:
    <form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>

Sample form:

<form action="https://developer.peachpayments.com/docs/oppwa-integrations-copyandpay-network-tokens" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>
body {background-color:#f6f6f5;}
var wpwlOptions = {style:"card", registrations: {requireCvv: true}, paymentTarget: "_top"}
Card form.

Card form.

3. Get the payment status

After the payment request processes, the customer redirects to your shopperResultUrl along with a GET parameter resourcePath=/v1/checkouts/{checkoutId}/registration

Payment response

The response includes a token transaction history, indicating that the network token provisioning process started with the card network. The system attempts to fetch the network token before the 3-D Secure authentication and payment authorisation begin. Due to a simulated 2-second delay in the test environment, the network token provisioning request remains in flight, and if no network token is active, both the 3-D Secure authentication and, payment authorisation continue using the real card data.

When the system fetches the network token, the response provides the original PAN BIN. This information appears in the payment response as part of the card.bin parameter. The network token BIN differs from the original PAN BIN. This distinction proves crucial for post-authorisation issuer BIN management, ensuring that you have the necessary details to handle the transaction accurately.

Sample request:

https://sandbox-card.peachpayments.com/v1/checkouts/C3C9A3741C3EF2121921A760AE3257DF.uat01-vm-tx03/payment

curl -G https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment \
  -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
  -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc";
    string url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data;
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "GET";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var s = new JavaScriptSerializer();
        responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    return responseData;
}

responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  def url = ("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data).toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("GET")
  connection.setRequestProperty("Authorization","Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  def json = new JsonSlurper().parseText(connection.inputStream.text)
  json
}
println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?entityId=8ac7a4c98ab5c40a018ab810cbc803fc");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) is = conn.getErrorStream();
    else is = conn.getInputStream();

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    let path = '/v1/checkouts/{id}/payment';
    path += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc';
    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'GET',
        headers: {
            'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };
    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        postRequest.on('error', reject);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment";
    $url .= "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                   'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    if (curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"
    url += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc'
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=b'')
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'GET'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
  path = "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  uri = URI.parse('https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment' + path)  # Replace {id} with actual checkout ID
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
  res = http.request(req)
  return JSON.parse(res.body)
end

puts request()
import java.net.{URL, HttpURLConnection}
import javax.net.ssl.HttpsURLConnection
import org.apache.commons.io.IOUtils

def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"  // Replace {id} with the actual checkout ID
  val fullUrl = url + "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  val conn = new URL(fullUrl).openConnection()

  conn match {
    case secureConn: HttpsURLConnection  => secureConn.setRequestMethod("GET")
    case _ => throw new ClassCastException
  }

  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()

  if (conn.getResponseCode >= 400) {
    return IOUtils.toString(conn.getErrorStream())
  } else {
    return IOUtils.toString(conn.getInputStream())
  }
}
import java.net.{URL, HttpURLConnection}
import javax.net.ssl.HttpsURLConnection
import org.apache.commons.io.IOUtils

def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"  // Replace {id} with the actual checkout ID
  val fullUrl = url + "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  val conn = new URL(fullUrl).openConnection()

  conn match {
    case secureConn: HttpsURLConnection  => secureConn.setRequestMethod("GET")
    case _ => throw new ClassCastException
  }

  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()

  if (conn.getResponseCode >= 400) {
    return IOUtils.toString(conn.getErrorStream())
  } else {
    return IOUtils.toString(conn.getInputStream())
  }
}
{
  "id":"8ac7a4a19d1f98d2019d20b1bc360350",
  "registrationId":"8ac7a4a09d1fa573019d20b1b9235eca",
  "paymentType":"DB",
  "paymentBrand":"VISA",
  "amount":"11.12",
  "currency":"EUR",
  "descriptor":"7763.6489.2068 NetworkToken3DChannel",
  "recurringType":"INITIAL",
  "result":{
    "avsResponse":"F",
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "resultDetails":{
    "Status":"AUTHORIZED",
    "ResponseCode":"00",
    "ConnectorTxID1":"7743700181376871404807",
    "AcquirerReconciliationId":"7743700181376871404807",
    "ConnectorTxID3":"7743700181376871404807",
    "ConnectorTxID2":"8ac7a4a19d1f98d2019d20b1bc360350",
    "retrievalReferenceNumber":"608316215354",
    "CardholderInitiatedTransactionID":"016153570198200",
    "ApprovalCode":"831000",
    "TransactionId":"016153570198200",
    "ExtendedDescription":"Successful approval.",
    "usedChallengeIndicator":"04",
    "avs.codeRaw":"Y",
    "authorizedAmount":"11.12",
    "avs.code":"Y",
    "AcquirerResponse":"AUTHORIZED",
    "reconciliationId":"8ac7a4a19d1f98d2019d20b1bc360350",
    "NetworkTransactionId":"016153570198200"
  },
  "card":{
    "bin":"420000",
    "last4Digits":"0091",
    "holder":"John Doe",
    "expiryMonth":"12",
    "expiryYear":"2029"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "threeDSecure":{
    "eci":"05",
    "version":"2.2.0",
    "dsTransactionId":"ef59e5a8-7c31-4605-a902-ede9315aecee",
    "challengeMandatedIndicator":"N",
    "transactionStatusReason":"",
    "acsTransactionId":"69e87b7d-c5c4-46bf-9c5e-1b6d4e7222fa",
    "cardHolderInfo":"",
    "authType":"01",
    "flow":"challenge",
    "authenticationStatus":"Y",
    "acsReferenceNumber":"b04ea28d11294692a29f63d2f5c84bfc",
    "dsReferenceNumber":"13db2d60d08c4f6b83de194ca5245e57",
    "purchaseDate":"20260324163332"
  },
  "customParameters":{
    "StandingInstructionAPI":"true",
    "SHOPPER_EndToEndIdentity":"270b1a2bb97f52e492a6705980a4bac8c4d046df3c653f620749275dc993fe41",
    "CTPE_DESCRIPTOR_TEMPLATE":"",
    "3DS2_flow":"challenge",
    "StoredCredentialType":"CIT",
    "StandingInstruction":"UNSCHEDULED",
    "3DS2_enrolled":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 16:33:38+0000",
  "ndc":"C3C9A3741C3EF2121921A760AE3257DF.uat01-vm-tx03",
  "standingInstruction":{
    "source":"CIT",
    "type":"UNSCHEDULED",
    "mode":"INITIAL",
    "initialTransactionId":"016153570198200"
  },
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a09d1fa573019d20b1b9535ed7",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TK",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      },
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a19d1f98d2019d20b1bc440357",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TF",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}

4. Send payment using the merchant token

To send a payment using the network token, perform a server-to-server POST request with the merchant token retrieved in the previous step. Or use one-click checkout to authorise the payment with a selected stored merchant token.

Payment response

The response includes a token transaction history, indicating an attempt to fetch the network token from the card network. If no active network token exists for payments, the payment authorisation proceeds using the real card data.

When fetching the network token, the response also provides the original PAN BIN. The card.bin parameter in the payment response contains this information. The network token BIN differs from the original PAN BIN. This distinction is crucial for managing post-authorisation issuer BINs accurately, ensuring access to the necessary details for handling the transaction.

Sample request:

https://sandbox-card.peachpayments.com/v1/registrations/8ac7a4a09d1fa573019d20b1b9235eca/payments

curl https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments \
 -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
 -d "paymentBrand=VISA" \
 -d "paymentType=DB" \
 -d "amount=17.99" \
 -d "currency=EUR" \
 -d "standingInstruction.type=UNSCHEDULED" \
 -d "standingInstruction.mode=REPEATED" \
 -d "standingInstruction.source=MIT" \
 -d "testMode=EXTERNAL" \
 -d "customer.givenName=Smith" \
 -d "customer.ip=192.168.0.0" \
 -d "customer.surname=John" \
 -d "customer.language=DE" \
 -d "[email protected]" \
 -d "billing.city=MyCity" \
 -d "billing.country=DE" \
 -d "billing.postcode=712121" \
 -d "billing.state=DE" \
 -d "billing.street1=MyStreet" \
 -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&paymentBrand=VISA" +
        "&paymentType=DB" +
        "&amount=17.99" +
        "&currency=EUR" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&standingInstruction.mode=REPEATED" +
        "&standingInstruction.source=MIT" +
        "&testMode=EXTERNAL" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet";
        
    string url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "POST";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    request.ContentType = "application/x-www-form-urlencoded";
    
    Stream postData = request.GetRequestStream();
    postData.Write(buffer, 0, buffer.Length);
    postData.Close();
    
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var serializer = new JavaScriptSerializer();
        responseData = serializer.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    
    return responseData;
}

responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
    "&paymentBrand=VISA" +
    "&paymentType=DB" +
    "&amount=17.99" +
    "&currency=EUR" +
    "&standingInstruction.type=UNSCHEDULED" +
    "&standingInstruction.mode=REPEATED" +
    "&standingInstruction.source=MIT" +
    "&testMode=EXTERNAL" +
    "&customer.givenName=Smith" +
    "&customer.ip=192.168.0.0" +
    "&customer.surname=John" +
    "&customer.language=DE" +
    "&[email protected]" +
    "&billing.city=MyCity" +
    "&billing.country=DE" +
    "&billing.postcode=712121" +
    "&billing.state=DE" +
    "&billing.street1=MyStreet"
    
  def url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments".toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  connection.doOutput = true
  connection.outputStream << data
  
  def json = new JsonSlurper().parseText(connection.inputStream.text)
  json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    String data = ""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&paymentBrand=VISA"
        + "&paymentType=DB"
        + "&amount=17.99"
        + "&currency=EUR"
        + "&standingInstruction.type=UNSCHEDULED"
        + "&standingInstruction.mode=REPEATED"
        + "&standingInstruction.source=MIT"
        + "&testMode=EXTERNAL"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet";

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(data);
    wr.flush();
    wr.close();
    
    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) 
        is = conn.getErrorStream();
    else 
        is = conn.getInputStream();

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    const path = '/v1/registrations/{id}/payments';
    const data = querystring.stringify({
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'paymentBrand': 'VISA',
        'paymentType': 'DB',
        'amount': '17.99',
        'currency': 'EUR',
        'standingInstruction.type': 'UNSCHEDULED',
        'standingInstruction.mode': 'REPEATED',
        'standingInstruction.source': 'MIT',
        'testMode': 'EXTERNAL',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    });

    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length,
            'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };

    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });

        postRequest.on('error', reject);
        postRequest.write(data);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments";
    $data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" .
            "&paymentBrand=VISA" .
            "&paymentType=DB" .
            "&amount=17.99" .
            "&currency=EUR" .
            "&standingInstruction.type=UNSCHEDULED" .
            "&standingInstruction.mode=REPEATED" .
            "&standingInstruction.source=MIT" .
            "&testMode=EXTERNAL" .
            "&customer.givenName=Smith" .
            "&customer.ip=192.168.0.0" .
            "&customer.surname=John" .
            "&customer.language=DE" .
            "&[email protected]" .
            "&billing.city=MyCity" .
            "&billing.country=DE" .
            "&billing.postcode=712121" .
            "&billing.state=DE" .
            "&billing.street1=MyStreet";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set this to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseData = curl_exec($ch);

    if (curl_errno($ch)) {
        return curl_error($ch);
    }

    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:  # Python 2 compatibility
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
    data = {
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'paymentBrand': 'VISA',
        'paymentType': 'DB',
        'amount': '17.99',
        'currency': 'EUR',
        'standingInstruction.type': 'UNSCHEDULED',
        'standingInstruction.mode': 'REPEATED',
        'standingInstruction.source': 'MIT',
        'testMode': 'EXTERNAL',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    }

    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'
        response = opener.open(request)
        return json.loads(response.read().decode('utf-8'))
    except HTTPError as e:
        return {"error": e.code, "message": e.read().decode('utf-8')}
    except URLError as e:
        return {"error": "URL Error", "message": str(e.reason)}

responseData = request()
print(json.dumps(responseData, indent=4))
require 'net/https'
require 'uri'
require 'json'

def request
  uri = URI('https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  req = Net::HTTP::Post.new(uri.path)
  req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
  req.set_form_data({
    'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
    'paymentBrand' => 'VISA',
    'paymentType' => 'DB',
    'amount' => '17.99',
    'currency' => 'EUR',
    'standingInstruction.type' => 'UNSCHEDULED',
    'standingInstruction.mode' => 'REPEATED',
    'standingInstruction.source' => 'MIT',
    'testMode' => 'EXTERNAL',
    'customer.givenName' => 'Smith',
    'customer.ip' => '192.168.0.0',
    'customer.surname' => 'John',
    'customer.language' => 'DE',
    'customer.email' => '[email protected]',
    'billing.city' => 'MyCity',
    'billing.country' => 'DE',
    'billing.postcode' => '712121',
    'billing.state' => 'DE',
    'billing.street1' => 'MyStreet'
  })

  begin
    res = http.request(req)
    JSON.parse(res.body)
  rescue JSON::ParserError => e
    { 'error' => 'Invalid JSON response', 'message' => e.message }
  rescue => e
    { 'error' => 'Request failed', 'message' => e.message }
  end
end

puts JSON.pretty_generate(request)
import java.net.URL
import javax.net.ssl.HttpsURLConnection
import org.apache.commons.io.IOUtils

def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
  val data = Seq(
    "entityId=8ac7a4c98ab5c40a018ab810cbc803fc",
    "paymentBrand=VISA",
    "paymentType=DB",
    "amount=17.99",
    "currency=EUR",
    "standingInstruction.type=UNSCHEDULED",
    "standingInstruction.mode=REPEATED",
    "standingInstruction.source=MIT",
    "testMode=EXTERNAL",
    "customer.givenName=Smith",
    "customer.ip=192.168.0.0",
    "customer.surname=John",
    "customer.language=DE",
    "[email protected]",
    "billing.city=MyCity",
    "billing.country=DE",
    "billing.postcode=712121",
    "billing.state=DE",
    "billing.street1=MyStreet"
  ).mkString("&")

  val connection = new URL(url).openConnection().asInstanceOf[HttpsURLConnection]
  connection.setRequestMethod("POST")
  connection.setDoInput(true)
  connection.setDoOutput(true)
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")

  val outputStream = connection.getOutputStream
  try {
    IOUtils.write(data, outputStream, "UTF-8")
  } finally {
    outputStream.close()
  }

  val responseStream = if (connection.getResponseCode >= 400) connection.getErrorStream else connection.getInputStream
  try {
    IOUtils.toString(responseStream, "UTF-8")
  } finally {
    responseStream.close()
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
    Dim data As String = String.Join("&", {
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc",
        "paymentBrand=VISA",
        "paymentType=DB",
        "amount=17.99",
        "currency=EUR",
        "standingInstruction.type=UNSCHEDULED",
        "standingInstruction.mode=REPEATED",
        "standingInstruction.source=MIT",
        "testMode=EXTERNAL",
        "customer.givenName=Smith",
        "customer.ip=192.168.0.0",
        "customer.surname=John",
        "customer.language=DE",
        "[email protected]",
        "billing.city=MyCity",
        "billing.country=DE",
        "billing.postcode=712121",
        "billing.state=DE",
        "billing.street1=MyStreet"
    })

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "POST"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"

    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
    req.ContentLength = byteArray.Length
    Using dataStream As Stream = req.GetRequestStream()
        dataStream.Write(byteArray, 0, byteArray.Length)
    End Using

    Dim response As String
    Using res As WebResponse = req.GetResponse()
        Using resStream As Stream = res.GetResponseStream()
            Using reader As New StreamReader(resStream)
                response = reader.ReadToEnd()
            End Using
        End Using
    End Using

    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Return jss.Deserialize(Of Dictionary(Of String, Object))(response)
End Function

Dim responseData As String = Request()("result")("description").ToString()
Console.WriteLine(responseData)
{
  "id":"8ac7a4a19d1f98d2019d20b600a50b6d",
  "registrationId":"8ac7a4a09d1fa573019d20b1b9235eca",
  "paymentType":"DB",
  "paymentBrand":"VISA",
  "amount":"17.99",
  "currency":"EUR",
  "descriptor":"7183.8283.3572 NetworkToken3DChannel ",
  "result":{
    "avsResponse":"F",
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "resultDetails":{
    "Status":"AUTHORIZED",
    "ResponseCode":"00",
    "ConnectorTxID1":"7743702929566120904805",
    "AcquirerReconciliationId":"7743702929566120904805",
    "ConnectorTxID3":"7743702929566120904805",
    "ConnectorTxID2":"8ac7a4a19d1f98d2019d20b600a50b6d",
    "retrievalReferenceNumber":"608316215501",
    "CardholderInitiatedTransactionID":"016153570198200",
    "ApprovalCode":"831000",
    "TransactionId":"016153570198200",
    "ExtendedDescription":"Successful approval.",
    "avs.codeRaw":"Y",
    "authorizedAmount":"17.99",
    "avs.code":"Y",
    "AcquirerResponse":"AUTHORIZED",
    "reconciliationId":"8ac7a4a19d1f98d2019d20b600a50b6d",
    "NetworkTransactionId":"016153570198200"
  },
  "card":{
    "bin":"420000",
    "last4Digits":"0091",
    "holder":"John Doe",
    "expiryMonth":"12",
    "expiryYear":"2029"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "customParameters":{
    "PAYMENT_INHOUSE_FACADE":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 16:38:13+0000",
  "ndc":"8ac7a4c98ab5c40a018ab810cbc803fc_17fea8383a4f42bbbb1bb24544a52146",
  "standingInstruction":{
    "source":"MIT",
    "type":"UNSCHEDULED",
    "mode":"REPEATED",
    "initialTransactionId":"016153570198200"
  },
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a19d1f98d2019d20b600b30b74",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TF",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}

Standalone tokenisation

The merchant collects card data from the customer through a widget and initiates tokenisation. This process does not involve a payment request or flow. The system provisions a merchant token synchronously and returns it to the merchant. The merchant uses this token for subsequent payments.

In the background, the card network provisions a network token. The issuer approves the token to activate it for payments.

1. Prepare the Checkout

PerforSend a server-to-server POST request to prepare the checkout with the required customer data. Include createRegistration=true and exclude paymentType. A successful request returns an id, which you need in the next step to create the registration form.

Sample request:

curl https://sandbox-card.peachpayments.com/v1/checkouts \
  -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
  -d "customParameters[3DS2_enrolled]=true" \
  -d "customParameters[3DS2_flow]=challenge" \
  -d "testMode=EXTERNAL" \
  -d "**createRegistration=true**" \
  -d "customer.givenName=Smith" \
  -d "customer.ip=192.168.0.0" \
  -d "customer.surname=John" \
  -d "customer.language=DE" \
  -d "[email protected]" \
  -d "billing.city=MyCity" \
  -d "billing.country=DE" \
  -d "billing.postcode=712121" \
  -d "billing.state=DE" \
  -d "billing.street1=MyStreet" \
  -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&createRegistration=true**" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet";

    string url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    byte[] buffer = Encoding.ASCII.GetBytes(data);

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "POST";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    request.ContentType = "application/x-www-form-urlencoded";

    Stream postData = request.GetRequestStream();
    postData.Write(buffer, 0, buffer.Length);
    postData.Close();

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var serializer = new JavaScriptSerializer();
        responseData = serializer.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }

    return responseData;
}

var responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
    def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&createRegistration=true**" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet"

    def url = "https://sandbox-card.peachpayments.com/v1/checkouts".toURL()
    def connection = url.openConnection()
    connection.setRequestMethod("POST")
    connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    connection.doOutput = true
    connection.outputStream << data

    def json = new JsonSlurper().parseText(connection.inputStream.text)
    json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    String data = ""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&customParameters[3DS2_enrolled]=true"
        + "&customParameters[3DS2_flow]=challenge"
        + "&testMode=EXTERNAL"
        + "&createRegistration=true**"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet";

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(data);
    wr.flush();
    wr.close();

    int responseCode = conn.getResponseCode();
    InputStream is = (responseCode >= 400) ? conn.getErrorStream() : conn.getInputStream();

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
  const path = '/v1/checkouts';
  const data = querystring.stringify({
    entityId: '8ac7a4c98ab5c40a018ab810cbc803fc',
    'customParameters[3DS2_enrolled]': 'true',
    'customParameters[3DS2_flow]': 'challenge',
    testMode: 'EXTERNAL',
    '**createRegistration**': 'true',
    'customer.givenName': 'Smith',
    'customer.ip': '192.168.0.0',
    'customer.surname': 'John',
    'customer.language': 'DE',
    'customer.email': '[email protected]',
    'billing.city': 'MyCity',
    'billing.country': 'DE',
    'billing.postcode': '712121',
    'billing.state': 'DE',
    'billing.street1': 'MyStreet'
  });

  const options = {
    port: 443,
    host: 'sandbox-card.peachpayments.com',
    path: path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': data.length,
      'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    }
  };

  return new Promise((resolve, reject) => {
    const postRequest = https.request(options, function(res) {
      const buf = [];
      res.on('data', chunk => {
        buf.push(Buffer.from(chunk));
      });
      res.on('end', () => {
        const jsonString = Buffer.concat(buf).toString('utf8');
        try {
          resolve(JSON.parse(jsonString));
        } catch (error) {
          reject(error);
        }
      });
    });

    postRequest.on('error', reject);
    postRequest.write(data);
    postRequest.end();
  });
};

request()
  .then(console.log)
  .catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    $data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" .
            "&customParameters[3DS2_enrolled]=true" .
            "&customParameters[3DS2_flow]=challenge" .
            "&testMode=EXTERNAL" .
            "&createRegistration=true**" .
            "&customer.givenName=Smith" .
            "&customer.ip=192.168.0.0" .
            "&customer.surname=John" .
            "&customer.language=DE" .
            "&[email protected]" .
            "&billing.city=MyCity" .
            "&billing.country=DE" .
            "&billing.postcode=712121" .
            "&billing.state=DE" .
            "&billing.street1=MyStreet";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseData = curl_exec($ch);

    if (curl_errno($ch)) {
        return curl_error($ch);
    }

    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts"
    data = {
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]': 'true',
        'customParameters[3DS2_flow]': 'challenge',
        'testMode': 'EXTERNAL',
        **'createRegistration': 'true',**
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    }
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return str(e.reason)

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
  uri = URI('https://sandbox-card.peachpayments.com/v1/checkouts')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Post.new(uri.path)
  req.set_form_data({
    'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
    'customParameters[3DS2_enrolled]' => 'true',
    'customParameters[3DS2_flow]' => 'challenge',
    'testMode' => 'EXTERNAL',
    **'createRegistration' => 'true',**
    'customer.givenName' => 'Smith',
    'customer.ip' => '192.168.0.0',
    'customer.surname' => 'John',
    'customer.language' => 'DE',
    'customer.email' => '[email protected]',
    'billing.city' => 'MyCity',
    'billing.country' => 'DE',
    'billing.postcode' => '712121',
    'billing.state' => 'DE',
    'billing.street1' => 'MyStreet'
  })
  res = http.request(req)
  return JSON.parse(res.body)
end

puts request()
def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts"
  val data = ("" +
    "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
    "&customParameters[3DS2_enrolled]=true" +
    "&customParameters[3DS2_flow]=challenge" +
    "&testMode=EXTERNAL" +
    **"&createRegistration=true"** +
    "&customer.givenName=Smith" +
    "&customer.ip=192.168.0.0" +
    "&customer.surname=John" +
    "&customer.language=DE" +
    "&[email protected]" +
    "&billing.city=MyCity" +
    "&billing.country=DE" +
    "&billing.postcode=712121" +
    "&billing.state=DE" +
    "&billing.street1=MyStreet"
  )
  val conn = new URL(url).openConnection()

  conn match {
    case secureConn: HttpsURLConnection => secureConn.setRequestMethod("POST")
    case _ => throw new ClassCastException
  }
  
  conn.setDoInput(true)
  conn.setDoOutput(true)
  IOUtils.write(data, conn.getOutputStream())
  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()
  
  if (conn.getResponseCode >= 400) {
    IOUtils.toString(conn.getErrorStream())
  } else {
    IOUtils.toString(conn.getInputStream())
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts"
    Dim data As String = "" +
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        **"&createRegistration=true"** +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "POST"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
    req.ContentLength = byteArray.Length
    Dim dataStream As Stream = req.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()

    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    reader.Close()
    resStream.Close()
    res.Close()

    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)

    Return dict
End Function

Dim responseData As String = Request()("result")("description")
Console.WriteLine(responseData)
{
  "result":{
    "code":"000.200.100",
    "description":"successfully created checkout"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 16:39:14+0000",
  "ndc":"27619404E5AB3973D37667B3A3D9ED77.uat01-vm-tx02",
  "id":"27619404E5AB3973D37667B3A3D9ED77.uat01-vm-tx02",
  "integrity":"sha384-xPd/lgsLgQg0IE/x2HgPRpX5fNH7gLUA5sw2eMNtyhvAcayO3PoYG/yQx1tEHoOV"
}

2. Create the tokenisation form

Create the tokenisation form by adding HTML and JavaScript to your page.

  • With the checkoutId received from first step:
    <script  
      src="https://sandbox-card.peachpayments.com/v1/paymentWidgets.js?checkoutId={checkout_id}"  
      integrity="{integrity}"  
      crossorigin="anonymous">  
    </script>
  • With the shopperResultUrl as the page on your site where the customer returns after completing the tokenisation process.
    `<form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>`

Sample form:

<form action="https://developer.peachpayments.com/docs/oppwa-integrations-copyandpay-network-tokens" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>
body {background-color:#f6f6f5;}
var wpwlOptions = {style:"card", registrations: {requireCvv: true}, paymentTarget: "_top"}
Card form.

Card form.

3. Get the tokenisation status

After the tokenisation request processes, the customer redirects to the shopperResultUrl with a GET parameter resourcePath=/v1/checkouts/{checkoutId}/registration.

Tokenisation response

The response includes a token transaction history, showing that the network token provisioning process starts with the card network. This process involves the issuer and may take some time for approval. In the test environment, a simulated 2-second delay mirrors production conditions. The network token retrieves during the next payment attempt.

Sample request:

https://sandbox-card.peachpayments.com/v1/checkouts/27619404E5AB3973D37667B3A3D9ED77.uat01-vm-tx02/registration

curl -G https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration \
-d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
-H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc";
    string url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration?" + data;
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "GET";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var s = new JavaScriptSerializer();
        responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    return responseData;
}

responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
    def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
    def url = ("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration?" + data).toURL()
    def connection = url.openConnection()
    connection.setRequestMethod("GET")
    connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    
    def json = new JsonSlurper().parseText(connection.inputStream.text)
    return json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration?entityId=8ac7a4c98ab5c40a018ab810cbc803fc");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    
    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) {
        is = conn.getErrorStream();
    } else {
        is = conn.getInputStream();
    }

    return IOUtils.toString(is, "UTF-8");
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    var path = '/v1/checkouts/{id}/registration';
    path += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc';
    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'GET',
        headers: {
            'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };
    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function (res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        postRequest.on('error', reject);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration";
    $url .= "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set this to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    
    if (curl_errno($ch)) {
        return curl_error($ch);
    }
    
    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration"
    url += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc'
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=b'')
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'GET'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request
  path = "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  uri = URI.parse('https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration' + path)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
  res = http.request(req)
  JSON.parse(res.body)
end

puts request
def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration"
  val fullUrl = url + "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  val conn = new URL(fullUrl).openConnection()

  conn match {
    case secureConn: HttpsURLConnection => secureConn.setRequestMethod("GET")
    case _ => throw new ClassCastException
  }

  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()

  if (conn.getResponseCode >= 400) {
    IOUtils.toString(conn.getErrorStream)
  } else {
    IOUtils.toString(conn.getInputStream)
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/registration" & 
        "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "GET"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    
    reader.Close()
    resStream.Close()
    res.Close()

    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)

    Return dict
End Function

Dim responseData As String = Request()("result")("description")
{
  "id":"8ac7a49f9d1f9917019d20bf469a1f54",
  "paymentBrand":"VISA",
  "result":{
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "card":{
    "bin":"420000",
    "binCountry":"US",
    "last4Digits":"0091",
    "holder":"John Doe",
    "expiryMonth":"12",
    "expiryYear":"2029"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "customParameters":{
    "SHOPPER_EndToEndIdentity":"8c4b6018a755d997699f737df7c00f98f1491b8d0fe31f13a855416236228ec2",
    "3DS2_flow":"challenge",
    "3DS2_enrolled":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 16:48:19+0000",
  "ndc":"27619404E5AB3973D37667B3A3D9ED77.uat01-vm-tx02",
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a49f9d1f9917019d20bf46bf1f61",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TK",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}

4. Send payment using the merchant token

To send a payment with the network token, perform a server-to-server POST request using the merchant token retrieved in the previous step. You can also use one-click checkout to authorise the payment with a selected stored merchant token.

Payment response

The response includes a token transaction history, confirming an attempt to fetch the network token from the card network. If no network token is active for payments, the payment authorisation uses the real card data.

When your server fetches the network token from the card network, the response includes the original PAN BIN. The payment response returns this information under the card.bin parameter. The network token BIN differs from the original PAN BIN. This distinction is essential for post-authorisation issuer BIN management, ensuring accurate transaction handling.

Sample request:

https://sandbox-card.peachpayments.com/v1/registrations/8ac7a49f9d1f9917019d20bf469a1f54/payments

curl https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments \
  -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
  -d "paymentBrand=VISA" \
  -d "paymentType=DB" \
  -d "amount=17.99" \
  -d "currency=EUR" \
  -d "standingInstruction.type=UNSCHEDULED" \
  -d "standingInstruction.mode=INITIAL" \
  -d "standingInstruction.source=CIT" \
  -d "testMode=EXTERNAL" \
  -d "customer.givenName=Smith" \
  -d "customer.ip=192.168.0.0" \
  -d "customer.surname=John" \
  -d "customer.language=DE" \
  -d "[email protected]" \
  -d "billing.city=MyCity" \
  -d "billing.country=DE" \
  -d "billing.postcode=712121" \
  -d "billing.state=DE" \
  -d "billing.street1=MyStreet" \
  -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;

public class PaymentRequest
{
    public Dictionary<string, dynamic> Request()
    {
        Dictionary<string, dynamic> responseData;
        string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
            "&paymentBrand=VISA" +
            "&paymentType=DB" +
            "&amount=17.99" +
            "&currency=EUR" +
            "&standingInstruction.type=UNSCHEDULED" +
            "&standingInstruction.mode=INITIAL" +
            "&standingInstruction.source=CIT" +
            "&testMode=EXTERNAL" +
            "&customer.givenName=Smith" +
            "&customer.ip=192.168.0.0" +
            "&customer.surname=John" +
            "&customer.language=DE" +
            "&[email protected]" +
            "&billing.city=MyCity" +
            "&billing.country=DE" +
            "&billing.postcode=712121" +
            "&billing.state=DE" +
            "&billing.street1=MyStreet";

        string url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments";
        byte[] buffer = Encoding.ASCII.GetBytes(data);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = buffer.Length;

        using (Stream postData = request.GetRequestStream())
        {
            postData.Write(buffer, 0, buffer.Length);
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (Stream dataStream = response.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(dataStream))
                {
                    var jsonSerializer = new JavaScriptSerializer();
                    responseData = jsonSerializer.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
                }
            }
        }

        return responseData;
    }

    public static void Main()
    {
        PaymentRequest paymentRequest = new PaymentRequest();
        var responseData = paymentRequest.Request();
        Console.WriteLine("Response Description: " + responseData["result"]["description"]);
    }
}
import groovy.json.JsonSlurper

public static Map request() {
    def data = """entityId=8ac7a4c98ab5c40a018ab810cbc803fc&
                  paymentBrand=VISA&
                  paymentType=DB&
                  amount=17.99&
                  currency=EUR&
                  standingInstruction.type=UNSCHEDULED&
                  standingInstruction.mode=INITIAL&
                  standingInstruction.source=CIT&
                  testMode=EXTERNAL&
                  customer.givenName=Smith&
                  customer.ip=192.168.0.0&
                  customer.surname=John&
                  customer.language=DE&
                  [email protected]&
                  billing.city=MyCity&
                  billing.country=DE&
                  billing.postcode=712121&
                  billing.state=DE&
                  billing.street1=MyStreet"""

    def url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments".toURL()
    def connection = url.openConnection()
    connection.requestMethod = "POST"
    connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    connection.doOutput = true

    connection.outputStream.withWriter("UTF-8") { writer ->
        writer << data
    }

    try {
        def response = connection.inputStream.text
        def json = new JsonSlurper().parseText(response)
        return json
    } catch (Exception e) {
        def errorResponse = connection.errorStream?.text
        println "Error: ${e.message}"
        if (errorResponse) {
            println "Error Response: ${errorResponse}"
        }
        return [error: e.message]
    }
}

println request()
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.URL;
import org.apache.commons.io.IOUtils;

public class PaymentRequest {
    
    public static String request() throws IOException {
        URL url = new URL("https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoInput(true);
        conn.setDoOutput(true);

        String data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
                "&paymentBrand=VISA" +
                "&paymentType=DB" +
                "&amount=17.99" +
                "&currency=EUR" +
                "&standingInstruction.type=UNSCHEDULED" +
                "&standingInstruction.mode=INITIAL" +
                "&standingInstruction.source=CIT" +
                "&testMode=EXTERNAL" +
                "&customer.givenName=Smith" +
                "&customer.ip=192.168.0.0" +
                "&customer.surname=John" +
                "&customer.language=DE" +
                "&[email protected]" +
                "&billing.city=MyCity" +
                "&billing.country=DE" +
                "&billing.postcode=712121" +
                "&billing.state=DE" +
                "&billing.street1=MyStreet";

        try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
            wr.writeBytes(data);
            wr.flush();
        }

        int responseCode = conn.getResponseCode();
        try (InputStream is = (responseCode >= 400) ? conn.getErrorStream() : conn.getInputStream()) {
            return IOUtils.toString(is, "UTF-8");
        }
    }

    public static void main(String[] args) {
        try {
            String response = request();
            System.out.println("Response: " + response);
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
  const path = '/v1/registrations/{id}/payments';
  const data = querystring.stringify({
    entityId: '8ac7a4c98ab5c40a018ab810cbc803fc',
    paymentBrand: 'VISA',
    paymentType: 'DB',
    amount: '17.99',
    currency: 'EUR',
    'standingInstruction.type': 'UNSCHEDULED',
    'standingInstruction.mode': 'INITIAL',
    'standingInstruction.source': 'CIT',
    testMode: 'EXTERNAL',
    'customer.givenName': 'Smith',
    'customer.ip': '192.168.0.0',
    'customer.surname': 'John',
    'customer.language': 'DE',
    'customer.email': '[email protected]',
    'billing.city': 'MyCity',
    'billing.country': 'DE',
    'billing.postcode': '712121',
    'billing.state': 'DE',
    'billing.street1': 'MyStreet',
  });

  const options = {
    hostname: 'sandbox-card.peachpayments.com',
    port: 443,
    path: path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': data.length,
      Authorization: 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=',
    },
  };

  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      let buf = '';
      res.on('data', (chunk) => {
        buf += chunk;
      });
      res.on('end', () => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          try {
            resolve(JSON.parse(buf));
          } catch (error) {
            reject(`JSON parse error: ${error.message}`);
          }
        } else {
          reject(`Request failed with status ${res.statusCode}: ${buf}`);
        }
      });
    });

    req.on('error', (error) => reject(`Request error: ${error.message}`));
    req.write(data);
    req.end();
  });
};

(async () => {
  try {
    const response = await request();
    console.log('Response:', response);
  } catch (error) {
    console.error('Error:', error);
  }
})();
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments";
    $data = http_build_query([
        'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
        'paymentBrand' => 'VISA',
        'paymentType' => 'DB',
        'amount' => '17.99',
        'currency' => 'EUR',
        'standingInstruction.type' => 'UNSCHEDULED',
        'standingInstruction.mode' => 'INITIAL',
        'standingInstruction.source' => 'CIT',
        'testMode' => 'EXTERNAL',
        'customer.givenName' => 'Smith',
        'customer.ip' => '192.168.0.0',
        'customer.surname' => 'John',
        'customer.language' => 'DE',
        'customer.email' => '[email protected]',
        'billing.city' => 'MyCity',
        'billing.country' => 'DE',
        'billing.postcode' => '712121',
        'billing.state' => 'DE',
        'billing.street1' => 'MyStreet',
    ]);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ]);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseData = curl_exec($ch);

    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        return "Curl error: $error";
    }

    $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpStatus >= 200 && $httpStatus < 300) {
        return json_decode($responseData, true); // Parse as an associative array
    } else {
        return "Request failed with status $httpStatus: $responseData";
    }
}

$responseData = request();
print_r($responseData);
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
    data = {
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'paymentBrand': 'VISA',
        'paymentType': 'DB',
        'amount': '17.99',
        'currency': 'EUR',
        'standingInstruction.type': 'UNSCHEDULED',
        'standingInstruction.mode': 'INITIAL',
        'standingInstruction.source': 'CIT',
        'testMode': 'EXTERNAL',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    }
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'

        with opener.open(request) as response:
            return json.loads(response.read().decode('utf-8'))

    except HTTPError as e:
        return {'error': 'HTTPError', 'status_code': e.code, 'message': e.read().decode('utf-8')}
    except URLError as e:
        return {'error': 'URLError', 'reason': str(e)}

responseData = request()
print(json.dumps(responseData, indent=4))
require 'net/https'
require 'uri'
require 'json'

def request
  uri = URI('https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  req = Net::HTTP::Post.new(uri.path)
  req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
  
  req.set_form_data(
    'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
    'paymentBrand' => 'VISA',
    'paymentType' => 'DB',
    'amount' => '17.99',
    'currency' => 'EUR',
    'standingInstruction.type' => 'UNSCHEDULED',
    'standingInstruction.mode' => 'INITIAL',
    'standingInstruction.source' => 'CIT',
    'testMode' => 'EXTERNAL',
    'customer.givenName' => 'Smith',
    'customer.ip' => '192.168.0.0',
    'customer.surname' => 'John',
    'customer.language' => 'DE',
    'customer.email' => '[email protected]',
    'billing.city' => 'MyCity',
    'billing.country' => 'DE',
    'billing.postcode' => '712121',
    'billing.state' => 'DE',
    'billing.street1' => 'MyStreet'
  )

  begin
    res = http.request(req)
    JSON.parse(res.body)
  rescue StandardError => e
    { 'error' => e.message }
  end
end

puts JSON.pretty_generate(request)
import java.net.URL
import javax.net.ssl.HttpsURLConnection
import org.apache.commons.io.IOUtils

def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
  val data = (
    "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
    "&paymentBrand=VISA" +
    "&paymentType=DB" +
    "&amount=17.99" +
    "&currency=EUR" +
    "&standingInstruction.type=UNSCHEDULED" +
    "&standingInstruction.mode=INITIAL" +
    "&standingInstruction.source=CIT" +
    "&testMode=EXTERNAL" +
    "&customer.givenName=Smith" +
    "&customer.ip=192.168.0.0" +
    "&customer.surname=John" +
    "&customer.language=DE" +
    "&[email protected]" +
    "&billing.city=MyCity" +
    "&billing.country=DE" +
    "&billing.postcode=712121" +
    "&billing.state=DE" +
    "&billing.street1=MyStreet"
  )

  val connection = new URL(url).openConnection().asInstanceOf[HttpsURLConnection]
  connection.setRequestMethod("POST")
  connection.setDoInput(true)
  connection.setDoOutput(true)
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")

  IOUtils.write(data, connection.getOutputStream, "UTF-8")

  val responseCode = connection.getResponseCode
  val responseStream = if (responseCode >= 400) connection.getErrorStream else connection.getInputStream

  IOUtils.toString(responseStream, "UTF-8")
}
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Web.Script.Serialization

Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/registrations/{id}/payments"
    Dim data As String = String.Join("&", {
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc",
        "paymentBrand=VISA",
        "paymentType=DB",
        "amount=17.99",
        "currency=EUR",
        "standingInstruction.type=UNSCHEDULED",
        "standingInstruction.mode=INITIAL",
        "standingInstruction.source=CIT",
        "testMode=EXTERNAL",
        "customer.givenName=Smith",
        "customer.ip=192.168.0.0",
        "customer.surname=John",
        "customer.language=DE",
        "[email protected]",
        "billing.city=MyCity",
        "billing.country=DE",
        "billing.postcode=712121",
        "billing.state=DE",
        "billing.street1=MyStreet"
    })

    Try
        Dim req As WebRequest = WebRequest.Create(url)
        req.Method = "POST"
        req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
        req.ContentType = "application/x-www-form-urlencoded"

        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
        req.ContentLength = byteArray.Length

        Using dataStream As Stream = req.GetRequestStream()
            dataStream.Write(byteArray, 0, byteArray.Length)
        End Using

        Using res As WebResponse = req.GetResponse()
            Using resStream As Stream = res.GetResponseStream()
                Using reader As New StreamReader(resStream)
                    Dim response As String = reader.ReadToEnd()
                    Dim jss As New JavaScriptSerializer()
                    Return jss.Deserialize(Of Dictionary(Of String, Object))(response)
                End Using
            End Using
        End Using
    Catch ex As WebException
        Using errorStream As Stream = ex.Response.GetResponseStream()
            Using reader As New StreamReader(errorStream)
                Dim errorResponse As String = reader.ReadToEnd()
                Throw New ApplicationException("Request failed: " & errorResponse)
            End Using
        End Using
    End Try
End Function

' Example usage:
Dim responseData As String = Request()("result")("description").ToString()
Console.WriteLine(responseData)
{
  "id":"8ac7a4a29d1fa595019d20c07bfb7ba0",
  "registrationId":"8ac7a49f9d1f9917019d20bf469a1f54",
  "paymentType":"DB",
  "paymentBrand":"VISA",
  "amount":"17.99",
  "currency":"EUR",
  "descriptor":"7218.7234.7044 NetworkToken3DChannel ",
  "result":{
    "avsResponse":"F",
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "resultDetails":{
    "Status":"AUTHORIZED",
    "ResponseCode":"00",
    "ConnectorTxID1":"7743709800786664804805",
    "AcquirerReconciliationId":"7743709800786664804805",
    "ConnectorTxID3":"7743709800786664804805",
    "ConnectorTxID2":"8ac7a4a29d1fa595019d20c07bfb7ba0",
    "retrievalReferenceNumber":"608316215932",
    "CardholderInitiatedTransactionID":"016153570198200",
    "ApprovalCode":"831000",
    "TransactionId":"016153570198200",
    "ExtendedDescription":"Successful approval.",
    "avs.codeRaw":"Y",
    "authorizedAmount":"17.99",
    "avs.code":"Y",
    "AcquirerResponse":"AUTHORIZED",
    "reconciliationId":"8ac7a4a29d1fa595019d20c07bfb7ba0",
    "NetworkTransactionId":"016153570198200"
  },
  "card":{
    "bin":"420000",
    "last4Digits":"0091",
    "holder":"John Doe",
    "expiryMonth":"12",
    "expiryYear":"2029"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "customParameters":{
    "PAYMENT_INHOUSE_FACADE":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-24 16:49:40+0000",
  "ndc":"8ac7a4c98ab5c40a018ab810cbc803fc_09558b7730ae43299d2b674a4251c6f6",
  "standingInstruction":{
    "source":"CIT",
    "type":"UNSCHEDULED",
    "mode":"INITIAL",
    "initialTransactionId":"016153570198200"
  },
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a29d1fa595019d20c07c097ba7",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TF",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}

One-click checkout

Accelerate the checkout process by reusing entered card data. When a returning customer visits the merchant's website, their card is already tokenised. The network token remains active for payments. An unscheduled one-click purchase uses one of the saved merchant tokens. The cardholder (CIT) initiates the payment, authorising it with the active network token for a seamless and efficient transaction.

1. Prepare the checkout

To start network token provisioning, send a server-to-server POST request to prepare the checkout with the necessary payment data, including the merchant token IDs. Pass each stored card-on-file's merchant token ID in the registrations[n].id parameter, where n starts at 0 and increments for each customer's registration ID. A successful request returns an id, which you need for the next step to generate the one-click payment form. Sample request:

curl https://sandbox-card.peachpayments.com/v1/checkouts \
  -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
  -d "customParameters[3DS2_enrolled]=true" \
  -d "customParameters[3DS2_flow]=challenge" \
  -d "testMode=EXTERNAL" \
  -d "**registrations[0].id=8ac7a49f94fc2bfa0194fdf0d72641ac**" \
  -d "**registrations[1].id=8ac7a4a294fc2ebf0194fdf0da923c61**" \
  -d "**registrations[2].id=8ac7a4a294fc2ebf0194fdf0dca83c7c**" \
  -d "amount=11.13" \
  -d "currency=EUR" \
  -d "paymentType=DB" \
  -d "standingInstruction.mode=REPEATED" \
  -d "standingInstruction.source=CIT" \
  -d "standingInstruction.type=UNSCHEDULED" \
  -d "customer.givenName=Smith" \
  -d "customer.ip=192.168.0.0" \
  -d "customer.surname=John" \
  -d "customer.language=DE" \
  -d "[email protected]" \
  -d "billing.city=MyCity" \
  -d "billing.country=DE" \
  -d "billing.postcode=712121" \
  -d "billing.state=DE" \
  -d "billing.street1=MyStreet" \
  -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;

public class PaymentRequest
{
    public Dictionary<string, dynamic> Request()
    {
        Dictionary<string, dynamic> responseData;
        
        string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
            "&customParameters[3DS2_enrolled]=true" +
            "&customParameters[3DS2_flow]=challenge" +
            "&testMode=EXTERNAL" +
            **"&registrations[0].id=8ac7a49f94fc2bfa0194fdf0d72641ac"** +
            **"&registrations[1].id=8ac7a4a294fc2ebf0194fdf0da923c61"** +
            **"&registrations[2].id=8ac7a4a294fc2ebf0194fdf0dca83c7c"** +
            "&amount=11.13" +
            "&currency=EUR" +
            "&paymentType=DB" +
            "&standingInstruction.mode=REPEATED" +
            "&standingInstruction.source=CIT" +
            "&standingInstruction.type=UNSCHEDULED" +
            "&customer.givenName=Smith" +
            "&customer.ip=192.168.0.0" +
            "&customer.surname=John" +
            "&customer.language=DE" +
            "&[email protected]" +
            "&billing.city=MyCity" +
            "&billing.country=DE" +
            "&billing.postcode=712121" +
            "&billing.state=DE" +
            "&billing.street1=MyStreet";

        string url = "https://sandbox-card.peachpayments.com/v1/checkouts";
        byte[] buffer = Encoding.ASCII.GetBytes(data);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
        request.ContentType = "application/x-www-form-urlencoded";

        using (Stream postData = request.GetRequestStream())
        {
            postData.Write(buffer, 0, buffer.Length);
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            Stream dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            var s = new JavaScriptSerializer();
            responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
            reader.Close();
        }

        return responseData;
    }
}
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
  "&customParameters[3DS2_enrolled]=true" +
  "&customParameters[3DS2_flow]=challenge" +
  "&testMode=EXTERNAL" +
  **"&registrations[0].id=8ac7a49f94fc2bfa0194fdf0d72641ac"** +
  **"&registrations[1].id=8ac7a4a294fc2ebf0194fdf0da923c61"** +
  **"&registrations[2].id=8ac7a4a294fc2ebf0194fdf0dca83c7c"** +
  "&amount=11.13" +
  "&currency=EUR" +
  "&paymentType=DB" +
  "&standingInstruction.mode=REPEATED" +
  "&standingInstruction.source=CIT" +
  "&standingInstruction.type=UNSCHEDULED" +
  "&customer.givenName=Smith" +
  "&customer.ip=192.168.0.0" +
  "&customer.surname=John" +
  "&customer.language=DE" +
  "&[email protected]" +
  "&billing.city=MyCity" +
  "&billing.country=DE" +
  "&billing.postcode=712121" +
  "&billing.state=DE" +
  "&billing.street1=MyStreet"

  def url = "https://sandbox-card.peachpayments.com/v1/checkouts".toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  connection.doOutput = true
  connection.outputStream << data

  def json = new JsonSlurper().parseText(connection.inputStream.text)
  json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    String data = ""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&customParameters[3DS2_enrolled]=true"
        + "&customParameters[3DS2_flow]=challenge"
        + "&testMode=EXTERNAL"
        + **"&registrations[0].id=8ac7a49f94fc2bfa0194fdf0d72641ac"**
        + **"&registrations[1].id=8ac7a4a294fc2ebf0194fdf0da923c61"**
        + **"&registrations[2].id=8ac7a4a294fc2ebf0194fdf0dca83c7c"**
        + "&amount=11.13"
        + "&currency=EUR"
        + "&paymentType=DB"
        + "&standingInstruction.mode=REPEATED"
        + "&standingInstruction.source=CIT"
        + "&standingInstruction.type=UNSCHEDULED"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet";

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(data);
    wr.flush();
    wr.close();

    int responseCode = conn.getResponseCode();
    InputStream is = (responseCode >= 400) ? conn.getErrorStream() : conn.getInputStream();
    
    return IOUtils.toString(is);
}
```node
const https = require('https');
const querystring = require('querystring');

const request = async () => {
  const path = '/v1/checkouts';
  const data = querystring.stringify({
    'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
    'customParameters[3DS2_enrolled]': 'true',
    'customParameters[3DS2_flow]': 'challenge',
    'testMode': 'EXTERNAL',
    **'registrations[0].id': '8ac7a49f94fc2bfa0194fdf0d72641ac',**
    **'registrations[1].id': '8ac7a4a294fc2ebf0194fdf0da923c61',**
    **'registrations[2].id': '8ac7a4a294fc2ebf0194fdf0dca83c7c',**
    'amount': '11.13',
    'currency': 'EUR',
    'paymentType': 'DB',
    'standingInstruction.mode': 'REPEATED',
    'standingInstruction.source': 'CIT',
    'standingInstruction.type': 'UNSCHEDULED',
    'customer.givenName': 'Smith',
    'customer.ip': '192.168.0.0',
    'customer.surname': 'John',
    'customer.language': 'DE',
    'customer.email': '[email protected]',
    'billing.city': 'MyCity',
    'billing.country': 'DE',
    'billing.postcode': '712121',
    'billing.state': 'DE',
    'billing.street1': 'MyStreet'
  });

  const options = {
    port: 443,
    host: 'sandbox-card.peachpayments.com',
    path: path,
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': data.length,
      'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    }
  };

  return new Promise((resolve, reject) => {
    const postRequest = https.request(options, function(res) {
      const buf = [];
      res.on('data', chunk => {
        buf.push(Buffer.from(chunk));
      });
      res.on('end', () => {
        const jsonString = Buffer.concat(buf).toString('utf8');
        try {
          resolve(JSON.parse(jsonString));
        } catch (error) {
          reject(error);
        }
      });
    });

    postRequest.on('error', reject);
    postRequest.write(data);
    postRequest.end();
  });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    $data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" .
             "&customParameters[3DS2_enrolled]=true" .
             "&customParameters[3DS2_flow]=challenge" .
             "&testMode=EXTERNAL" .
             **"&registrations[0].id=8ac7a49f94fc2bfa0194fdf0d72641ac" .**
             **"&registrations[1].id=8ac7a4a294fc2ebf0194fdf0da923c61" .**
             **"&registrations[2].id=8ac7a4a294fc2ebf0194fdf0dca83c7c" .**
             "&amount=11.13" .
             "&currency=EUR" .
             "&paymentType=DB" .
             "&standingInstruction.mode=REPEATED" .
             "&standingInstruction.source=CIT" .
             "&standingInstruction.type=UNSCHEDULED" .
             "&customer.givenName=Smith" .
             "&customer.ip=192.168.0.0" .
             "&customer.surname=John" .
             "&customer.language=DE" .
             "&[email protected]" .
             "&billing.city=MyCity" .
             "&billing.country=DE" .
             "&billing.postcode=712121" .
             "&billing.state=DE" .
             "&billing.street1=MyStreet";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization:Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // this should be set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    if (curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts"
    data = {
        'entityId': '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]': 'true',
        'customParameters[3DS2_flow]': 'challenge',
        'testMode': 'EXTERNAL',
        'registrations[0].id': '8ac7a49f94fc2bfa0194fdf0d72641ac',
        'registrations[1].id': '8ac7a4a294fc2ebf0194fdf0da923c61',
        'registrations[2].id': '8ac7a4a294fc2ebf0194fdf0dca83c7c',
        'amount': '11.13',
        'currency': 'EUR',
        'paymentType': 'DB',
        'standingInstruction.mode': 'REPEATED',
        'standingInstruction.source': 'CIT',
        'standingInstruction.type': 'UNSCHEDULED',
        'customer.givenName': 'Smith',
        'customer.ip': '192.168.0.0',
        'customer.surname': 'John',
        'customer.language': 'DE',
        'customer.email': '[email protected]',
        'billing.city': 'MyCity',
        'billing.country': 'DE',
        'billing.postcode': '712121',
        'billing.state': 'DE',
        'billing.street1': 'MyStreet'
    }

    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return str(e.reason)

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request
  uri = URI('https://sandbox-card.peachpayments.com/v1/checkouts')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Post.new(uri.path)
  
  req.set_form_data({
    'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
    'customParameters[3DS2_enrolled]' => 'true',
    'customParameters[3DS2_flow]' => 'challenge',
    'testMode' => 'EXTERNAL',
    'registrations[0].id' => '**8ac7a49f94fc2bfa0194fdf0d72641ac**',
    'registrations[1].id' => '**8ac7a4a294fc2ebf0194fdf0da923c61**',
    'registrations[2].id' => '**8ac7a4a294fc2ebf0194fdf0dca83c7c**',
    'amount' => '11.13',
    'currency' => 'EUR',
    'paymentType' => 'DB',
    'standingInstruction.mode' => 'REPEATED',
    'standingInstruction.source' => 'CIT',
    'standingInstruction.type' => 'UNSCHEDULED',
    'customer.givenName' => 'Smith',
    'customer.ip' => '192.168.0.0',
    'customer.surname' => 'John',
    'customer.language' => 'DE',
    'customer.email' => '[email protected]',
    'billing.city' => 'MyCity',
    'billing.country' => 'DE',
    'billing.postcode' => '712121',
    'billing.state' => 'DE',
    'billing.street1' => 'MyStreet'
  })

  res = http.request(req)
  JSON.parse(res.body)
end

puts request
def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts"
  val data = (
    "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
    "&customParameters[3DS2_enrolled]=true" +
    "&customParameters[3DS2_flow]=challenge" +
    "&testMode=EXTERNAL" +
    "&registrations[0].id=**8ac7a49f94fc2bfa0194fdf0d72641ac**" +
    "&registrations[1].id=**8ac7a4a294fc2ebf0194fdf0da923c61**" +
    "&registrations[2].id=**8ac7a4a294fc2ebf0194fdf0dca83c7c**" +
    "&amount=11.13" +
    "&currency=EUR" +
    "&paymentType=DB" +
    "&standingInstruction.mode=REPEATED" +
    "&standingInstruction.source=CIT" +
    "&standingInstruction.type=UNSCHEDULED" +
    "&customer.givenName=Smith" +
    "&customer.ip=192.168.0.0" +
    "&customer.surname=John" +
    "&customer.language=DE" +
    "&[email protected]" +
    "&billing.city=MyCity" +
    "&billing.country=DE" +
    "&billing.postcode=712121" +
    "&billing.state=DE" +
    "&billing.street1=MyStreet"
  )
  val conn = new URL(url).openConnection()

  conn match {
    case secureConn: HttpsURLConnection => secureConn.setRequestMethod("POST")
    case _ => throw new ClassCastException
  }
  
  conn.setDoInput(true)
  conn.setDoOutput(true)
  IOUtils.write(data, conn.getOutputStream())
  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()
  
  if (conn.getResponseCode >= 400) {
    IOUtils.toString(conn.getErrorStream())
  } else {
    IOUtils.toString(conn.getInputStream())
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts"
    Dim data As String = "" +
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&registrations[0].id=**8ac7a49f94fc2bfa0194fdf0d72641ac**" +
        "&registrations[1].id=**8ac7a4a294fc2ebf0194fdf0da923c61**" +
        "&registrations[2].id=**8ac7a4a294fc2ebf0194fdf0dca83c7c**" +
        "&amount=11.13" +
        "&currency=EUR" +
        "&paymentType=DB" +
        "&standingInstruction.mode=REPEATED" +
        "&standingInstruction.source=CIT" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "POST"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
    req.ContentLength = byteArray.Length
    Dim dataStream As Stream = req.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    reader.Close()
    resStream.Close()
    res.Close()

    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)
    Return dict
End Function

Dim responseData As String = Request()("result")("description")
{
  "result":{
    "code":"000.200.100",
    "description":"successfully created checkout"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-25 04:06:37+0000",
  "ndc":"843FF38610ACF8F39C00BC65A9CA35DD.uat01-vm-tx01",
  "id":"843FF38610ACF8F39C00BC65A9CA35DD.uat01-vm-tx01",
  "integrity":"sha384-tWas4KdOS6lW7MWWRIJ1eh2hmCT6pWdPHhbZpdZbOY8dKnKkSfdhMiqhuz2/ay6R"
}

2. Create the payment form

Create the payment form by adding the following lines of HTML/JavaScript to your page:

  • With the checkoutId received from first step:
    <script  
      src="https://sandbox-card.peachpayments.com/v1/paymentWidgets.js?checkoutId={checkout_id}"  
      integrity="{integrity}"  
      crossorigin="anonymous">  
    </script>
  • With the shopperResultUrl as the page on your site that the system redirects the customer to after completing the payment:
    <form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>

When COPYandPAY builds up the payment form it automatically fetches the tokens data from the server and displays the pre-filled widgets to the customer.

Sample form:

<form action="https://developer.peachpayments.com/docs/oppwa-integrations-copyandpay-network-tokens" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>
body {background-color:#f6f6f5;}
var wpwlOptions = {style:"card", registrations: {requireCvv: true}, paymentTarget: "_top"}
Stored cards.

Stored cards.

3. Get the payment status

After processing the payment request, the system redirects the customer to your shopperResultUrl with a GET parameter resourcePath=/v1/checkouts/{checkoutId}/registration

Payment response

The response includes a token transaction history, showing an attempt to fetch the network token before starting 3-D Secure authentication and payment authorisation. If no network token is active, the process continues using the real card data.

When fetching a network token, the response includes the original PAN BIN in the card.bin parameter. The network token BIN differs from the original PAN BIN, which is essential for post-authorisation issuer BIN management to ensure accurate transaction handling.

Sample request:

https://sandbox-card.peachpayments.com/v1/checkouts/843FF38610ACF8F39C00BC65A9CA35DD.uat01-vm-tx01/payment

curl -G https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment \
-d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
-H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc";
    string url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data;
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "GET";
    request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var s = new JavaScriptSerializer();
        responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    return responseData;
}

var responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  def url = ("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data).toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("GET")
  connection.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  def json = new JsonSlurper().parseText(connection.inputStream.text)
  return json
}

println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?entityId=8ac7a4c98ab5c40a018ab810cbc803fc");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    
    int responseCode = conn.getResponseCode();
    InputStream is = (responseCode >= 400) ? conn.getErrorStream() : conn.getInputStream();
    
    return IOUtils.toString(is, StandardCharsets.UTF_8);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    var path = '/v1/checkouts/{id}/payment';
    path += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc';
    
    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'GET',
        headers: {
            'Authorization': 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };
    
    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        
        postRequest.on('error', reject);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment";
    $url .= "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    ));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseData = curl_exec($ch);
    if (curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}

$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"
    url += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc'
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=b'')
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'GET'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
  path = ("?entityId=8ac7a4c98ab5c40a018ab810cbc803fc")
  uri = URI.parse('https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment' + path)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
  res = http.request(req)
  return JSON.parse(res.body)
end

puts request()
def initialPayment: String = {
  val url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"
  val fullUrl = url + "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  val conn = new URL(fullUrl).openConnection()

  conn match {
    case secureConn: HttpsURLConnection => secureConn.setRequestMethod("GET")
    case _ => throw new ClassCastException
  }
  
  conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  conn.connect()
  
  if (conn.getResponseCode >= 400) {
    IOUtils.toString(conn.getErrorStream())
  } else {
    IOUtils.toString(conn.getInputStream())
  }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment" + 
        "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "GET"
    req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    
    reader.Close()
    resStream.Close()
    res.Close()
    
    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)
    
    Return dict
End Function

responseData = Request()("result")("description")
{
  "id":"8ac7a4a19d21da51019d23311e984ec1",
  "registrationId":"8ac7a4a19d21da51019d232086303b11",
  "paymentType":"DB",
  "paymentBrand":"VISA",
  "amount":"11.13",
  "currency":"EUR",
  "descriptor":"8950.1399.4916 NetworkToken3DChannel",
  "result":{
    "avsResponse":"F",
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "resultDetails":{
    "Status":"AUTHORIZED",
    "ResponseCode":"00",
    "ConnectorTxID1":"7744119203956538004806",
    "AcquirerReconciliationId":"7744119203956538004806",
    "ConnectorTxID3":"7744119203956538004806",
    "ConnectorTxID2":"8ac7a4a19d21da51019d23311e984ec1",
    "retrievalReferenceNumber":"608304288489",
    "CardholderInitiatedTransactionID":"016153570198200",
    "ApprovalCode":"831000",
    "TransactionId":"016153570198200",
    "ExtendedDescription":"Successful approval.",
    "avs.codeRaw":"Y",
    "authorizedAmount":"11.13",
    "avs.code":"Y",
    "AcquirerResponse":"AUTHORIZED",
    "reconciliationId":"8ac7a4a19d21da51019d23311e984ec1",
    "NetworkTransactionId":"016153570198200"
  },
  "card":{
    "bin":"424242",
    "last4Digits":"6066",
    "holder":"John Smith",
    "expiryMonth":"12",
    "expiryYear":"2031"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "threeDSecure":{
    "eci":"05",
    "version":"2.2.0",
    "dsTransactionId":"0a99d948-17fa-4c06-91eb-9f8da67d08dd",
    "challengeMandatedIndicator":"N",
    "transactionStatusReason":"",
    "acsTransactionId":"9ed62ff4-770c-4d89-9199-388d5f0974a5",
    "cardHolderInfo":"",
    "authType":"01",
    "flow":"challenge",
    "authenticationStatus":"Y",
    "acsReferenceNumber":"b04ea28d11294692a29f63d2f5c84bfc",
    "dsReferenceNumber":"13db2d60d08c4f6b83de194ca5245e57",
    "purchaseDate":"20260325041155"
  },
  "customParameters":{
    "StandingInstructionAPI":"true",
    "CTPE_DESCRIPTOR_TEMPLATE":"",
    "3DS2_flow":"challenge",
    "StoredCredentialType":"CIT_STORED",
    "3DS2_enrolled":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-25 04:12:00+0000",
  "ndc":"843FF38610ACF8F39C00BC65A9CA35DD.uat01-vm-tx01",
  "standingInstruction":{
    "source":"CIT",
    "type":"UNSCHEDULED",
    "mode":"REPEATED",
    "initialTransactionId":"016153570198200"
  },
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a19d21da51019d23311eae4ec8",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TF",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}

One-time payment

Collect card data from the customer through a widget and start the one-time payment. The card network provisions a network token, involving the issuer in the approval process. The system authorises the payment with real card data or the network token if available and active.

1. Prepare the checkout

To start network token provisioning, perform a server-to-server POST request with all required payment and customer data, including payment type, amount, and currency. A successful request returns an id needed to create the payment form.

Sample request:

curl https://sandbox-card.peachpayments.com/v1/checkouts \
 -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
 -d "customParameters[3DS2_enrolled]=true" \
 -d "customParameters[3DS2_flow]=challenge" \
 -d "testMode=EXTERNAL" \
 -d "amount=11.12" \
 -d "currency=EUR" \
 -d "paymentType=DB" \
 -d "standingInstruction.mode=INITIAL" \
 -d "standingInstruction.source=CIT" \
 -d "standingInstruction.type=UNSCHEDULED" \
 -d "customer.givenName=Smith" \
 -d "customer.ip=192.168.0.0" \
 -d "customer.surname=John" \
 -d "customer.language=DE" \
 -d "[email protected]" \
 -d "billing.city=MyCity" \
 -d "billing.country=DE" \
 -d "billing.postcode=712121" \
 -d "billing.state=DE" \
 -d "billing.street1=MyStreet" \
 -d "integrity=true" \
 -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data="entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&amount=11.12" +
        "&currency=EUR" +
        "&paymentType=DB" +
        "&standingInstruction.mode=INITIAL" +
        "&standingInstruction.source=CIT" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet" +
        "&integrity=true";
    string url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    byte[]  buffer = Encoding.ASCII.GetBytes(data);
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "POST";
        request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    request.ContentType = "application/x-www-form-urlencoded";
    Stream PostData = request.GetRequestStream();
    PostData.Write(buffer, 0, buffer.Length);
    PostData.Close();
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var s = new JavaScriptSerializer();
        responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    return responseData;
}

responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
  "&customParameters[3DS2_enrolled]=true" +
  "&customParameters[3DS2_flow]=challenge" +
  "&testMode=EXTERNAL" +
  "&amount=11.12" +
  "&currency=EUR" +
  "&paymentType=DB" +
  "&standingInstruction.mode=INITIAL" +
  "&standingInstruction.source=CIT" +
  "&standingInstruction.type=UNSCHEDULED" +
  "&customer.givenName=Smith" +
  "&customer.ip=192.168.0.0" +
  "&customer.surname=John" +
  "&customer.language=DE" +
  "&[email protected]" +
  "&billing.city=MyCity" +
  "&billing.country=DE" +
  "&billing.postcode=712121" +
  "&billing.state=DE" +
  "&billing.street1=MyStreet" +
  "&integrity=true"
  def url = "https://sandbox-card.peachpayments.com/v1/checkouts".toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Authorization","Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  connection.doOutput = true
  connection.outputStream << data
  def json = new JsonSlurper().parseText(connection.inputStream.text)
  json
}
println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    String data = ""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&customParameters[3DS2_enrolled]=true"
        + "&customParameters[3DS2_flow]=challenge"
        + "&testMode=EXTERNAL"
        + "&amount=11.12"
        + "&currency=EUR"
        + "&paymentType=DB"
        + "&standingInstruction.mode=INITIAL"
        + "&standingInstruction.source=CIT"
        + "&standingInstruction.type=UNSCHEDULED"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet"
        + "&integrity=true";

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(data);
    wr.flush();
    wr.close();
    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) is = conn.getErrorStream();
    else is = conn.getInputStream();

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    const path='/v1/checkouts';
    const data = querystring.stringify({
        'entityId':'8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]':'true',
        'customParameters[3DS2_flow]':'challenge',
        'testMode':'EXTERNAL',
        'amount':'11.12',
        'currency':'EUR',
        'paymentType':'DB',
        'standingInstruction.mode':'INITIAL',
        'standingInstruction.source':'CIT',
        'standingInstruction.type':'UNSCHEDULED',
        'customer.givenName':'Smith',
        'customer.ip':'192.168.0.0',
        'customer.surname':'John',
        'customer.language':'DE',
        'customer.email':'[email protected]',
        'billing.city':'MyCity',
        'billing.country':'DE',
        'billing.postcode':'712121',
        'billing.state':'DE',
        'billing.street1':'MyStreet',
        'integrity':'true'
    });
    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length,
            'Authorization':'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };
    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        postRequest.on('error', reject);
        postRequest.write(data);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts";
    $data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" .
                "&customParameters[3DS2_enrolled]=true" .
                "&customParameters[3DS2_flow]=challenge" .
                "&testMode=EXTERNAL" .
                "&amount=11.12" .
                "&currency=EUR" .
                "&paymentType=DB" .
                "&standingInstruction.mode=INITIAL" .
                "&standingInstruction.source=CIT" .
                "&standingInstruction.type=UNSCHEDULED" .
                "&customer.givenName=Smith" .
                "&customer.ip=192.168.0.0" .
                "&customer.surname=John" .
                "&customer.language=DE" .
                "&[email protected]" .
                "&billing.city=MyCity" .
                "&billing.country=DE" .
                "&billing.postcode=712121" .
                "&billing.state=DE" .
                "&billing.street1=MyStreet" .
                "&integrity=true";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                   'Authorization:Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// this should be set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    if(curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}
$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts"
    data = {
        'entityId' : '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]' : 'true',
        'customParameters[3DS2_flow]' : 'challenge',
        'testMode' : 'EXTERNAL',
        'amount' : '11.12',
        'currency' : 'EUR',
        'paymentType' : 'DB',
        'standingInstruction.mode' : 'INITIAL',
        'standingInstruction.source' : 'CIT',
        'standingInstruction.type' : 'UNSCHEDULED',
        'customer.givenName' : 'Smith',
        'customer.ip' : '192.168.0.0',
        'customer.surname' : 'John',
        'customer.language' : 'DE',
        'customer.email' : '[email protected]',
        'billing.city' : 'MyCity',
        'billing.country' : 'DE',
        'billing.postcode' : '712121',
        'billing.state' : 'DE',
        'billing.street1' : 'MyStreet',
        'integrity' : 'true'
    }
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=urlencode(data).encode('utf-8'))
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'POST'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
    uri = URI('https://sandbox-card.peachpayments.com/v1/checkouts')
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    req = Net::HTTP::Post.new(uri.path)
    req.set_form_data({
        'entityId' => '8ac7a4c98ab5c40a018ab810cbc803fc',
        'customParameters[3DS2_enrolled]' => 'true',
        'customParameters[3DS2_flow]' => 'challenge',
        'testMode' => 'EXTERNAL',
        'amount' => '11.12',
        'currency' => 'EUR',
        'paymentType' => 'DB',
        'standingInstruction.mode' => 'INITIAL',
        'standingInstruction.source' => 'CIT',
        'standingInstruction.type' => 'UNSCHEDULED',
        'customer.givenName' => 'Smith',
        'customer.ip' => '192.168.0.0',
        'customer.surname' => 'John',
        'customer.language' => 'DE',
        'customer.email' => '[email protected]',
        'billing.city' => 'MyCity',
        'billing.country' => 'DE',
        'billing.postcode' => '712121',
        'billing.state' => 'DE',
        'billing.street1' => 'MyStreet',
        'integrity' => 'true'
    })
    res = http.request(req)
    return JSON.parse(res.body)
end

puts request()
def initialPayment : String = {
    val url = "https://sandbox-card.peachpayments.com/v1/checkouts"
    val data = (""
        + "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
        + "&customParameters[3DS2_enrolled]=true"
        + "&customParameters[3DS2_flow]=challenge"
        + "&testMode=EXTERNAL"
        + "&amount=11.12"
        + "&currency=EUR"
        + "&paymentType=DB"
        + "&standingInstruction.mode=INITIAL"
        + "&standingInstruction.source=CIT"
        + "&standingInstruction.type=UNSCHEDULED"
        + "&customer.givenName=Smith"
        + "&customer.ip=192.168.0.0"
        + "&customer.surname=John"
        + "&customer.language=DE"
        + "&[email protected]"
        + "&billing.city=MyCity"
        + "&billing.country=DE"
        + "&billing.postcode=712121"
        + "&billing.state=DE"
        + "&billing.street1=MyStreet"
        + "&integrity=true"
    )
    val conn = new URL(url).openConnection()

    conn match {
        case secureConn: HttpsURLConnection  => secureConn.setRequestMethod("POST")
        case _ => throw new ClassCastException
    }
    conn.setDoInput(true)
    conn.setDoOutput(true)
    IOUtils.write(data, conn.getOutputStream())
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    conn.connect()
    if (conn.getResponseCode() >= 400) {
        return IOUtils.toString(conn.getErrorStream())
    }
    else {
        return IOUtils.toString(conn.getInputStream())
    }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts"
    Dim data As String = "" +
        "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" +
        "&customParameters[3DS2_enrolled]=true" +
        "&customParameters[3DS2_flow]=challenge" +
        "&testMode=EXTERNAL" +
        "&amount=11.12" +
        "&currency=EUR" +
        "&paymentType=DB" +
        "&standingInstruction.mode=INITIAL" +
        "&standingInstruction.source=CIT" +
        "&standingInstruction.type=UNSCHEDULED" +
        "&customer.givenName=Smith" +
        "&customer.ip=192.168.0.0" +
        "&customer.surname=John" +
        "&customer.language=DE" +
        "&[email protected]" +
        "&billing.city=MyCity" +
        "&billing.country=DE" +
        "&billing.postcode=712121" +
        "&billing.state=DE" +
        "&billing.street1=MyStreet" +
        "&integrity=true"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "POST"
        req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(data)
    req.ContentLength = byteArray.Length
    Dim dataStream As Stream = req.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    reader.Close()
    resStream.Close()
    res.Close()
    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)

    Return dict
End Function

responseData = Request()("result")("description")
{
  "result":{
    "code":"000.200.100",
    "description":"successfully created checkout"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-25 04:13:04+0000",
  "ndc":"3FF49270FE8E729368885A951431C182.uat01-vm-tx01",
  "id":"3FF49270FE8E729368885A951431C182.uat01-vm-tx01",
  "integrity":"sha384-Gu544UradBCDq5dr/KlJhTp4ySJMSZ6vzxilwA4DJBcWs5WmvE0c9c0P+RrAi41X"
}

2. Create the payment form

Add the following lines of HTML and JavaScript to your page:

  • With the checkoutId received from the first step:
    <script
      src="https://sandbox-card.peachpayments.com/v1/paymentWidgets.js?checkoutId={checkout_id}"
      integrity="{integrity}"
      crossorigin="anonymous">
    </script>
  • With the shopperResultUrl as the page to which the system redirects the customer after payment.
    <form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>

Sample form:

<form action="https://developer.peachpayments.com/docs/oppwa-integrations-copyandpay-network-tokens" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>
body {background-color:#f6f6f5;}
var wpwlOptions = {style:"card", registrations: {requireCvv: true}, paymentTarget: "_top"}
Card form.

Card form.

3. Get the payment status

After processing the payment request, the system redirects the customer to shopperResultUrl with a GET parameter resourcePath: resourcePath=/v1/checkouts/{checkoutId}/payment.

Payment response

The response includes a token transaction history, showing that the card network has started the network token provisioning process. The system fetches the network token before 3-D Secure authentication and payment authorisation.

A simulated delay in the test environment keeps the network token provisioning request in flight. If no network token is active, 3-D Secure authentication and payment authorisation use real card data.

When the system fetches the network token, the response includes the original PAN BIN. The card.bin parameter contains this information. The network token BIN differs from the original PAN BIN, which is essential for post-authorisation issuer BIN management.

Sample request:

https://sandbox-card.peachpayments.com/v1/checkouts/3FF49270FE8E729368885A951431C182.uat01-vm-tx01/payment

curl -G https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment \
 -d "entityId=8ac7a4c98ab5c40a018ab810cbc803fc" \
 -H "Authorization: Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ="
public Dictionary<string, dynamic> Request() {
    Dictionary<string, dynamic> responseData;
    string data="entityId=8ac7a4c98ab5c40a018ab810cbc803fc";
    string url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data;
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "GET";
        request.Headers["Authorization"] = "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=";
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        var s = new JavaScriptSerializer();
        responseData = s.Deserialize<Dictionary<string, dynamic>>(reader.ReadToEnd());
        reader.Close();
        dataStream.Close();
    }
    return responseData;
}

responseData = Request()["result"]["description"];
import groovy.json.JsonSlurper

public static String request() {
  def data = "entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
  def url = ("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?" + data).toURL()
  def connection = url.openConnection()
  connection.setRequestMethod("GET")
  connection.setRequestProperty("Authorization","Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
  def json = new JsonSlurper().parseText(connection.inputStream.text)
  json
}
println request()
private String request() throws IOException {
    URL url = new URL("https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment?entityId=8ac7a4c98ab5c40a018ab810cbc803fc");

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
        conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=");
    int responseCode = conn.getResponseCode();
    InputStream is;

    if (responseCode >= 400) is = conn.getErrorStream();
    else is = conn.getInputStream();

    return IOUtils.toString(is);
}
const https = require('https');
const querystring = require('querystring');

const request = async () => {
    var path='/v1/checkouts/{id}/payment';
    path += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc';
    const options = {
        port: 443,
        host: 'sandbox-card.peachpayments.com',
        path: path,
        method: 'GET',
        headers: {
            'Authorization':'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
        }
    };
    return new Promise((resolve, reject) => {
        const postRequest = https.request(options, function(res) {
            const buf = [];
            res.on('data', chunk => {
                buf.push(Buffer.from(chunk));
            });
            res.on('end', () => {
                const jsonString = Buffer.concat(buf).toString('utf8');
                try {
                    resolve(JSON.parse(jsonString));
                } catch (error) {
                    reject(error);
                }
            });
        });
        postRequest.on('error', reject);
        postRequest.end();
    });
};

request().then(console.log).catch(console.error);
function request() {
    $url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment";
    $url .= "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                   'Authorization:Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// this should be set to true in production
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $responseData = curl_exec($ch);
    if(curl_errno($ch)) {
        return curl_error($ch);
    }
    curl_close($ch);
    return $responseData;
}
$responseData = request();
try:
    from urllib.parse import urlencode
    from urllib.request import build_opener, Request, HTTPHandler
    from urllib.error import HTTPError, URLError
except ImportError:
    from urllib import urlencode
    from urllib2 import build_opener, Request, HTTPHandler, HTTPError, URLError
import json

def request():
    url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"
    url += '?entityId=8ac7a4c98ab5c40a018ab810cbc803fc'
    try:
        opener = build_opener(HTTPHandler)
        request = Request(url, data=b'')
        request.add_header('Authorization', 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=')
        request.get_method = lambda: 'GET'
        response = opener.open(request)
        return json.loads(response.read())
    except HTTPError as e:
        return json.loads(e.read())
    except URLError as e:
        return e.reason

responseData = request()
print(responseData)
require 'net/https'
require 'uri'
require 'json'

def request()
    path = ("?entityId=8ac7a4c98ab5c40a018ab810cbc803fc")
    uri = URI.parse('https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment' + path)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    req = Net::HTTP::Get.new(uri)
    req['Authorization'] = 'Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ='
    res = http.request(req)
    return JSON.parse(res.body)
end

puts request()
def initialPayment : String = {
    val url = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment"
    url +="?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"
    val conn = new URL(url).openConnection()

    conn match {
        case secureConn: HttpsURLConnection  => secureConn.setRequestMethod("GET")
        case _ => throw new ClassCastException
    }
    conn.setRequestProperty("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    conn.connect()
    if (conn.getResponseCode() >= 400) {
        return IOUtils.toString(conn.getErrorStream())
    }
    else {
        return IOUtils.toString(conn.getInputStream())
    }
}
Public Function Request() As Dictionary(Of String, Object)
    Dim url As String = "https://sandbox-card.peachpayments.com/v1/checkouts/{id}/payment" +
        "?entityId=8ac7a4c98ab5c40a018ab810cbc803fc"

    Dim req As WebRequest = WebRequest.Create(url)
    req.Method = "GET"
        req.Headers.Add("Authorization", "Bearer OGE4Mjk0MTc0ZTczNWQwYzAxNGU3OGNmMjY2YjE3OTR8SFV3I3JGQTQ9bWpxaWYrPz9OWVQ=")
    req.ContentType = "application/x-www-form-urlencoded"
    Dim res As WebResponse = req.GetResponse()
    Dim resStream = res.GetResponseStream()
    Dim reader As New StreamReader(resStream)
    Dim response As String = reader.ReadToEnd()
    reader.Close()
    resStream.Close()
    res.Close()
    Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
    Dim dict As Dictionary(Of String, Object) = jss.Deserialize(Of Dictionary(Of String, Object))(response)

    Return dict
End Function

responseData = Request()("result")("description")
{
  "id":"8ac7a4a09d21e349019d23347c793dec",
  "paymentType":"DB",
  "paymentBrand":"VISA",
  "amount":"11.12",
  "currency":"EUR",
  "descriptor":"6624.1306.6660 NetworkToken3DChannel",
  "recurringType":"INITIAL",
  "result":{
    "avsResponse":"F",
    "code":"000.100.112",
    "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
  },
  "resultDetails":{
    "Status":"AUTHORIZED",
    "ResponseCode":"00",
    "ConnectorTxID1":"7744121403646651704805",
    "AcquirerReconciliationId":"7744121403646651704805",
    "ConnectorTxID3":"7744121403646651704805",
    "ConnectorTxID2":"8ac7a4a09d21e349019d23347c793dec",
    "retrievalReferenceNumber":"608304773888",
    "CardholderInitiatedTransactionID":"016153570198200",
    "ApprovalCode":"831000",
    "TransactionId":"016153570198200",
    "ExtendedDescription":"Successful approval.",
    "usedChallengeIndicator":"04",
    "avs.codeRaw":"Y",
    "authorizedAmount":"11.12",
    "avs.code":"Y",
    "AcquirerResponse":"AUTHORIZED",
    "reconciliationId":"8ac7a4a09d21e349019d23347c793dec",
    "NetworkTransactionId":"016153570198200"
  },
  "card":{
    "bin":"420000",
    "last4Digits":"0091",
    "holder":"John Doe",
    "expiryMonth":"12",
    "expiryYear":"2029"
  },
  "customer":{
    "givenName":"Smith",
    "surname":"John",
    "email":"[email protected]",
    "ip":"192.168.0.0",
    "language":"DE"
  },
  "billing":{
    "street1":"MyStreet",
    "city":"MyCity",
    "state":"DE",
    "postcode":"712121",
    "country":"DE"
  },
  "threeDSecure":{
    "eci":"05",
    "version":"2.2.0",
    "dsTransactionId":"1cb57c13-7127-464b-a51d-544a9a2b0e4e",
    "challengeMandatedIndicator":"N",
    "transactionStatusReason":"",
    "acsTransactionId":"5e8361a6-ca83-4ceb-b6e3-5b800b127838",
    "cardHolderInfo":"",
    "authType":"01",
    "flow":"challenge",
    "authenticationStatus":"Y",
    "acsReferenceNumber":"b04ea28d11294692a29f63d2f5c84bfc",
    "dsReferenceNumber":"13db2d60d08c4f6b83de194ca5245e57",
    "purchaseDate":"20260325041536"
  },
  "customParameters":{
    "StandingInstructionAPI":"true",
    "SHOPPER_EndToEndIdentity":"1adda58be2b022430c36fdd315f5d840b1774cd86888eddc4f2060f61a080bde",
    "CTPE_DESCRIPTOR_TEMPLATE":"",
    "3DS2_flow":"challenge",
    "StoredCredentialType":"CIT",
    "StandingInstruction":"UNSCHEDULED",
    "3DS2_enrolled":"true"
  },
  "risk":{
    "score":"0"
  },
  "buildNumber":"9092e7a6af8301accda2f9a3a38f743f907dadd5@2026-03-23 16:50:06 +0000",
  "timestamp":"2026-03-25 04:15:40+0000",
  "ndc":"3FF49270FE8E729368885A951431C182.uat01-vm-tx01",
  "standingInstruction":{
    "source":"CIT",
    "type":"UNSCHEDULED",
    "mode":"INITIAL",
    "initialTransactionId":"016153570198200"
  },
  "processingDetails":{
    "transactions":[
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a09d21e349019d23347ca23df4",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TK",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      },
      {
        "reason":"tokenization",
        "transactionId":"8ac7a4a09d21e349019d23347ef53dfc",
        "clearingInstituteName":"TokenVault",
        "paymentType":"TF",
        "result":{
          "code":"000.100.112",
          "description":"Request successfully processed in 'Merchant in Connector Test Mode'"
        }
      }
    ]
  }
}