HPP API Reference
The NCR Voyix Hosted Payment Page (HPP) API is a server-driven REST API for creating and finalizing eCommerce payment sessions. Your server creates sessions, your frontend embeds the hosted payment form in an iframe, and your server finalizes the transaction.
The API accepts both application/json and text/xml bodies, uses RSA-SHA256 request signing for authentication, and returns JSON or XML responses with standard HTTP status codes.
Base URL
All endpoints share a single base URL with a configurable datacenter and environment. All code examples on this page update automatically when you change the values below.
Sample URL: https://seps{datacenter}-{environment}.paymentslab.ncrvoyix.com/WebEPS. Your NCR integration team will confirm your datacenter and environment during onboarding.
API versioning
All endpoints are prefixed with the API version segment. The current production version is v1.4. The URL pattern is: {baseURL}/v1.4/{Service}/{Endpoint}
Content types
All endpoints accept application/json (preferred) or text/xml. The Content-Type you set must exactly match the format of the body you sign — changing the body after signing will invalidate the signature.
Postman end-to-end sandbox
Validate the complete purchase flow without writing app code. Use this Postman-first path to verify configuration, RSA signing, and API responses before frontend integration.
Complete these setup items before using the collection:
- Generate RSA keys first and secure private key material. Follow RSA key generation (clean setup) below.
- Prepare Postman environment with
privateEncryptedKeyPEMandpasswordto validate signatures before app integration. - Confirm NCR onboarding values:
X-CompanyNumber,X-StoreNumber, and allowed origins forReturnURL/FrameHostingURL. - Set server environment variables and keep private key usage server-side only.
The zip contains the Postman collection and the sandbox environment file. Import both into Postman to get started immediately.
RSA key generation (clean setup)
Use the Dev Portal RSA Key Generation Studio output as your single source for Postman and backend signing inputs.
⬇ Download RSA Key Generator (.zip)
- Open
RsaKeyGenerationStudio.exefrom the Dev Portal package. - Enter a key prefix (for example:
KC250630-STORE190). - Use key size
2048or4096(recommended default:2048). - Set a key secret so the private PEM is exported as encrypted PKCS#8.
- Generate and verify:
{Prefix}.Private.pem,{Prefix}.Public.pem,{Prefix}.Private.xml,{Prefix}.Public.xml.
Where each key file is used
| File | Used by | Purpose |
|---|---|---|
{Prefix}.Private.pem | Postman (privateEncryptedKeyPEM) | RSA signing for InitializeSession / CompleteSession scripts |
{Prefix}.Public.pem | Postman optional verification | Signature verification during troubleshooting |
{Prefix}.Public.xml | Mobile registration body | ClientPublicKey for RegisterMobileDevice |
{Prefix}.Private.xml | Legacy tools only | Not required in standard HPP browser iframe flow |
Recommended collection flow
- Import
NCR Postman WebEPS APIcollection and matching environment. - Set environment values:
baseURL,API Version,Company Number,Store Number,Client Application Name. - Set key material:
privateEncryptedKeyPEMandpassword. - Run InitializeSession — the pre-request script auto-injects
RequestExpirationUTCandX-Signature. - Open the returned
RequestURLin a browser and complete a test payment. - Run CompleteSession using the saved
CompleteSessioncollection variable.
Prefer a visual Swagger-style explorer? Try all endpoints directly from the browser.
Open Swagger UI →Authentication
HPP API authentication is stateless and per-request. Every request is authenticated by two components:
- Merchant identity headers —
X-CompanyNumberandX-StoreNumberidentify your merchant account. - RSA-SHA256 request signature —
X-Signatureproves the request body was sent by the holder of your registered RSA private key and has not been tampered with.
There are no API keys, Bearer tokens, or session cookies. Every request must carry a freshly computed signature. The RequestExpirationUTC field in every request body acts as a replay-attack guard.
Required headers
All three endpoints share the same required headers. X-Client-Application-Name is additionally required on InitializeSession.
application/json or text/xml. Must match the exact format you signed. Mismatches cause a 400.crypto.randomUUID().replace(/-/g, '').toUpperCase(). Used for tracing and support."MyCheckoutApp"). Used by NCR for telemetry and support routing."2.1.0").POST /v1.4/PaymentTransactionManagement/InitializeSession
Content-Type: application/json
X-CompanyNumber: YOUR_COMPANY_NUMBER
X-StoreNumber: YOUR_STORE_NUMBER
X-ReferenceId: A1B2C3D4E5F6789012345678901234AB
X-Client-Application-Name: MyEcommerceApp
X-Client-Application-Version: 1.0.0
X-Signature: 3A9F12C8D4...
// Fresh unique ID per request
const refId = crypto
.randomUUID()
.replace(/-/g, '')
.toUpperCase();
// → "A1B2C3D4E5F6789012345678901234AB"
RegisterServer
Registers your server's RSA public key with NCR Voyix. This establishes the trust relationship that allows WebEPS to verify the RSA-SHA256 signatures on all subsequent API calls. You must call this endpoint before any payment operations can succeed.
The key is tied to your X-CompanyNumber and X-StoreNumber and remains valid for the number of days specified in KeyDurationInDays. Re-register before the key expires to avoid service interruption.
KeyFormat for definitions.90.KeyFormat for definitions.curl -X POST "https://seps1-rls.paymentslab.ncrvoyix.com/WebEPS/v1.4/EndpointAdministration/RegisterServer" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: 3F9B1A..." \
-d '{
"ClientPublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjAN...\n-----END PUBLIC KEY-----",
"ClientPublicKeyFormat": "PEM",
"KeyDurationInDays": 90,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z"
}'
{
"ServerPublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjAN...\n-----END PUBLIC KEY-----",
"ServerPublicKeyFormat": "PEM",
"KeyExpirationUTC": "2026-10-13T12:00:00.000Z"
}
async function registerServer(publicKeyPem) {
const body = {
ClientPublicKey: publicKeyPem,
ClientPublicKeyFormat: 'PEM',
KeyDurationInDays: 90,
RequestExpirationUTC: new Date(Date.now() + 5 * 60000).toISOString()
};
const signature = signBody(body); // RSA-SHA256 hex, upper-case
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EndpointAdministration/RegisterServer`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Signature': signature
},
body: JSON.stringify(body)
}
);
return res.json();
}
// Response: { ServerPublicKey, ServerPublicKeyFormat, KeyExpirationUTC }
import requests, os, uuid
from datetime import datetime, timezone, timedelta
from sign import sign_body # your RSA-SHA256 helper
def register_server(public_key_pem: str) -> dict:
body = {
"ClientPublicKey": public_key_pem,
"ClientPublicKeyFormat": "PEM",
"KeyDurationInDays": 90,
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime("%Y-%m-%dT%H:%M:%S.000Z")
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EndpointAdministration/RegisterServer",
headers={
"Content-Type": "application/json",
"X-CompanyNumber": os.environ["COMPANY"],
"X-StoreNumber": os.environ["STORE"],
"X-ReferenceId": uuid.uuid4().hex.upper(),
"X-Signature": sign_body(body)
},
json=body
)
r.raise_for_status()
return r.json()
# Response: {"ServerPublicKey": "...", "ServerPublicKeyFormat": "PEM", "KeyExpirationUTC": "..."}
public async Task<string> RegisterServerAsync(string publicKeyPem)
{
var body = new {
ClientPublicKey = publicKeyPem,
ClientPublicKeyFormat = "PEM",
KeyDurationInDays = 90,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5)
.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
};
var json = JsonSerializer.Serialize(body);
var sig = SignBody(json); // RSA-SHA256 hex upper-case
var request = new HttpRequestMessage(
HttpMethod.Post,
$"{Env("HPP_BASE")}/v1.4/EndpointAdministration/RegisterServer");
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Headers.Add("X-CompanyNumber", Env("COMPANY"));
request.Headers.Add("X-StoreNumber", Env("STORE"));
request.Headers.Add("X-ReferenceId", Guid.NewGuid().ToString("N").ToUpper());
request.Headers.Add("X-Signature", sig);
var response = await _http.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
// Response: { ServerPublicKey, ServerPublicKeyFormat, KeyExpirationUTC }
public String registerServer(String publicKeyPem) throws Exception {
String expiry = Instant.now().plusSeconds(300).toString();
String json = String.format(
"{\"ClientPublicKey\":\"%s\"," +
"\"ClientPublicKeyFormat\":\"PEM\"," +
"\"KeyDurationInDays\":90," +
"\"RequestExpirationUTC\":\"%s\"}",
publicKeyPem.replace("\n", "\\n"), expiry);
String sig = signBody(json);
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(HPP_BASE + "/v1.4/EndpointAdministration/RegisterServer"))
.header("Content-Type", "application/json")
.header("X-CompanyNumber", COMPANY)
.header("X-StoreNumber", STORE)
.header("X-ReferenceId", UUID.randomUUID().toString().replace("-","").toUpperCase())
.header("X-Signature", sig)
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
}
// Response: {"ServerPublicKey":"...","ServerPublicKeyFormat":"PEM","KeyExpirationUTC":"..."}
InitializeSession
Creates a new HPP payment session. Returns a SessionId and a RequestURL. Set RequestURL as the src of your payment <iframe>. Store SessionId server-side — it is required for CompleteSession.
This endpoint must be called from your server. Sign the request body with your RSA private key and pass only sessionId and requestURL back to the browser.
"MyEcommerceApp"). Required only on this endpoint."2.1.0").2026-07-10T12:05:00.000Z.AuthorizationMode is specified.?statusCode=NNN on redirect."Redirect". See CardEnrollmentReturnMethod for all values.ReturnURL.true."Full" for 3-D Secure sessions. Default: "Full".false.false.true, the SecurePay UI presents the user with a dialog for naming their card for wallet storage. Default: false."Credit". See TenderType for all values.15.X-StoreNumber header is not sent.false.false.false.MMYY or MMYYYY format. Intended for edit scenarios when a token was already received.CompleteSession. Never expose to browser JavaScript.src of your payment <iframe> element in the browser.curl -X POST "https://seps1-rls.paymentslab.ncrvoyix.com/WebEPS/v1.4/PaymentTransactionManagement/InitializeSession" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Client-Application-Name: MyApp" \
-H "X-Signature: 3A9F12C8D4..." \
-d '{
"Amount": 59.99,
"ReturnMethod": "Redirect",
"ReturnURL": "https://example.com/pay/return",
"FrameHostingURL": "https://example.com",
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"PaymentMethodType": ["CreditCard","GooglePay"],
"GooglePayMerchantId": "YOUR_GPAY_MERCHANT_ID",
"GooglePayMerchantName": "Your Store",
"TokenRetrievalRequired": true,
"AccountAddressCollectionMode": "Full",
"ValidateAccountSecurityCode": true,
"ValidateAccountAddress": true
}'
{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestURL": "https://hpp.ncrvoyix.com/WebEPS/HPP?session=45016f4cce57e5ab4e308a1822b9b9fc3336"
}
const crypto = require('crypto');
const fs = require('fs');
const key = fs.readFileSync('./private.pem', 'utf8');
async function initializeSession(cart) {
const payload = {
Amount: cart.total,
ReturnMethod: 'Redirect',
ReturnURL: `${process.env.APP_URL}/pay/return`,
FrameHostingURL: process.env.APP_URL,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
PaymentMethodType: ['CreditCard', 'GooglePay'],
GooglePayMerchantId: process.env.GPAY_MERCHANT_ID,
GooglePayMerchantName: process.env.GPAY_MERCHANT_NAME,
TokenRetrievalRequired: true,
AccountAddressCollectionMode: 'Full',
ValidateAccountSecurityCode: true,
ValidateAccountAddress: true
};
const body = JSON.stringify(payload);
const sign = crypto.createSign('RSA-SHA256');
sign.update(body, 'utf8');
const xSig = sign.sign(
{ key, passphrase: process.env.KEY_PASS }, 'hex'
).toUpperCase();
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentTransactionManagement/InitializeSession`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Client-Application-Name': 'MyApp',
'X-Signature': xSig
},
body
}
);
return res.json(); // { SessionId, RequestURL }
}
{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestURL": "https://hpp.ncrvoyix.com/WebEPS/HPP?session=45016f4cce57e5ab4e308a1822b9b9fc3336"
}
import json, os, uuid, requests
from datetime import datetime, timedelta, timezone
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
with open("private.pem","rb") as f:
pkey = serialization.load_pem_private_key(
f.read(), password=os.environ["KEY_PASS"].encode())
def initialize_session(amount: float) -> dict:
payload = {
"Amount": amount,
"ReturnMethod": "Redirect",
"ReturnURL": f"{os.environ['APP_URL']}/pay/return",
"FrameHostingURL": os.environ["APP_URL"],
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime('%Y-%m-%dT%H:%M:%S.000Z'),
"PaymentMethodType": ["CreditCard", "GooglePay"],
"GooglePayMerchantId": os.environ["GPAY_MERCHANT_ID"],
"GooglePayMerchantName": os.environ["GPAY_MERCHANT_NAME"],
"TokenRetrievalRequired": True,
"AccountAddressCollectionMode": "Full",
"ValidateAccountSecurityCode": True,
"ValidateAccountAddress": True
}
body = json.dumps(payload, separators=(',', ':'))
sig = pkey.sign(body.encode(), padding.PKCS1v15(), hashes.SHA256())
x_sig = sig.hex().upper()
resp = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentTransactionManagement/InitializeSession",
headers={
"Content-Type": "application/json",
"X-CompanyNumber": os.environ["COMPANY"],
"X-StoreNumber": os.environ["STORE"],
"X-ReferenceId": uuid.uuid4().hex.upper(),
"X-Client-Application-Name": "MyApp",
"X-Signature": x_sig
},
data=body, timeout=30
)
return resp.json()
{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestURL": "https://hpp.ncrvoyix.com/WebEPS/HPP?session=45016f4cce57e5ab4e308a1822b9b9fc3336"
}
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
public async Task<(string SessionId, string RequestURL)> InitializeSessionAsync(decimal amount)
{
using var rsa = RSA.Create();
rsa.ImportFromEncryptedPem(File.ReadAllText("private.pem"),
Environment.GetEnvironmentVariable("KEY_PASS"));
var payload = new {
Amount = amount,
ReturnMethod = "Redirect",
ReturnURL = $"{Env("APP_URL")}/pay/return",
FrameHostingURL = Env("APP_URL"),
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5)
.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
PaymentMethodType = new[] { "CreditCard", "GooglePay" },
GooglePayMerchantId = Env("GPAY_MERCHANT_ID"),
GooglePayMerchantName = Env("GPAY_MERCHANT_NAME"),
TokenRetrievalRequired = true,
AccountAddressCollectionMode = "Full",
ValidateAccountSecurityCode = true,
ValidateAccountAddress = true
};
var body = JsonSerializer.Serialize(payload);
var sigBytes = rsa.SignData(Encoding.UTF8.GetBytes(body),
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var xSig = Convert.ToHexString(sigBytes); // uppercase
using var client = new HttpClient();
using var req = new HttpRequestMessage(HttpMethod.Post,
$"{Env("HPP_BASE")}/v1.4/PaymentTransactionManagement/InitializeSession");
req.Headers.TryAddWithoutValidation("X-CompanyNumber", Env("COMPANY"));
req.Headers.TryAddWithoutValidation("X-StoreNumber", Env("STORE"));
req.Headers.TryAddWithoutValidation("X-ReferenceId", Guid.NewGuid().ToString("N").ToUpper());
req.Headers.TryAddWithoutValidation("X-Client-Application-Name", "MyApp");
req.Headers.TryAddWithoutValidation("X-Signature", xSig);
req.Content = new StringContent(body, Encoding.UTF8, "application/json");
var res = await client.SendAsync(req);
var data = await res.Content.ReadFromJsonAsync<InitResponse>();
return (data!.SessionId, data.RequestURL);
}
{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestURL": "https://hpp.ncrvoyix.com/WebEPS/HPP?session=45016f4cce57e5ab4e308a1822b9b9fc3336"
}
PrivateKey key = /* load PKCS#8 DER key */;
String expiry = ZonedDateTime.now(ZoneOffset.UTC).plusMinutes(5)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
String body = """
{
"Amount": 59.99,
"ReturnMethod": "Redirect",
"ReturnURL": "https://example.com/pay/return",
"FrameHostingURL": "https://example.com",
"RequestExpirationUTC": "%s",
"PaymentMethodType": ["CreditCard","GooglePay"],
"GooglePayMerchantId": "GPAY_MERCHANT_ID",
"GooglePayMerchantName": "Your Store",
"TokenRetrievalRequired": true,
"AccountAddressCollectionMode": "Full",
"ValidateAccountSecurityCode": true,
"ValidateAccountAddress": true
}""".formatted(expiry);
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(key);
signer.update(body.getBytes(StandardCharsets.UTF_8));
String xSig = HexFormat.of().formatHex(signer.sign()).toUpperCase();
HttpResponse<String> res = HttpClient.newHttpClient().send(
HttpRequest.newBuilder()
.uri(URI.create(HPP_BASE + "/v1.4/PaymentTransactionManagement/InitializeSession"))
.header("Content-Type", "application/json")
.header("X-CompanyNumber", COMPANY)
.header("X-StoreNumber", STORE)
.header("X-ReferenceId", UUID.randomUUID().toString().replace("-","").toUpperCase())
.header("X-Client-Application-Name", "MyApp")
.header("X-Signature", xSig)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build(),
HttpResponse.BodyHandlers.ofString()
);
{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestURL": "https://hpp.ncrvoyix.com/WebEPS/HPP?session=45016f4cce57e5ab4e308a1822b9b9fc3336"
}
CompleteSession
Finalizes a payment session and captures the authorised funds. Call this from your server only after receiving a PAYMENT_RETURN postMessage with statusCode === 100. Must be called exactly once per session.
useRef boolean flag (completingRef.current) to ensure CompleteSession is called at most once. Calling it twice may cause a 409 conflict or duplicate charges.InitializeSession. Identifies which session to finalize. Store this server-side after InitializeSession — never expose it to the browser.WebEPSResponseCode for definitions.WebEPSResponseCode for definitions.TokenRetrievalRequired: true was set in InitializeSession.false.false.false.curl -X POST "https://seps1-rls.paymentslab.ncrvoyix.com/WebEPS/v1.4/PaymentTransactionManagement/CompleteSession" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: B2C3D4E5F6789012345678901234ABCD" \
-H "X-Signature: 7F2A9B3C1E..." \
-d '{
"SessionId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"RequestExpirationUTC": "2026-07-10T12:10:00.000Z"
}'
{
"TransactionStatus": "Approved",
"AuthorizationCode": "A12345",
"ReferenceNumber": "TXN-2026-001234",
"Token": "tok_xxxxxxxxxxxxxxxxxxxxxxxx",
"CardType": "Visa",
"Last4Digits": "4242"
}
const crypto = require('crypto');
const fs = require('fs');
const key = fs.readFileSync('./private.pem', 'utf8');
// completingRef guards against double-call (React StrictMode)
let completing = false;
async function completeSession(sessionId) {
if (completing) return;
completing = true;
try {
const payload = {
SessionId: sessionId,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const body = JSON.stringify(payload);
const sign = crypto.createSign('RSA-SHA256');
sign.update(body, 'utf8');
const xSig = sign.sign(
{ key, passphrase: process.env.KEY_PASS }, 'hex'
).toUpperCase();
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentTransactionManagement/CompleteSession`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Signature': xSig
},
body
}
);
return res.json();
} finally { completing = false; }
}
{
"TransactionStatus": "Approved",
"AuthorizationCode": "A12345",
"ReferenceNumber": "TXN-2026-001234",
"Token": "tok_xxxxxxxxxxxxxxxxxxxxxxxx",
"CardType": "Visa",
"Last4Digits": "4242"
}
def complete_session(session_id: str) -> dict:
payload = {
"SessionId": session_id,
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime('%Y-%m-%dT%H:%M:%S.000Z')
}
body = json.dumps(payload, separators=(',', ':'))
sig = pkey.sign(body.encode(), padding.PKCS1v15(), hashes.SHA256())
x_sig = sig.hex().upper()
resp = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentTransactionManagement/CompleteSession",
headers={
"Content-Type": "application/json",
"X-CompanyNumber": os.environ["COMPANY"],
"X-StoreNumber": os.environ["STORE"],
"X-ReferenceId": uuid.uuid4().hex.upper(),
"X-Signature": x_sig
},
data=body, timeout=30
)
return resp.json()
{
"TransactionStatus": "Approved",
"AuthorizationCode": "A12345",
"ReferenceNumber": "TXN-2026-001234",
"CardType": "Visa",
"Last4Digits": "4242"
}
public async Task<CompleteResponse> CompleteSessionAsync(string sessionId)
{
using var rsa = RSA.Create();
rsa.ImportFromEncryptedPem(File.ReadAllText("private.pem"), Env("KEY_PASS"));
var payload = new { SessionId = sessionId,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5)
.ToString("yyyy-MM-ddTHH:mm:ss.fffZ") };
var body = JsonSerializer.Serialize(payload);
var sigBytes = rsa.SignData(Encoding.UTF8.GetBytes(body),
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var xSig = Convert.ToHexString(sigBytes);
using var client = new HttpClient();
using var req = new HttpRequestMessage(HttpMethod.Post,
$"{Env("HPP_BASE")}/v1.4/PaymentTransactionManagement/CompleteSession");
req.Headers.TryAddWithoutValidation("X-CompanyNumber", Env("COMPANY"));
req.Headers.TryAddWithoutValidation("X-StoreNumber", Env("STORE"));
req.Headers.TryAddWithoutValidation("X-ReferenceId", Guid.NewGuid().ToString("N").ToUpper());
req.Headers.TryAddWithoutValidation("X-Signature", xSig);
req.Content = new StringContent(body, Encoding.UTF8, "application/json");
var res = await client.SendAsync(req);
return await res.Content.ReadFromJsonAsync<CompleteResponse>()!;
}
{
"TransactionStatus": "Approved",
"AuthorizationCode": "A12345",
"ReferenceNumber": "TXN-2026-001234",
"CardType": "Visa",
"Last4Digits": "4242"
}
public String completeSession(String sessionId) throws Exception {
String expiry = ZonedDateTime.now(ZoneOffset.UTC).plusMinutes(5)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
String body = String.format(
"{\"SessionId\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
sessionId, expiry);
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(privateKey);
signer.update(body.getBytes(StandardCharsets.UTF_8));
String xSig = HexFormat.of().formatHex(signer.sign()).toUpperCase();
return HttpClient.newHttpClient().send(
HttpRequest.newBuilder()
.uri(URI.create(HPP_BASE + "/v1.4/PaymentTransactionManagement/CompleteSession"))
.header("Content-Type", "application/json")
.header("X-CompanyNumber", COMPANY)
.header("X-StoreNumber", STORE)
.header("X-ReferenceId", UUID.randomUUID().toString().replace("-","").toUpperCase())
.header("X-Signature", xSig)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build(),
HttpResponse.BodyHandlers.ofString()
).body();
}
{
"TransactionStatus": "Approved",
"AuthorizationCode": "A12345",
"ReferenceNumber": "TXN-2026-001234",
"CardType": "Visa",
"Last4Digits": "4242"
}
ReverseTransaction
Reverses (voids) a previously authorised or completed transaction. Use for timeout scenarios where the session expired before CompleteSession was called, or for merchant-initiated voids. Uses the same signed-header model as the other endpoints.
ReferenceId of the authorization request.ReversalType "Timeout" will automatically be queued and retried.2026-07-10T12:10:00.000Z.curl -X POST "https://seps1-rls.paymentslab.ncrvoyix.com/WebEPS/v1.4/ReversalAdministration/ReverseTransaction" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: C3D4E5F6789012345678901234ABCDEF" \
-H "X-Signature: 2E8A4F..." \
-d '{
"OriginalReferenceId": "45016f4cce57e5ab4e308a1822b9b9fc3336",
"ReversalType": "timeout",
"RequestExpirationUTC": "2026-07-10T12:10:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TXN987",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-2026-001235",
"CardType": { "Type": "Credit", "Name": "Visa" },
"MerchantID": "MID-001",
"MerchantCategoryCode": "5411",
"NetworkID": "VISA",
"StoreNumber": 190,
"AuditId": 42,
"BusinessTransactionDate": "2026-07-14T12:05:00.000Z",
"CardProcId": "PROC-001",
"PaymentAccountReference": null,
"CreditToDebitConversionType": null,
"HostValues": {}
}
async function reverseTransaction(originalRefId, type = 'timeout') {
const payload = {
OriginalReferenceId: originalRefId,
ReversalType: type,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const body = JSON.stringify(payload);
const sign = crypto.createSign('RSA-SHA256');
sign.update(body, 'utf8');
const xSig = sign.sign(
{ key, passphrase: process.env.KEY_PASS }, 'hex'
).toUpperCase();
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/ReversalAdministration/ReverseTransaction`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Signature': xSig
},
body
}
);
return res.json();
}
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TXN987",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-2026-001235",
"CardType": { "Type": "Credit", "Name": "Visa" },
"MerchantID": "MID-001",
"MerchantCategoryCode": "5411",
"NetworkID": "VISA",
"StoreNumber": 190,
"AuditId": 42,
"BusinessTransactionDate": "2026-07-14T12:05:00.000Z",
"CardProcId": "PROC-001",
"PaymentAccountReference": null,
"CreditToDebitConversionType": null,
"HostValues": {}
}
def reverse_transaction(original_ref_id: str, reversal_type: str = "timeout") -> dict:
payload = {
"OriginalReferenceId": original_ref_id,
"ReversalType": reversal_type,
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime('%Y-%m-%dT%H:%M:%S.000Z')
}
body = json.dumps(payload, separators=(',', ':'))
sig = pkey.sign(body.encode(), padding.PKCS1v15(), hashes.SHA256())
x_sig = sig.hex().upper()
return requests.post(
f"{os.environ['HPP_BASE']}/v1.4/ReversalAdministration/ReverseTransaction",
headers={
"Content-Type": "application/json",
"X-CompanyNumber": os.environ["COMPANY"],
"X-StoreNumber": os.environ["STORE"],
"X-ReferenceId": uuid.uuid4().hex.upper(),
"X-Signature": x_sig
},
data=body, timeout=30
).json()
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TXN987",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-2026-001235",
"CardType": { "Type": "Credit", "Name": "Visa" },
"MerchantID": "MID-001",
"MerchantCategoryCode": "5411",
"NetworkID": "VISA",
"StoreNumber": 190,
"AuditId": 42,
"BusinessTransactionDate": "2026-07-14T12:05:00.000Z",
"CardProcId": "PROC-001",
"PaymentAccountReference": null,
"CreditToDebitConversionType": null,
"HostValues": {}
}
public async Task<string> ReverseTransactionAsync(string originalRefId, string type = "timeout")
{
using var rsa = RSA.Create();
rsa.ImportFromEncryptedPem(File.ReadAllText("private.pem"), Env("KEY_PASS"));
var payload = new { OriginalReferenceId = originalRefId, ReversalType = type,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss.fffZ") };
var body = JsonSerializer.Serialize(payload);
var sigBytes = rsa.SignData(Encoding.UTF8.GetBytes(body),
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var xSig = Convert.ToHexString(sigBytes);
using var client = new HttpClient();
using var req = new HttpRequestMessage(HttpMethod.Post,
$"{Env("HPP_BASE")}/v1.4/ReversalAdministration/ReverseTransaction");
req.Headers.TryAddWithoutValidation("X-CompanyNumber", Env("COMPANY"));
req.Headers.TryAddWithoutValidation("X-StoreNumber", Env("STORE"));
req.Headers.TryAddWithoutValidation("X-ReferenceId", Guid.NewGuid().ToString("N").ToUpper());
req.Headers.TryAddWithoutValidation("X-Signature", xSig);
req.Content = new StringContent(body, Encoding.UTF8, "application/json");
var res = await client.SendAsync(req);
return await res.Content.ReadAsStringAsync();
}
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TXN987",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-2026-001235",
"CardType": { "Type": "Credit", "Name": "Visa" },
"MerchantID": "MID-001",
"MerchantCategoryCode": "5411",
"NetworkID": "VISA",
"StoreNumber": 190,
"AuditId": 42,
"BusinessTransactionDate": "2026-07-14T12:05:00.000Z",
"CardProcId": "PROC-001",
"PaymentAccountReference": null,
"CreditToDebitConversionType": null,
"HostValues": {}
}
public String reverseTransaction(String originalRefId, String type) throws Exception {
String expiry = ZonedDateTime.now(ZoneOffset.UTC).plusMinutes(5)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
String body = String.format(
"{\"OriginalReferenceId\":\"%s\",\"ReversalType\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
originalRefId, type, expiry);
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(privateKey);
signer.update(body.getBytes(StandardCharsets.UTF_8));
String xSig = HexFormat.of().formatHex(signer.sign()).toUpperCase();
return HttpClient.newHttpClient().send(
HttpRequest.newBuilder()
.uri(URI.create(HPP_BASE + "/v1.4/ReversalAdministration/ReverseTransaction"))
.header("Content-Type", "application/json")
.header("X-CompanyNumber", COMPANY)
.header("X-StoreNumber", STORE)
.header("X-ReferenceId", UUID.randomUUID().toString().replace("-","").toUpperCase())
.header("X-Signature", xSig)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build(),
HttpResponse.BodyHandlers.ofString()
).body();
}
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TXN987",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-2026-001235",
"CardType": { "Type": "Credit", "Name": "Visa" },
"MerchantID": "MID-001",
"MerchantCategoryCode": "5411",
"NetworkID": "VISA",
"StoreNumber": 190,
"AuditId": 42,
"BusinessTransactionDate": "2026-07-14T12:05:00.000Z",
"CardProcId": "PROC-001",
"PaymentAccountReference": null,
"CreditToDebitConversionType": null,
"HostValues": {}
}
InitializeSessionKey (RFC4050XML)
Generates a symmetric session encryption key, wrapping it with the client's ECC public key supplied in RFC4050 XML format. The returned EncryptedSessionKey can decrypt subsequent AccountNumber and AccountSecurityCode fields in EncryptedPaymentAdministration calls.
SessionKeyFormat for definitions. Must be "RFC4050XML" for this variant.SessionKeyExchangeFormat for definitions.72.EncryptionInfo.EncryptionKeyId when using the Session Key for encryption.SessionKeyFormat for definitions.curl -X POST "$HPP_BASE/v1.4/EndpointAdministration/InitializeSessionKey" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"ClientPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ClientPublicKeyFormat": "RFC4050XML",
"ExchangeFormat": "ECDH",
"KeyDurationInHours": 72,
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"KeyId": "key-abc123",
"ServerPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ServerPublicKeyFormat": "RFC4050XML",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
async function initSessionKey(eccPublicKeyXml) {
const body = {
ClientPublicKey: eccPublicKeyXml,
ClientPublicKeyFormat: 'RFC4050XML',
ExchangeFormat: 'ECDH',
KeyDurationInHours: 72,
RequestExpirationUTC: new Date(Date.now() + 5 * 60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EndpointAdministration/InitializeSessionKey`,
{ method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Signature': signBody(body)
},
body: JSON.stringify(body) }
);
return res.json();
}
{
"KeyId": "key-abc123",
"ServerPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ServerPublicKeyFormat": "RFC4050XML",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
def init_session_key(ecc_public_key_xml: str) -> dict:
body = {
"ClientPublicKey": ecc_public_key_xml,
"ClientPublicKeyFormat": "RFC4050XML",
"ExchangeFormat": "ECDH",
"KeyDurationInHours": 72,
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime("%Y-%m-%dT%H:%M:%S.000Z")
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EndpointAdministration/InitializeSessionKey",
headers={
"Content-Type": "application/json",
"X-CompanyNumber": os.environ["COMPANY"],
"X-StoreNumber": os.environ["STORE"],
"X-ReferenceId": uuid.uuid4().hex.upper(),
"X-Signature": sign_body(body)
}, json=body)
r.raise_for_status()
return r.json()
{
"KeyId": "key-abc123",
"ServerPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ServerPublicKeyFormat": "RFC4050XML",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
var body = new { ClientPublicKey = eccPublicKeyXml,
ClientPublicKeyFormat = "RFC4050XML",
ExchangeFormat = "ECDH",
KeyDurationInHours = 72,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o") };
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EndpointAdministration/InitializeSessionKey", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsStringAsync();
{
"KeyId": "key-abc123",
"ServerPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ServerPublicKeyFormat": "RFC4050XML",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
String json = String.format(
"{\"ClientPublicKey\":\"%s\",\"ClientPublicKeyFormat\":\"RFC4050XML\"," +
"\"ExchangeFormat\":\"ECDH\",\"KeyDurationInHours\":72," +
"\"RequestExpirationUTC\":\"%s\"}", eccPublicKeyXml.replace("\"","\\\""),
Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/EndpointAdministration/InitializeSessionKey", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
{
"KeyId": "key-abc123",
"ServerPublicKey": "<ECDHKeyValue>...</ECDHKeyValue>",
"ServerPublicKeyFormat": "RFC4050XML",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
InitializeSessionKey (Base64MicrosoftECCBlob)
Alternative form of InitializeSessionKey using a Microsoft CNG ECC public key blob encoded as Base64. Use this variant on Windows/.NET platforms where CNG key export produces a BCRYPT_ECCPUBLIC_BLOB.
SessionKeyFormat for definitions. Must be "Base64MicrosoftECCBlob" for this variant.SessionKeyExchangeFormat for definitions.72.EncryptionInfo.EncryptionKeyId when using the Session Key for encryption.SessionKeyFormat for definitions.curl -X POST "$HPP_BASE/v1.4/EndpointAdministration/InitializeSessionKey" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"ClientPublicKey": "AQAB...BASE64BLOB==",
"ClientPublicKeyFormat": "Base64MicrosoftECCBlob",
"ExchangeFormat": "ECDH",
"KeyDurationInHours": 72,
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"KeyId": "key-abc123",
"ServerPublicKey": "AQAB...BASE64BLOB==",
"ServerPublicKeyFormat": "Base64MicrosoftECCBlob",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
async function initSessionKeyBlob(eccPublicKeyBase64) {
const body = {
ClientPublicKey: eccPublicKeyBase64,
ClientPublicKeyFormat: 'Base64MicrosoftECCBlob',
ExchangeFormat: 'ECDH',
KeyDurationInHours: 72,
RequestExpirationUTC: new Date(Date.now() + 5 * 60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EndpointAdministration/InitializeSessionKey`,
{ method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CompanyNumber': process.env.COMPANY,
'X-StoreNumber': process.env.STORE,
'X-ReferenceId': crypto.randomUUID().replace(/-/g,'').toUpperCase(),
'X-Signature': signBody(body)
},
body: JSON.stringify(body) }
);
return res.json();
}
{
"KeyId": "key-abc123",
"ServerPublicKey": "AQAB...BASE64BLOB==",
"ServerPublicKeyFormat": "Base64MicrosoftECCBlob",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
def init_session_key_blob(ecc_public_key_b64: str) -> dict:
body = {
"ClientPublicKey": ecc_public_key_b64,
"ClientPublicKeyFormat": "Base64MicrosoftECCBlob",
"ExchangeFormat": "ECDH",
"KeyDurationInHours": 72,
"RequestExpirationUTC": (
datetime.now(timezone.utc) + timedelta(minutes=5)
).strftime("%Y-%m-%dT%H:%M:%S.000Z")
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EndpointAdministration/InitializeSessionKey",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
{
"KeyId": "key-abc123",
"ServerPublicKey": "AQAB...BASE64BLOB==",
"ServerPublicKeyFormat": "Base64MicrosoftECCBlob",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
// Export CNG key as Base64 blob
using var ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);
string blob = Convert.ToBase64String(
ecdh.PublicKey.ExportSubjectPublicKeyInfo());
var body = new { ClientPublicKey = blob,
ClientPublicKeyFormat = "Base64MicrosoftECCBlob",
ExchangeFormat = "ECDH",
KeyDurationInHours = 72,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o") };
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EndpointAdministration/InitializeSessionKey", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
{
"KeyId": "key-abc123",
"ServerPublicKey": "AQAB...BASE64BLOB==",
"ServerPublicKeyFormat": "Base64MicrosoftECCBlob",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
String json = String.format(
"{\"ClientPublicKey\":\"%s\",\"ClientPublicKeyFormat\":\"Base64MicrosoftECCBlob\"," +
"\"ExchangeFormat\":\"ECDH\",\"KeyDurationInHours\":72," +
"\"RequestExpirationUTC\":\"%s\"}", eccPublicKeyBase64,
Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/EndpointAdministration/InitializeSessionKey", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
{
"KeyId": "key-abc123",
"ServerPublicKey": "AQAB...BASE64BLOB==",
"ServerPublicKeyFormat": "Base64MicrosoftECCBlob",
"KeyExpirationUTC": "2026-07-16T12:05:00.000Z"
}
InitializeSession (EndpointAdministration)
Creates a new payment session from the server side using stored endpoint credentials. Unlike PaymentTransactionManagement/InitializeSession, this variant is intended for server-initiated flows and returns a SessionId without HPP interaction.
false response means the endpoint needs to be provisioned by calling one of the registration methods.curl -X POST "$HPP_BASE/v1.4/EndpointAdministration/InitializeSession" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z"
}'
{
"IsValid": true,
"KeyExpirationUTC": "2026-07-11T12:05:00.000Z"
}
async function initEndpointSession() {
const body = { RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString() };
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EndpointAdministration/InitializeSession`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsValid: true, KeyExpirationUTC: "2026-07-11T12:05:00.000Z" }
def endpoint_init_session() -> dict:
body = {"RequestExpirationUTC": utc_plus(5)}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EndpointAdministration/InitializeSession",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsValid": True, "KeyExpirationUTC": "2026-07-11T12:05:00.000Z"}
var body = new { RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o") };
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EndpointAdministration/InitializeSession", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { "IsValid": true, "KeyExpirationUTC": "2026-07-11T12:05:00.000Z" }
String json = String.format(
"{\"RequestExpirationUTC\":\"%s\"}", Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/EndpointAdministration/InitializeSession", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsValid":true,"KeyExpirationUTC":"2026-07-11T12:05:00.000Z"}
GetReceiptTemplates
Returns the configured receipt templates for a given company and store. Templates define the print layout for customer and merchant copies of transaction receipts.
ReceiptTemplateLastModifiedAtUTC during initialization.curl -X POST "$HPP_BASE/v1.4/EndpointAdministration/GetReceiptTemplates" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{ "RequestExpirationUTC": "2026-07-10T12:05:00.000Z" }'
{
"Footer": "Thank you for your purchase!",
"Header": "ACME Store - 123 Main St",
"LastModifiedAtUTC": "2026-06-01T00:00:00.000Z",
"Templates": {
"Receipt": {
"CustomerCopy": [ { "Line": "{{MerchantName}}", "Format": "Center" } ],
"MerchantCopy": [ { "Line": "{{MerchantName}}", "Format": "Center" } ]
}
}
}
async function getReceiptTemplates() {
const body = { RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString() };
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EndpointAdministration/GetReceiptTemplates`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { Footer, Header, LastModifiedAtUTC, Templates }
def get_receipt_templates() -> dict:
body = {"RequestExpirationUTC": utc_plus(5)}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EndpointAdministration/GetReceiptTemplates",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"Footer": "...", "Header": "...", "LastModifiedAtUTC": "...", "Templates": {...}}
var body = new { RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o") };
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EndpointAdministration/GetReceiptTemplates", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { Footer, Header, LastModifiedAtUTC, Templates }
return await resp.Content.ReadAsStringAsync();
String json = String.format("{\"RequestExpirationUTC\":\"%s\"}",
Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/EndpointAdministration/GetReceiptTemplates", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"Footer":"...","Header":"...","LastModifiedAtUTC":"...","Templates":{...}}
PurchaseForToken
Processes a purchase transaction using a stored payment token. The token references a previously stored card and removes the need to transmit full PAN data. Use for repeat or subscription billing scenarios.
ValidateAccountSecurityCode is set to true.false."USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service."Credit". See TenderType for definitions.false.false.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/PurchaseForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 1200,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"HostRetrievalNumber": "123456789012",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1,
"ApprovedAmount": 1200,
"AccountNumberLastFour": "1234",
"Tokens": []
}
async function purchaseForToken(tokenValue, amount, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/PurchaseForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, CardType, MerchantID, NetworkID, StoreNumber, Tokens }
def purchase_for_token(token_value: str, amount: int, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/PurchaseForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/PurchaseForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, Tokens, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/PurchaseForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
VoidPurchaseForToken
Voids a previously authorised token-based purchase before settlement. The original transaction must be unsettled. Provide the OriginalReferenceId returned from the PurchaseForToken call.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."Credit". See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/VoidPurchaseForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 1200,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 1200,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 1200,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function voidPurchaseForToken(tokenValue, amount, originalReferenceId, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, OriginalReferenceId: originalReferenceId,
OriginalAmount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/VoidPurchaseForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def void_purchase_for_token(token_value: str, amount: int,
original_ref: str, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "OriginalReferenceId": original_ref,
"OriginalAmount": amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/VoidPurchaseForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, OriginalReferenceId = originalReferenceId,
OriginalAmount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/VoidPurchaseForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"OriginalReferenceId\":\"%s\",\"OriginalAmount\":%d," +
"\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, originalRefId, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/VoidPurchaseForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
RefundForToken
Issues a refund against a settled token-based purchase. The refund amount can be partial or full. Provide the original transaction reference and the token used.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service."Credit". See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/RefundForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 1200,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 1200,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"HostRetrievalNumber": "123456789012",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function refundForToken(tokenValue, amount, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/RefundForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def refund_for_token(token_value: str, amount: int, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/RefundForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/RefundForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/RefundForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
VoidRefundForToken
Cancels an unsettled token-based refund. Must be called before the refund batch closes. Provide the reference ID from the original RefundForToken response.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."Credit". See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/VoidRefundForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 1200,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 1200,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 1200,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function voidRefundForToken(tokenValue, amount, originalReferenceId, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, OriginalReferenceId: originalReferenceId,
OriginalAmount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/VoidRefundForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def void_refund_for_token(token_value: str, amount: int,
original_ref: str, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "OriginalReferenceId": original_ref,
"OriginalAmount": amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/VoidRefundForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, OriginalReferenceId = originalReferenceId,
OriginalAmount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/VoidRefundForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"OriginalReferenceId\":\"%s\",\"OriginalAmount\":%d," +
"\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, originalRefId, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/VoidRefundForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
PreauthorizeForToken
Places a hold on funds for a token-based card without capturing. Follow with CompleteAuthorizationForToken to capture, or VoidPreauthorizeForToken to release the hold.
ValidateAccountSecurityCode is set to true.false."USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service."Credit". See TenderType for definitions.false.false.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/PreauthorizeForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 5000,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 5000,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"AccountNumberLastFour": "1234",
"HostRetrievalNumber": "123456789012",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1,
"Tokens": []
}
async function preauthorizeForToken(tokenValue, amount, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/PreauthorizeForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, Tokens, ... }
def preauthorize_for_token(token_value: str, amount: int, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "TenderType": "Credit", "EntryMode": "ComputerOrder",
"ExpirationDate": expiry, "RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/PreauthorizeForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/PreauthorizeForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, Tokens, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/PreauthorizeForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123","Tokens":[],...}
VoidPreauthorizeForToken
Releases a fund hold placed by PreauthorizeForToken. Use when the pre-authorised transaction will not be captured.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."Credit". See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/VoidPreauthorizeForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 5000,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 5000,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 5000,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function voidPreauthorizeForToken(tokenValue, amount, originalReferenceId, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, OriginalReferenceId: originalReferenceId,
OriginalAmount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/VoidPreauthorizeForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def void_preauthorize_for_token(token_value: str, amount: int,
original_ref: str, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "OriginalReferenceId": original_ref,
"OriginalAmount": amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/VoidPreauthorizeForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, OriginalReferenceId = originalReferenceId,
OriginalAmount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/VoidPreauthorizeForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"OriginalReferenceId\":\"%s\",\"OriginalAmount\":%d," +
"\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, originalRefId, amount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/VoidPreauthorizeForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
CompleteAuthorizationForToken
Captures a pre-authorised token-based transaction. The capture amount can equal or be less than the pre-auth amount. Provide the OriginalReferenceId from the PreauthorizeForToken response.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."Credit". See TenderType for definitions.false.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/CompleteAuthorizationForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 4800,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 5000,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 4800,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"HostRetrievalNumber": "123456789012",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function completeAuthForToken(tokenValue, amount, originalReferenceId,
originalAmount, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, OriginalReferenceId: originalReferenceId,
OriginalAmount: originalAmount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/CompleteAuthorizationForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def complete_auth_for_token(token_value: str, amount: int, original_ref: str,
original_amount: int, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "OriginalReferenceId": original_ref,
"OriginalAmount": original_amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/CompleteAuthorizationForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/CompleteAuthorizationForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"OriginalReferenceId\":\"%s\",\"OriginalAmount\":%d," +
"\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, originalRefId, originalAmount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/CompleteAuthorizationForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "AUTH12",
"HostRetrievalNumber": "123456",
"RetrievalReferenceNumber": "RRN-001",
"CardType": { "Type": "Credit", "Name": "Visa" },
"AuditId": 42,
"StoreNumber": 190
}
VoidCompleteAuthorizationForToken
Voids a captured token-based authorization before settlement. Provide the reference ID from the CompleteAuthorizationForToken response.
"USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."Credit". See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/PaymentAdministration/VoidCompleteAuthorizationForToken" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Token": { "TokenType": "201", "TokenValue": "371449551708431" },
"Amount": 4800,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 5000,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-15T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "TAS123",
"AuditId": 123456,
"ApprovedAmount": 4800,
"BusinessTransactionDate": "2026-07-15T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "123456789012",
"StoreNumber": 1
}
async function voidCompleteAuthForToken(tokenValue, amount, originalReferenceId,
originalAmount, expiry) {
const body = {
Token: { TokenType: '201', TokenValue: tokenValue },
Amount: amount, OriginalReferenceId: originalReferenceId,
OriginalAmount: originalAmount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/PaymentAdministration/VoidCompleteAuthorizationForToken`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, CardType, MerchantID, ... }
def void_complete_auth_for_token(token_value: str, amount: int, original_ref: str,
original_amount: int, expiry: str) -> dict:
body = {
"Token": {"TokenType": "201", "TokenValue": token_value},
"Amount": amount, "OriginalReferenceId": original_ref,
"OriginalAmount": original_amount, "TenderType": "Credit",
"EntryMode": "ComputerOrder", "ExpirationDate": expiry,
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/PaymentAdministration/VoidCompleteAuthorizationForToken",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS123", ...}
var body = new {
Token = new { TokenType = "201", TokenValue = tokenValue },
Amount = amount, OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/PaymentAdministration/VoidCompleteAuthorizationForToken", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, ... }
String json = String.format(
"{\"Token\":{\"TokenType\":\"201\",\"TokenValue\":\"%s\"}," +
"\"Amount\":%d,\"OriginalReferenceId\":\"%s\",\"OriginalAmount\":%d," +
"\"TenderType\":\"Credit\",\"EntryMode\":\"ComputerOrder\"," +
"\"ExpirationDate\":\"%s\",\"RequestExpirationUTC\":\"%s\"}",
tokenValue, amount, originalRefId, originalAmount, expiry, Instant.now().plusSeconds(300));
HttpRequest req = buildSignedRequest(
"/v1.4/PaymentAdministration/VoidCompleteAuthorizationForToken", json);
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS123",...}
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "Approved",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "AUTH12",
"AuditId": 42,
"StoreNumber": 190
}
Purchase (Encrypted)
Processes a purchase with an encrypted card number and security code. The card data must be encrypted using the AES session key obtained from InitializeSessionKey. No plain-text PAN is transmitted.
EncryptionType, EncryptionKeyId, EncryptionAlgorithm, EncryptionInitializationVector, and EncryptedValue.AccountNumber. Required when ValidateAccountSecurityCode is true.false."USD"."ComputerOrder" in Server auth mode.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, or Service."Credit". See TenderType for definitions.false.false.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/Purchase" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"AccountNumber": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_PAN=="
},
"AccountSecurityCode": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_CVV=="
},
"Amount": 2500,
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "TAS456",
"AuditId": 234567,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"HostRetrievalNumber": "234567890123",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "234567890123",
"StoreNumber": 1,
"ApprovedAmount": 2500,
"AccountNumberFirstSix": "411111",
"AccountNumberLastFour": "1111",
"Tokens": []
}
async function encPurchase(encPan, encCvv, keyId, amount, expiry) {
const encObj = (encVal) => ({
EncryptionType: 'SessionKey', EncryptionKeyId: keyId,
EncryptionAlgorithm: 'AES128',
EncryptionInitializationVector: encVal.iv,
EncryptedValue: encVal.data
});
const body = {
AccountNumber: encObj(encPan), AccountSecurityCode: encObj(encCvv),
Amount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/Purchase`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, CardType, MerchantID, Tokens, ... }
def enc_obj(encrypted_value: str, iv: str, key_id: str) -> dict:
return {"EncryptionType": "SessionKey", "EncryptionKeyId": key_id,
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": iv, "EncryptedValue": encrypted_value}
def enc_purchase(enc_pan, enc_cvv, key_id: str, amount: int, expiry: str) -> dict:
body = {
"AccountNumber": enc_obj(enc_pan["data"], enc_pan["iv"], key_id),
"AccountSecurityCode": enc_obj(enc_cvv["data"], enc_cvv["iv"], key_id),
"Amount": amount, "TenderType": "Credit", "EntryMode": "ComputerOrder",
"ExpirationDate": expiry, "RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/Purchase",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AuthorizationCode": "TAS456", ...}
object EncObj(string val, string iv, string kid) => new {
EncryptionType = "SessionKey", EncryptionKeyId = kid,
EncryptionAlgorithm = "AES128",
EncryptionInitializationVector = iv, EncryptedValue = val };
var body = new {
AccountNumber = EncObj(encPan, panIv, keyId),
AccountSecurityCode = EncObj(encCvv, cvvIv, keyId),
Amount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/Purchase", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, Tokens, ... }
// Use a JSON library (e.g. Jackson) to build the encrypted payload
ObjectNode body = mapper.createObjectNode();
body.set("AccountNumber", encryptedField(encPan, panIv, keyId));
body.set("AccountSecurityCode", encryptedField(encCvv, cvvIv, keyId));
body.put("Amount", amount).put("TenderType", "Credit")
.put("EntryMode", "ComputerOrder").put("ExpirationDate", expiry)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString());
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/Purchase", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AuthorizationCode":"TAS456",...}
VoidPurchase (Encrypted)
Voids an unsettled encrypted purchase transaction. Provide the reference ID and other transaction details returned from the Purchase response.
Purchase response.Purchase response.Purchase response.Purchase response.Purchase response.Purchase response.Purchase response.Purchase response."USD"."ComputerOrder".MMYY or MMYYYY format."Credit".curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/VoidPurchase" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 2500,
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"OriginalAmount": 2500,
"OriginalApprovalCode": "TAS456",
"OriginalAuditId": 234567,
"OriginalBusinessTransactionDate": "2026-07-10T12:00:00.000Z",
"OriginalHostResponseCode": "00",
"OriginalRetrievalReferenceNumber": "234567890123"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "TAS456",
"AuditId": 234568,
"BusinessTransactionDate": "2026-07-10T12:06:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1
}
async function encVoidPurchase(originalReferenceId, amount, originalData) {
const body = {
Amount: amount,
OriginalReferenceId: originalReferenceId,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
OriginalAmount: originalData.amount,
OriginalApprovalCode: originalData.approvalCode,
OriginalAuditId: originalData.auditId,
OriginalBusinessTransactionDate: originalData.businessDate,
OriginalHostResponseCode: originalData.hostResponseCode,
OriginalRetrievalReferenceNumber: originalData.retrievalReferenceNumber
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/VoidPurchase`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, CardType, ... }
def enc_void_purchase(original_ref: str, amount: int, original_data: dict) -> dict:
body = {
"Amount": amount,
"OriginalReferenceId": original_ref,
"RequestExpirationUTC": utc_plus(5),
"OriginalAmount": original_data["amount"],
"OriginalApprovalCode": original_data["approval_code"],
"OriginalAuditId": original_data["audit_id"],
"OriginalBusinessTransactionDate": original_data["business_date"],
"OriginalHostResponseCode": original_data["host_response_code"],
"OriginalRetrievalReferenceNumber": original_data["retrieval_ref"]
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/VoidPurchase",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", "AuthorizationCode": "TAS456", ...}
var body = new {
Amount = amount,
OriginalReferenceId = originalReferenceId,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
OriginalAmount = originalAmount,
OriginalApprovalCode = originalApprovalCode,
OriginalAuditId = originalAuditId,
OriginalBusinessTransactionDate = originalBusinessDate,
OriginalHostResponseCode = originalHostResponseCode,
OriginalRetrievalReferenceNumber = originalRetrievalRef
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/VoidPurchase", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("OriginalReferenceId", originalReferenceId)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("OriginalAmount", originalAmount)
.put("OriginalApprovalCode", originalApprovalCode)
.put("OriginalAuditId", originalAuditId)
.put("OriginalBusinessTransactionDate", originalBusinessDate)
.put("OriginalHostResponseCode", originalHostResponseCode)
.put("OriginalRetrievalReferenceNumber", originalRetrievalRef);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/VoidPurchase", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"TAS456",...}
Refund (Encrypted)
Issues a refund against a settled encrypted purchase. The card data must be re-submitted encrypted. Refunds can be partial or full.
"ComputerOrder" in Server mode. See EntryMode for definitions.MMYY or MMYYYY format. Required when submitting to a financial host.Convenience, Surcharge, Service.Initial, Subsequent."USD".BenefitsProgram."Credit". See TenderType for definitions.true, the operation fails when a token cannot be retrieved. Default: false.BenefitsProgram.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/Refund" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"AccountNumber": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_PAN=="
},
"Amount": 2500,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"AuthorizationCode": "REF789",
"AuditId": 345678,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1,
"ApprovedAmount": 2500,
"AccountNumberFirstSix": "411111",
"AccountNumberLastFour": "1111",
"Tokens": []
}
async function encRefund(encPan, keyId, amount, expiry) {
const body = {
AccountNumber: { EncryptionType: 'SessionKey', EncryptionKeyId: keyId,
EncryptionAlgorithm: 'AES128',
EncryptionInitializationVector: encPan.iv, EncryptedValue: encPan.data },
Amount: amount, TenderType: 'Credit', EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/Refund`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AuthorizationCode, AuditId, ApprovedAmount, Tokens, ... }
def enc_refund(enc_pan, key_id: str, amount: int, expiry: str) -> dict:
body = {
"AccountNumber": enc_obj(enc_pan["data"], enc_pan["iv"], key_id),
"Amount": amount, "TenderType": "Credit", "EntryMode": "ComputerOrder",
"ExpirationDate": expiry, "RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/Refund",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "ApprovedAmount": 2500, ...}
var body = new {
AccountNumber = EncObj(encPan, panIv, keyId),
Amount = amount, TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/Refund", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AuthorizationCode, ApprovedAmount, Tokens, ... }
ObjectNode body = mapper.createObjectNode();
body.set("AccountNumber", encryptedField(encPan, panIv, keyId));
body.put("Amount", amount).put("TenderType", "Credit")
.put("EntryMode", "ComputerOrder").put("ExpirationDate", expiry)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString());
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/Refund", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","ApprovedAmount":2500,...}
VoidRefund (Encrypted)
Cancels an unsettled encrypted refund transaction before it is batched.
ComputerOrder when using Server authentication mode.MMYY or MMYYYY format. Required when submitting a transaction to a financial Host.Convenience, Surcharge, Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."USD".Credit.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/VoidRefund" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 2500,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 2500,
"OriginalAuthorizationCode": "REF789",
"OriginalAuditId": 345678,
"OriginalDateTimeUTC": "2026-07-10T12:00:00.0000000Z",
"OriginalHostResponseCode": "00",
"OriginalRetrievalReferenceNumber": "345678901234"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "REF789",
"AuditId": 345679,
"BusinessTransactionDate": "2026-07-10T12:06:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1
}
async function encVoidRefund(originalReferenceId, amount, originalData) {
const body = {
Amount: amount,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
OriginalReferenceId: originalReferenceId,
OriginalAmount: originalData.amount,
OriginalAuthorizationCode: originalData.authorizationCode,
OriginalAuditId: originalData.auditId,
OriginalDateTimeUTC: originalData.dateTimeUTC,
OriginalHostResponseCode: originalData.hostResponseCode,
OriginalRetrievalReferenceNumber: originalData.retrievalReferenceNumber
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/VoidRefund`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, CardType, ... }
def enc_void_refund(original_ref: str, amount: int, original_data: dict) -> dict:
body = {
"Amount": amount,
"RequestExpirationUTC": utc_plus(5),
"OriginalReferenceId": original_ref,
"OriginalAmount": original_data["amount"],
"OriginalAuthorizationCode": original_data["authorization_code"],
"OriginalAuditId": original_data["audit_id"],
"OriginalDateTimeUTC": original_data["date_time_utc"],
"OriginalHostResponseCode": original_data["host_response_code"],
"OriginalRetrievalReferenceNumber": original_data["retrieval_ref"]
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/VoidRefund",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", ...}
var body = new {
Amount = amount,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount,
OriginalAuthorizationCode = originalAuthorizationCode,
OriginalAuditId = originalAuditId,
OriginalDateTimeUTC = originalDateTimeUTC,
OriginalHostResponseCode = originalHostResponseCode,
OriginalRetrievalReferenceNumber = originalRetrievalRef
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/VoidRefund", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("OriginalReferenceId", originalReferenceId)
.put("OriginalAmount", originalAmount)
.put("OriginalAuthorizationCode", originalAuthorizationCode)
.put("OriginalAuditId", originalAuditId)
.put("OriginalDateTimeUTC", originalDateTimeUTC)
.put("OriginalHostResponseCode", originalHostResponseCode)
.put("OriginalRetrievalReferenceNumber", originalRetrievalRef);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/VoidRefund", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"REF789",...}
Preauthorize (Encrypted)
Places a hold on funds using an encrypted card number. Follow with CompleteAuthorization to capture, or VoidPreauthorization to release.
ComputerOrder when using Server authentication mode. See EntryMode for definitions.MMYY or MMYYYY format. Required when submitting a transaction to a financial Host.Convenience, Surcharge, Service.false.Initial, Subsequent."USD".Credit. See TenderType for definitions.true will fail the operation if a Token cannot be retrieved. Default: false.false.false.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/Preauthorize" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 10000,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240",
"AccountNumber": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_PAN=="
},
"TenderType": "Credit"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"ApprovedAmount": 10000,
"AuthorizationCode": "AUTH001",
"AuditId": 456789,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"AccountNumberFirstSix": "411111",
"AccountNumberLastFour": "1111",
"HostRetrievalNumber": "456789012345",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "456789012345",
"StoreNumber": 1,
"Tokens": []
}
async function encPreauthorize(encPan, keyId, amount, expiry) {
const body = {
Amount: amount,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
EntryMode: 'ComputerOrder',
ExpirationDate: expiry,
AccountNumber: { EncryptionType: 'SessionKey', EncryptionKeyId: keyId,
EncryptionAlgorithm: 'AES128',
EncryptionInitializationVector: encPan.iv, EncryptedValue: encPan.data },
TenderType: 'Credit'
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/Preauthorize`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, ApprovedAmount, Tokens, ... }
def enc_preauthorize(enc_pan, key_id: str, amount: int, expiry: str) -> dict:
body = {
"Amount": amount,
"RequestExpirationUTC": utc_plus(5),
"EntryMode": "ComputerOrder",
"ExpirationDate": expiry,
"AccountNumber": enc_obj(enc_pan["data"], enc_pan["iv"], key_id),
"TenderType": "Credit"
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/Preauthorize",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None",
# "AuthorizationCode": "AUTH001", "ApprovedAmount": 10000, ...}
var body = new {
Amount = amount,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
EntryMode = "ComputerOrder",
ExpirationDate = expiry,
AccountNumber = EncObj(encPan, panIv, keyId),
TenderType = "Credit"
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/Preauthorize", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, VerificationMethod, AuthorizationCode, ApprovedAmount, Tokens, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("EntryMode", "ComputerOrder")
.put("ExpirationDate", expiry)
.put("TenderType", "Credit");
body.set("AccountNumber", encryptedField(encPan, panIv, keyId));
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/Preauthorize", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"AUTH001",...}
VoidPreauthorization (Encrypted)
Releases a fund hold placed by an encrypted Preauthorize call.
ComputerOrder when using Server authentication mode. See EntryMode for definitions.MMYY or MMYYYY format. Required when submitting a transaction to a financial Host.Convenience, Surcharge, Service.yyyy-MM-ddTHH:mm:ss.fffffffZ."USD".Credit. See TenderType for definitions.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/VoidPreauthorization" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \ -H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 10000,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 10000,
"OriginalAuthorizationCode": "AUTH001",
"OriginalAuditId": 456789,
"OriginalDateTimeUTC": "2026-07-10T12:00:00.0000000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "AUTH001",
"AuditId": 456790,
"BusinessTransactionDate": "2026-07-10T12:06:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1
}
async function encVoidPreauthorization(originalReferenceId, amount, originalData) {
const body = {
Amount: amount,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
OriginalReferenceId: originalReferenceId,
OriginalAmount: originalData.amount,
OriginalAuthorizationCode: originalData.authorizationCode,
OriginalAuditId: originalData.auditId,
OriginalDateTimeUTC: originalData.dateTimeUTC
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/VoidPreauthorization`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, CardType, ... }
def enc_void_preauthorization(original_ref: str, amount: int, original_data: dict) -> dict:
body = {
"Amount": amount,
"RequestExpirationUTC": utc_plus(5),
"OriginalReferenceId": original_ref,
"OriginalAmount": original_data["amount"],
"OriginalAuthorizationCode": original_data["authorization_code"],
"OriginalAuditId": original_data["audit_id"],
"OriginalDateTimeUTC": original_data["date_time_utc"]
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/VoidPreauthorization",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", ...}
var body = new {
Amount = amount,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount,
OriginalAuthorizationCode = originalAuthorizationCode,
OriginalAuditId = originalAuditId,
OriginalDateTimeUTC = originalDateTimeUTC
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/VoidPreauthorization", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("OriginalReferenceId", originalReferenceId)
.put("OriginalAmount", originalAmount)
.put("OriginalAuthorizationCode", originalAuthorizationCode)
.put("OriginalAuditId", originalAuditId)
.put("OriginalDateTimeUTC", originalDateTimeUTC);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/VoidPreauthorization", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"AUTH001",...}
CompleteAuthorization (Encrypted)
Captures an encrypted pre-authorised transaction. The capture amount can equal or be less than the original pre-auth amount.
ComputerOrder when using Server authentication mode. See EntryMode for definitions.MMYY or MMYYYY format. Required when submitting a transaction to a financial Host.Convenience, Surcharge, Service.yyyy-MM-ddTHH:mm:ss.fffffffZ.Initial, Subsequent."USD".Credit. See TenderType for definitions.true will fail the operation if a Token cannot be retrieved. Default: false.false.false.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/CompleteAuthorization" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \ -H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 9500,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 10000,
"OriginalAuthorizationCode": "AUTH001",
"OriginalAuditId": 456789,
"OriginalDateTimeUTC": "2026-07-10T12:00:00.0000000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"ApprovedAmount": 9500,
"AuthorizationCode": "CAP002",
"AuditId": 567890,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"HostRetrievalNumber": "567890123456",
"MerchantID": "MERCH001",
"NetworkID": "NET01",
"RetrievalReferenceNumber": "567890123456",
"StoreNumber": 1,
"Tokens": []
}
async function encCompleteAuthorization(originalReferenceId, amount, originalData) {
const body = {
Amount: amount,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
OriginalReferenceId: originalReferenceId,
OriginalAmount: originalData.amount,
OriginalAuthorizationCode: originalData.authorizationCode,
OriginalAuditId: originalData.auditId,
OriginalDateTimeUTC: originalData.dateTimeUTC
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/CompleteAuthorization`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, ApprovedAmount, Tokens, ... }
def enc_complete_authorization(original_ref: str, amount: int, original_data: dict) -> dict:
body = {
"Amount": amount,
"RequestExpirationUTC": utc_plus(5),
"OriginalReferenceId": original_ref,
"OriginalAmount": original_data["amount"],
"OriginalAuthorizationCode": original_data["authorization_code"],
"OriginalAuditId": original_data["audit_id"],
"OriginalDateTimeUTC": original_data["date_time_utc"]
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/CompleteAuthorization",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", "ApprovedAmount": 9500, ...}
var body = new {
Amount = amount,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount,
OriginalAuthorizationCode = originalAuthorizationCode,
OriginalAuditId = originalAuditId,
OriginalDateTimeUTC = originalDateTimeUTC
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/CompleteAuthorization", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ApprovedAmount, Tokens, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("OriginalReferenceId", originalReferenceId)
.put("OriginalAmount", originalAmount)
.put("OriginalAuthorizationCode", originalAuthorizationCode)
.put("OriginalAuditId", originalAuditId)
.put("OriginalDateTimeUTC", originalDateTimeUTC);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/CompleteAuthorization", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"CAP002",...}
VoidCompleteAuthorization (Encrypted)
Voids a captured encrypted authorization before settlement. Provide the reference ID from CompleteAuthorization.
ComputerOrder when using Server authentication mode.yyyy-MM-ddTHH:mm:ss.fffffffZ."USD".Credit.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/VoidCompleteAuthorization" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \ -H "X-Signature: $SIGNATURE" \
-d '{
"Amount": 9500,
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"OriginalReferenceId": "c7b716bb-1234-5678-abcd-ef0123456789",
"OriginalAmount": 9500,
"OriginalAuthorizationCode": "CAP002",
"OriginalAuditId": 567890,
"OriginalDateTimeUTC": "2026-07-10T12:05:00.0000000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "CAP002",
"AuditId": 567891,
"BusinessTransactionDate": "2026-07-10T12:06:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1
}
async function encVoidCompleteAuthorization(originalReferenceId, amount, originalData) {
const body = {
Amount: amount,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString(),
OriginalReferenceId: originalReferenceId,
OriginalAmount: originalData.amount,
OriginalAuthorizationCode: originalData.authorizationCode,
OriginalAuditId: originalData.auditId,
OriginalDateTimeUTC: originalData.dateTimeUTC
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/VoidCompleteAuthorization`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, CardType, ... }
def enc_void_complete_authorization(original_ref: str, amount: int, original_data: dict) -> dict:
body = {
"Amount": amount,
"RequestExpirationUTC": utc_plus(5),
"OriginalReferenceId": original_ref,
"OriginalAmount": original_data["amount"],
"OriginalAuthorizationCode": original_data["authorization_code"],
"OriginalAuditId": original_data["audit_id"],
"OriginalDateTimeUTC": original_data["date_time_utc"]
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/VoidCompleteAuthorization",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", ...}
var body = new {
Amount = amount,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o"),
OriginalReferenceId = originalReferenceId,
OriginalAmount = originalAmount,
OriginalAuthorizationCode = originalAuthorizationCode,
OriginalAuditId = originalAuditId,
OriginalDateTimeUTC = originalDateTimeUTC
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/VoidCompleteAuthorization", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ... }
ObjectNode body = mapper.createObjectNode();
body.put("Amount", amount)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString())
.put("OriginalReferenceId", originalReferenceId)
.put("OriginalAmount", originalAmount)
.put("OriginalAuthorizationCode", originalAuthorizationCode)
.put("OriginalAuditId", originalAuditId)
.put("OriginalDateTimeUTC", originalDateTimeUTC);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/VoidCompleteAuthorization", mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"CAP002",...}
BalanceInquiry (Encrypted)
Queries the available balance for an encrypted card (e.g. prepaid or gift cards). The card PAN and security code must be encrypted using the session key.
EncryptionType, EncryptionKeyId, EncryptionAlgorithm, EncryptionInitializationVector, and EncryptedValue.ValidateAccountSecurityCode is true."ComputerOrder".MMYY or MMYYYY format."Credit", "Debit", or "Gift". Default: "Credit".false.curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/BalanceInquiry" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"AccountNumber": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_PAN=="
},
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"TenderType": "Gift",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL", "HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AvailableBalance": 5000,
"AuditId": 678901,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Gift",
"MerchantID": "MERCH001",
"StoreNumber": 1,
"AccountNumberFirstSix": "603144",
"AccountNumberLastFour": "5678"
}
async function encBalanceInquiry(encPan, keyId, tenderType, expiry) {
const body = {
AccountNumber: { EncryptionType: 'SessionKey', EncryptionKeyId: keyId,
EncryptionAlgorithm: 'AES128',
EncryptionInitializationVector: encPan.iv, EncryptedValue: encPan.data },
TenderType: tenderType, EntryMode: 'ComputerOrder', ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/BalanceInquiry`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// AvailableBalance, CardType, ... }
def enc_balance_inquiry(enc_pan, key_id: str, tender_type: str, expiry: str) -> dict:
body = {
"AccountNumber": enc_obj(enc_pan["data"], enc_pan["iv"], key_id),
"TenderType": tender_type, "EntryMode": "ComputerOrder",
"ExpirationDate": expiry, "RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/BalanceInquiry",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "AvailableBalance": 5000, ...}
var body = new {
AccountNumber = EncObj(encPan, panIv, keyId),
TenderType = tenderType, EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/BalanceInquiry", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, AvailableBalance, ... }
ObjectNode body = mapper.createObjectNode();
body.set("AccountNumber", encryptedField(encPan, panIv, keyId));
body.put("TenderType", tenderType).put("EntryMode", "ComputerOrder")
.put("ExpirationDate", expiry)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString());
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/BalanceInquiry",
mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","AvailableBalance":5000,...}
VoiceAuthorize (Encrypted)
Submits a voice-authorized transaction for settlement. Used when a merchant has obtained a verbal approval code via phone and needs to record it for batch processing. The card PAN is encrypted.
EncryptionType, EncryptionKeyId, EncryptionAlgorithm, EncryptionInitializationVector, and EncryptedValue."ComputerOrder".MMYY or MMYYYY format."Credit".curl -X POST "$HPP_BASE/v1.4/EncryptedPaymentAdministration/VoiceAuthorize" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"AccountNumber": {
"EncryptionType": "SessionKey",
"EncryptionKeyId": "YOUR_KEY_ID",
"EncryptionAlgorithm": "AES128",
"EncryptionInitializationVector": "BASE64_IV==",
"EncryptedValue": "BASE64_ENCRYPTED_PAN=="
},
"Amount": 3000,
"ApprovalCode": "VOICE123",
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z",
"TenderType": "Credit",
"EntryMode": "ComputerOrder",
"ExpirationDate": "1240"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"VerificationMethod": "None",
"AuthorizationCode": "VOICE123",
"AuditId": 789012,
"BusinessTransactionDate": "2026-07-10T12:05:00.000Z",
"CardType": "Visa",
"MerchantID": "MERCH001",
"StoreNumber": 1,
"ApprovedAmount": 3000,
"AccountNumberFirstSix": "411111",
"AccountNumberLastFour": "1111"
}
async function encVoiceAuthorize(encPan, keyId, amount, expiry, approvalCode) {
const body = {
AccountNumber: { EncryptionType: 'SessionKey', EncryptionKeyId: keyId,
EncryptionAlgorithm: 'AES128',
EncryptionInitializationVector: encPan.iv, EncryptedValue: encPan.data },
Amount: amount, ApprovalCode: approvalCode,
TenderType: 'Credit', EntryMode: 'ComputerOrder', ExpirationDate: expiry,
RequestExpirationUTC: new Date(Date.now() + 5*60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedPaymentAdministration/VoiceAuthorize`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// VerificationMethod, AuthorizationCode, AuditId, ApprovedAmount, ... }
def enc_voice_authorize(enc_pan, key_id: str, amount: int,
expiry: str, approval_code: str) -> dict:
body = {
"AccountNumber": enc_obj(enc_pan["data"], enc_pan["iv"], key_id),
"Amount": amount, "ApprovalCode": approval_code,
"TenderType": "Credit", "EntryMode": "ComputerOrder",
"ExpirationDate": expiry, "RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedPaymentAdministration/VoiceAuthorize",
headers=signed_headers(body), json=body)
r.raise_for_status(); return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "VerificationMethod": "None", "AuthorizationCode": "VOICE123", ...}
var body = new {
AccountNumber = EncObj(encPan, panIv, keyId),
Amount = amount, ApprovalCode = approvalCode,
TenderType = "Credit", EntryMode = "ComputerOrder",
ExpirationDate = expiry,
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedPaymentAdministration/VoiceAuthorize", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, VerificationMethod, AuthorizationCode, ApprovedAmount, ... }
ObjectNode body = mapper.createObjectNode();
body.set("AccountNumber", encryptedField(encPan, panIv, keyId));
body.put("Amount", amount).put("ApprovalCode", approvalCode)
.put("TenderType", "Credit").put("EntryMode", "ComputerOrder")
.put("ExpirationDate", expiry)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString());
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedPaymentAdministration/VoiceAuthorize",
mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","VerificationMethod":"None","AuthorizationCode":"VOICE123",...}
GetTokensForAuthenticatedPaymentData (EncryptedToken)
Exchanges an authenticated digital-wallet payment blob (Google Pay, Apple Pay) for a network payment token. The resulting token can be used in subsequent PaymentAdministration calls in place of a raw card number.
MMYY or MMYYYY format. Required when submitting a transaction to a financial host.curl -X POST "$HPP_BASE/v1.4/EncryptedTokenAdministration/GetTokensForAuthenticatedPaymentData" \
-H "Content-Type: application/json" \
-H "X-CompanyNumber: YOUR_COMPANY" \
-H "X-StoreNumber: YOUR_STORE" \
-H "X-ReferenceId: A1B2C3D4E5F6789012345678901234AB" \
-H "X-Signature: $SIGNATURE" \
-d '{
"ApplicationSource": 1,
"AuthenticatedPaymentDetails": {
"AuthenticatedPaymentType": "GOOGLEPAY",
"AuthenticatedPaymentBlob": "{\"signature\":\"...\",\"protocolVersion\":\"ECv2\",\"signedMessage\":\"...\"}"
},
"RequestExpirationUTC": "2026-07-10T12:05:00.000Z"
}'
{
"IsApproved": true,
"ResponseCode": "000",
"ResponseMessage": "APPROVAL",
"HostResponseCode": "00",
"HostType": 1,
"Tokens": [
{ "TokenType": "201", "TokenValue": "4111110123456789" }
],
"AccountNumberFirstSix": "411111",
"AccountNumberLastFour": "6789",
"AccountNumberLength": 16,
"AuditId": 678901,
"AuthorizationCode": "TOK001",
"CardType": "Visa",
"ExpirationDate": "1228",
"RetrievalReferenceNumber": "678901234567"
}
async function getTokensForWallet(paymentType, paymentBlob) {
const body = {
ApplicationSource: 1,
AuthenticatedPaymentDetails: {
AuthenticatedPaymentType: paymentType, // 'GOOGLEPAY' | 'APPLEPAY'
AuthenticatedPaymentBlob: JSON.stringify(paymentBlob)
},
RequestExpirationUTC: new Date(Date.now() + 5 * 60000).toISOString()
};
const res = await fetch(
`${process.env.HPP_BASE}/v1.4/EncryptedTokenAdministration/GetTokensForAuthenticatedPaymentData`,
{ method: 'POST', headers: signedHeaders(body), body: JSON.stringify(body) });
return res.json();
}
// Response: { IsApproved, ResponseCode, ResponseMessage, HostResponseCode, HostType,
// Tokens, AccountNumberLastFour, ExpirationDate, CardType, AuditId, ... }
import json
def get_tokens_for_wallet(payment_type: str, payment_blob: dict) -> dict:
body = {
"ApplicationSource": 1,
"AuthenticatedPaymentDetails": {
"AuthenticatedPaymentType": payment_type, # "GOOGLEPAY" | "APPLEPAY"
"AuthenticatedPaymentBlob": json.dumps(payment_blob)
},
"RequestExpirationUTC": utc_plus(5)
}
r = requests.post(
f"{os.environ['HPP_BASE']}/v1.4/EncryptedTokenAdministration/GetTokensForAuthenticatedPaymentData",
headers=signed_headers(body), json=body)
r.raise_for_status()
return r.json()
# Response: {"IsApproved": True, "ResponseCode": "000", "Tokens": [...], "CardType": "Visa", "AuditId": 678901, ...}
var body = new {
ApplicationSource = 1,
AuthenticatedPaymentDetails = new {
AuthenticatedPaymentType = paymentType, // "GOOGLEPAY" | "APPLEPAY"
AuthenticatedPaymentBlob = JsonSerializer.Serialize(paymentBlob)
},
RequestExpirationUTC = DateTime.UtcNow.AddMinutes(5).ToString("o")
};
var req = BuildRequest(HttpMethod.Post,
"/v1.4/EncryptedTokenAdministration/GetTokensForAuthenticatedPaymentData", body);
var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode();
// Response: { IsApproved, ResponseCode, ResponseMessage, Tokens, CardType, AuditId, ExpirationDate, ... }
ObjectNode details = mapper.createObjectNode()
.put("AuthenticatedPaymentType", paymentType)
.put("AuthenticatedPaymentBlob", mapper.writeValueAsString(paymentBlob));
ObjectNode body = mapper.createObjectNode()
.put("ApplicationSource", 1)
.put("RequestExpirationUTC", Instant.now().plusSeconds(300).toString());
body.set("AuthenticatedPaymentDetails", details);
HttpRequest req = buildSignedRequest(
"/v1.4/EncryptedTokenAdministration/GetTokensForAuthenticatedPaymentData",
mapper.writeValueAsString(body));
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
// Response: {"IsApproved":true,"ResponseCode":"000","Tokens":[...],"CardType":"Visa","AuditId":678901,...}
Payment status codes
Status codes are delivered via the PAYMENT_RETURN postMessage event as event.data.statusCode after the HPP iframe redirects to your ReturnURL. Only code 100 indicates a successful authorisation. For all other codes, do not call CompleteSession.
100, the payment was not authorised. Calling CompleteSession with a non-100 code results in a 4xx error or unexpected behaviour.| Code | Label | Description | Recommended action |
|---|---|---|---|
| 100 | ✅ Success | Payment authorised by card issuer. Ready to finalize. | Call CompleteSession exactly once using stored SessionId. Navigate to order confirmation on success. |
| 201 | ⚠️ Cancelled | Customer voluntarily cancelled payment. | Show a cancellation message with a retry option. Do not call CompleteSession. |
| 202 | ❌ Network Error | Connectivity failure occurred during the transaction. Payment state is uncertain. | Ask user to check connection and retry. Consider calling ReverseTransaction("timeout") as a precaution. |
| 203 | ❌ Server Reject | Transaction rejected by NCR server or card issuer declined. | Log with X-ReferenceId. Show a generic decline message. Offer retry or alternative payment method. |
| 204 | ❌ Technical Error | Internal technical error during processing. | Log the error. Suggest retry. Contact NCR support if persistent. |
| 205 | ⚠️ Session Expired | Session expired — more than 5 minutes (or configured TimeoutInMinutes) elapsed without completion. |
Re-call InitializeSession for a fresh session. Do not call CompleteSession. |
| 206 | ❌ External Error | Error in an external dependency (card network or acquiring bank temporarily unavailable). | Suggest retry in a few minutes. Log for support. |
| 207 | ❌ Invalid Request | Payment request was malformed or contained invalid field values. | Review your InitializeSession request body. Check required fields, types, and enum values. |
| 208 | ❌ Auth Failed | 3DS authentication failed or customer could not complete card verification. | Ask customer to try a different card. Do not call CompleteSession. |
| 209 | ⚠️ Timeout | Payment request timed out waiting for authorisation response from the card network. | Offer customer a retry. Consider calling ReverseTransaction("timeout") if there is a risk of duplicate authorisation. |
window.addEventListener('message', (event) => {
// Always verify origin before acting
if (
!event.origin.includes('ncrvoyix.com') &&
event.origin !== window.location.origin
) return;
const { messageType, height, statusCode } = event.data ?? {};
if (messageType === 'PAGE_LOAD_COMPLETE') {
setIframeLoaded(true);
} else if (messageType === 'IFRAME_RESIZE') {
if (height > 0) setIframeHeight(height);
} else if (messageType === 'PAYMENT_RETURN') {
handlePaymentReturn(statusCode);
}
});
async function handlePaymentReturn(statusCode) {
switch (statusCode) {
case 100:
// ✅ SUCCESS — call CompleteSession on your server
await fetch('/api/payments/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId })
});
navigate('/order-confirm');
break;
case 201:
showMessage('Payment cancelled. You can try again.');
break;
case 205:
showMessage('Session expired. Restarting payment…');
await reinitializeSession();
break;
case 208:
showMessage('Card authentication failed. Try another card.');
break;
default:
showMessage(`Payment failed (code ${statusCode}). Contact support.`);
}
}
// /pay/return — NCR redirects iframe here with ?statusCode=NNN
const params = new URLSearchParams(window.location.search);
const statusCode = parseInt(params.get('statusCode') ?? '0', 10);
// Forward result to parent (CheckoutPage)
window.parent.postMessage(
{ messageType: 'PAYMENT_RETURN', statusCode },
window.location.origin
);