Skip to main content

Cancel / Reverse POS Charge

POST /pos/charge/:chargeID/cancel POST /pos/charge/:chargeID/reverse

Cancels (voids) a POS charge before it has been settled. Both the /cancel and /reverse paths invoke the same operation — use whichever naming convention fits your integration. If the charge has already been settled, use the Refund endpoint instead.

MSK encryption: Response body is MSK-encrypted (TR31-DATA). No request body (HMAC signs empty body). See End-to-End Example.

Purpose

  • Void a charge that has not yet been settled with the acquirer
  • Cancel an accidental or incorrect charge immediately
  • The /reverse alias is provided for integrations that use reversal terminology
Cancel vs Refund

Cancel / Reverse voids the authorization before settlement — the cardholder is never charged. Refund returns funds after settlement has occurred. Use cancel when the transaction is still pending; use refund after the charge has settled.

Authentication

POS HMAC Signature — requires device identification headers and HMAC signature for every request.

Device Identification Headers

HeaderRequiredFormatDescription
X-Terminal-IdYesTerminal ID stringIdentifier of the terminal requesting the cancellation. Example: TERM-001
User-AgentYesViopay-POS/{version} ({OS}; {model})POS app version string. Must start with Viopay-POS/. Example: Viopay-POS/1.4.2 (Android 12; PAX-A920)
X-Client-TypeYesposClient type identifier. Always pos for POS devices.

Signature Headers

HeaderRequiredFormatDescription
X-Key-IdYesFree-form stringIdentifier of the HMAC key used to generate the signature. Example: hmac-key-2025-01
X-TimestampYesRFC3339Current time in UTC. Must be within 5 minutes of server time. Example: 2025-12-13T14:25:30Z
X-NonceYesAlphanumeric stringUnique random value for each request. At least 12 characters. Example: a1b2c3d4e5f6
X-SignatureYesv1={base64_hmac}HMAC-SHA256 signature over the request. See Signature Computation.

See the Headers Reference for complete details on all POS headers.

Request

Path Parameters

ParameterTypeRequiredDescription
chargeIDstringYesThe charge ID to cancel (returned from Create POS Charge)

Body

No request body is required. The cancellation is identified entirely by the charge ID in the path.

Response

200 OK — MSK-encrypted envelope

Decrypt with MSK to obtain:

{
"charge_id": "ch_abc123def456",
"status": "cancelled"
}

Wire format:

{
"format": "TR31-DATA",
"ciphertext": "D4E5F6...",
"initialization_vector": "101112131415161718191A1B1C1D1E1F",
"mode": "CBC",
"key_kcv": "ABCD12"
}
FieldTypeDescription
charge_idstringThe charge that was cancelled
statusstringAlways "cancelled" on success

400 Bad Request

Returned when the charge ID is missing or the charge is not in a cancellable state.

{
"error": {
"code": "4000",
"message": "Charge cannot be cancelled",
"trace_id": "abc123..."
}
}

401 Unauthorized

Returned when HMAC signature validation fails.

{
"error": {
"code": "4001",
"message": "Invalid signature",
"trace_id": "abc123..."
}
}

500 Internal Server Error

Returned when the payment gateway returns an error or processing fails.

{
"error": {
"code": "5000",
"message": "Gateway processing error",
"trace_id": "abc123..."
}
}

Code Examples

curl -X POST https://api.viopay.io/pos/charge/ch_abc123def456/cancel \
-H "X-Terminal-Id: TERM-001" \
-H "User-Agent: Viopay-POS/1.4.2 (Android 12; PAX-A920)" \
-H "X-Client-Type: pos" \
-H "X-Key-Id: hmac-key-2025-01" \
-H "X-Timestamp: 2025-12-13T14:25:30Z" \
-H "X-Nonce: a1b2c3d4e5f6" \
-H "X-Signature: v1=SGVsbG8gV29ybGQ=" \
-H "Content-Type: application/json"

What's Next?