Skip to content
payrocdevelopers

Save a customer's payment details

Convert a Hosted Fields single-use token into a reusable secure token by sending a POST request to the Secure Tokens endpoint, enabling future card and bank account payments without recapturing payment details.

An AI skill is available for this guide, get it on the Skills Marketplace (GitHub).

You can update your Hosted Fields integration to save a customer's payment details as a secure token without charging the customer.

To tokenize the customer's payment details, you need to update the Hosted Fields JavaScript configuration, and then send a request to our Secure Tokens endpoint.

You don't need to change your authentication process for your existing Hosted Fields integration.

Before you begin

Make sure that you've set up your Hosted Fields integration to handle the single-use token from the submissionSuccess event. For more information, go to Run a sale.

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

Integration steps

  1. Update the JavaScript configuration.
  2. Convert the single-use token into a secure token.

Step 1. Update the JavaScript configuration

  • In the JavaScript configuration, change the value for the mode parameter from payment to tokenization.

Card

JavaScript
<script
  src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
  integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
  crossorigin="anonymous"
></script>

<script>
  const cardForm = new Payroc.hostedFields({
    sessionToken: YOUR_SESSION_TOKEN,
    mode: "tokenization",
    fields: {
      card: {
        cardholderName: {
          target: ".card-holder-name",
          errorTarget: ".card-holder-name-error",
          placeholder: "Cardholder Name",
        },
        cardNumber: {
          target: ".card-number",
          errorTarget: ".card-number-error",
          placeholder: "1234 5678 1234 1211",
        },
        cvv: {
          wrapperTarget: ".card-cvv-wrapper",
          target: ".card-cvv",
          errorTarget: ".card-cvv-error",
          placeholder: "CVV",
        },
        expiryDate: {
          target: ".card-expiry",
          errorTarget: ".card-expiry-error",
          placeholder: "MM/YY",
        },
        submit: {
          target: ".submit-button",
          value: "Submit",
        },
      },
    },
  });
  padForm.initialize();
</script>

ACH

JavaScript
<script
  src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
  integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
  crossorigin="anonymous"
></script>

<script>
  const achForm = new Payroc.hostedFields({
    sessionToken: YOUR_SESSION_TOKEN,
    mode: "tokenization",
    fields: {
      ach: {
        nameOnAccount: {
          target: ".ach-account-holder",
          errorTarget: ".ach-account-holder-error",
          placeholder: "Accountholder Name",
        },
        accountType: {
          target: ".ach-account-type",
          errorTarget: ".ach-account-type-error",
        },
        achAccountNumber: {
          target: ".ach-account-number",
          errorTarget: ".ach-account-number-error",
          placeholder: "Account Number",
        },
        routingNumber: {
          target: ".ach-routing-number",
          errorTarget: ".ach-routing-number-error",
          placeholder: "Routing Number",
        },
        submit: {
          target: ".submit-button",
          value: "Submit",
        },
      },
    },
  });
</script>

PAD

JavaScript
<script
  src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
  integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
  crossorigin="anonymous"
></script>

<script>
  const padForm = new Payroc.hostedFields({
    sessionToken: YOUR_SESSION_TOKEN,
    mode: "tokenization",
    fields: {
      pad: {
        nameOnAccount: {
          target: ".pad-account-holder",
          errorTarget: ".pad-account-holder-error",
          placeholder: "Accountholder Name",
        },
        padAccountNumber: {
          target: ".pad-account-number",
          errorTarget: ".pad-account-number-error",
          placeholder: "Account Number",
        },
        institutionNumber: {
          target: ".pad-institution-number",
          errorTarget: ".pad-institution-number-error",
          placeholder: "Institution Number",
        },
        transitNumber: {
          target: ".pad-transit-number",
          errorTarget: ".pad-transit-number-error",
          placeholder: "Transit Number",
        },
        submit: {
          target: ".submit-button",
          value: "Submit",
        },
      },
    },
  });
</script>

Step 2. Convert the single-use token into a secure token

To convert the single-use token into a secure token, send a POST request to our Secure Tokens endpoint.

EnvironmentURL
Testhttps://api.uat.payroc.com/v1/processing-terminals/{processingTerminalId}/secure-tokens
Productionhttps://api.payroc.com/v1/processing-terminals/{processingTerminalId}/secure-tokens

Request parameters

In the body of your request, include the singleUseToken from the submissionSuccess event in the source object. We also recommend that you assign a secureTokenId.

Schema (request.body)

Request body schema for POST /processing-terminals/{processingTerminalId}/secure-tokens

Example request

Request

POST https://api.payroc.com/v1/processing-terminals/{processingTerminalId}/secure-tokens

Secure token created from a single-use token

curl
curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens \
     -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "source": {
    "type": "singleUseToken",
    "token": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  },
  "operator": "Jane",
  "mitAgreement": "unscheduled",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "dateOfBirth": "1990-07-15",
    "referenceNumber": "Customer-12",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2"
    },
    "contactMethods": [
      {
        "type": "email",
        "value": "sarah.hopper@example.com"
      }
    ],
    "notificationLanguage": "en"
  },
  "ipAddress": {
    "type": "ipv4",
    "value": "104.18.24.203"
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}'

Secure token created from a single-use token

Python
import requests

url = "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens"

payload = {
    "source": {
        "type": "singleUseToken",
        "token": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    },
    "operator": "Jane",
    "mitAgreement": "unscheduled",
    "customer": {
        "firstName": "Sarah",
        "lastName": "Hopper",
        "dateOfBirth": "1990-07-15",
        "referenceNumber": "Customer-12",
        "billingAddress": {
            "address1": "1 Example Ave.",
            "city": "Chicago",
            "state": "Illinois",
            "country": "US",
            "postalCode": "60056",
            "address2": "Example Address Line 2"
        },
        "contactMethods": [
            {
                "type": "email",
                "value": "sarah.hopper@example.com"
            }
        ],
        "notificationLanguage": "en"
    },
    "ipAddress": {
        "type": "ipv4",
        "value": "104.18.24.203"
    },
    "customFields": [
        {
            "name": "yourCustomField",
            "value": "abc123"
        }
    ]
}
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())

Secure token created from a single-use token

JavaScript
const url = 'https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"source":{"type":"singleUseToken","token":"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"},"operator":"Jane","mitAgreement":"unscheduled","customer":{"firstName":"Sarah","lastName":"Hopper","dateOfBirth":"1990-07-15","referenceNumber":"Customer-12","billingAddress":{"address1":"1 Example Ave.","city":"Chicago","state":"Illinois","country":"US","postalCode":"60056","address2":"Example Address Line 2"},"contactMethods":[{"type":"email","value":"sarah.hopper@example.com"}],"notificationLanguage":"en"},"ipAddress":{"type":"ipv4","value":"104.18.24.203"},"customFields":[{"name":"yourCustomField","value":"abc123"}]}'
};

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

Secure token created from a single-use token

go
package main

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

func main() {

	url := "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens"

	payload := strings.NewReader("{\n  \"source\": {\n    \"type\": \"singleUseToken\",\n    \"token\": \"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\"\n  },\n  \"operator\": \"Jane\",\n  \"mitAgreement\": \"unscheduled\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"dateOfBirth\": \"1990-07-15\",\n    \"referenceNumber\": \"Customer-12\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\"\n    },\n    \"contactMethods\": [\n      {\n        \"type\": \"email\",\n        \"value\": \"sarah.hopper@example.com\"\n      }\n    ],\n    \"notificationLanguage\": \"en\"\n  },\n  \"ipAddress\": {\n    \"type\": \"ipv4\",\n    \"value\": \"104.18.24.203\"\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}")

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

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

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

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

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

}

Secure token created from a single-use token

ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens")

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

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"source\": {\n    \"type\": \"singleUseToken\",\n    \"token\": \"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\"\n  },\n  \"operator\": \"Jane\",\n  \"mitAgreement\": \"unscheduled\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"dateOfBirth\": \"1990-07-15\",\n    \"referenceNumber\": \"Customer-12\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\"\n    },\n    \"contactMethods\": [\n      {\n        \"type\": \"email\",\n        \"value\": \"sarah.hopper@example.com\"\n      }\n    ],\n    \"notificationLanguage\": \"en\"\n  },\n  \"ipAddress\": {\n    \"type\": \"ipv4\",\n    \"value\": \"104.18.24.203\"\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}"

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

Secure token created from a single-use token

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

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"source\": {\n    \"type\": \"singleUseToken\",\n    \"token\": \"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\"\n  },\n  \"operator\": \"Jane\",\n  \"mitAgreement\": \"unscheduled\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"dateOfBirth\": \"1990-07-15\",\n    \"referenceNumber\": \"Customer-12\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\"\n    },\n    \"contactMethods\": [\n      {\n        \"type\": \"email\",\n        \"value\": \"sarah.hopper@example.com\"\n      }\n    ],\n    \"notificationLanguage\": \"en\"\n  },\n  \"ipAddress\": {\n    \"type\": \"ipv4\",\n    \"value\": \"104.18.24.203\"\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}")
  .asString();

Secure token created from a single-use token

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens', [
  'body' => '{
  "source": {
    "type": "singleUseToken",
    "token": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  },
  "operator": "Jane",
  "mitAgreement": "unscheduled",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "dateOfBirth": "1990-07-15",
    "referenceNumber": "Customer-12",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2"
    },
    "contactMethods": [
      {
        "type": "email",
        "value": "sarah.hopper@example.com"
      }
    ],
    "notificationLanguage": "en"
  },
  "ipAddress": {
    "type": "ipv4",
    "value": "104.18.24.203"
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();

Secure token created from a single-use token

C#
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"source\": {\n    \"type\": \"singleUseToken\",\n    \"token\": \"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\"\n  },\n  \"operator\": \"Jane\",\n  \"mitAgreement\": \"unscheduled\",\n  \"customer\": {\n    \"firstName\": \"Sarah\",\n    \"lastName\": \"Hopper\",\n    \"dateOfBirth\": \"1990-07-15\",\n    \"referenceNumber\": \"Customer-12\",\n    \"billingAddress\": {\n      \"address1\": \"1 Example Ave.\",\n      \"city\": \"Chicago\",\n      \"state\": \"Illinois\",\n      \"country\": \"US\",\n      \"postalCode\": \"60056\",\n      \"address2\": \"Example Address Line 2\"\n    },\n    \"contactMethods\": [\n      {\n        \"type\": \"email\",\n        \"value\": \"sarah.hopper@example.com\"\n      }\n    ],\n    \"notificationLanguage\": \"en\"\n  },\n  \"ipAddress\": {\n    \"type\": \"ipv4\",\n    \"value\": \"104.18.24.203\"\n  },\n  \"customFields\": [\n    {\n      \"name\": \"yourCustomField\",\n      \"value\": \"abc123\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Secure token created from a single-use token

swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "source": [
    "type": "singleUseToken",
    "token": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  ],
  "operator": "Jane",
  "mitAgreement": "unscheduled",
  "customer": [
    "firstName": "Sarah",
    "lastName": "Hopper",
    "dateOfBirth": "1990-07-15",
    "referenceNumber": "Customer-12",
    "billingAddress": [
      "address1": "1 Example Ave.",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056",
      "address2": "Example Address Line 2"
    ],
    "contactMethods": [
      [
        "type": "email",
        "value": "sarah.hopper@example.com"
      ]
    ],
    "notificationLanguage": "en"
  ],
  "ipAddress": [
    "type": "ipv4",
    "value": "104.18.24.203"
  ],
  "customFields": [
    [
      "name": "yourCustomField",
      "value": "abc123"
    ]
  ]
] as [String : Any]

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

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

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

dataTask.resume()

Response fields

If your request is successful, our gateway converts the single-use token into a secure token. Our gateway returns the secure token in the token field. The response also contains the following fields:

Schema (response.body)

Response body schema for POST /processing-terminals/{processingTerminalId}/secure-tokens

Response example

Response (201)

JSON
{
  "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
  "processingTerminalId": "1234001",
  "source": {
    "type": "card",
    "cardNumber": "453985******7062",
    "cardholderName": "Sarah Hazel Hopper",
    "expiryDate": "1230"
  },
  "token": "296753123456",
  "status": "notValidated",
  "mitAgreement": "unscheduled",
  "customer": {
    "firstName": "Sarah",
    "lastName": "Hopper",
    "dateOfBirth": "1990-07-15",
    "referenceNumber": "Customer-12",
    "billingAddress": {
      "address1": "1 Example Ave.",
      "address2": "Example Address Line 2",
      "city": "Chicago",
      "state": "Illinois",
      "country": "US",
      "postalCode": "60056"
    },
    "contactMethods": [
      {
        "type": "email",
        "value": "sarah.hopper@example.com"
      }
    ],
    "notificationLanguage": "en"
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}

Using the secure token

After you receive the secure token that represents the customer's payment details, you can use it in follow-up requests to our API, including:

Note: You can also use the secure token to set up repeat payments with our gateway, which requires more integration effort and cost. For more information, contact our Integrations Team at integrationsupport@payroc.com.

Browse guides

Search documentation

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

Menu

Theme

Sign out

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

Talk to an engineer