401 Unauthorized response.
Signing protects your integration in three ways:
- The secret never travels. It stays on your server and is used only to compute the signature.
- Tampering is detectable. The signature covers the method, path, query string, and body.
- Replay is limited. The signature includes a timestamp, and requests outside a five-minute window are rejected.
Get your credentials
SmartRetry provides your credentials during onboarding. If you don’t have them yet, contact SmartRetry to get started. You receive one credential, your API Secret. It starts withsrk_live_ for production or srk_test_ for the sandbox, and each works only in its own environment. SmartRetry identifies your account from the terminal ID in the request path.
- Keep it server-side. Sign requests on your backend only. Never put the secret in client-side code or call the API directly from a frontend.
- Store it safely. Use a secrets manager or an environment variable (for example,
SMARTRETRY_API_SECRET). Never commit it to source control. - Limit access. Restrict who can read your production secret, and use the sandbox secret for development and testing.
- Keep it out of logs. Log request IDs and transaction IDs, never the secret or signing inputs that contain card data.
- Rotate if compromised. Contact SmartRetry immediately to revoke the secret and issue a new one. To rotate on a schedule, ask for a new secret, deploy it, then have the old one revoked.
Sign a request
Send these headers on every request:
We also recommend an
Idempotency-Key header on POST requests so you can retry safely. It’s optional and isn’t part of the signature. See Idempotency.
1
Build the string to sign
Join four fields with a period (
.):String to sign
timestampis the current Unix time in seconds. Send the same value inx-timestamp.HTTP_METHOD_UPPERCASEis the method in uppercase, such asPOSTorGET.path_including_query_stringis the path and query string, for example/v1/payments/sale/ABC123. Don’t include the scheme or host.raw_request_bodyis the exact bytes you send. For requests with no body, use an empty string, so the string ends with a period.
2
Compute the HMAC-SHA256
Use your API Secret as the key and encode the result as lowercase hex:
Signature
3
Send the request
Add
x-timestamp and x-signature, and send the same body bytes you signed. Don’t parse and re-serialize the JSON after signing.Try it
Enter your values to see the string to sign and the signature. The defaults are a test vector. With them,x-signature must be a3572da91fd748adefe19333fed189d3e1f228dcd76c0556ec3e038bd7c33e17. Use it to check your own implementation.
Code examples
Each example signs a sale request and sends the exact body string it signed. ReplaceABC123 with your terminal ID.
Common pitfalls
Re-serializing the JSON body
Re-serializing the JSON body
Serialize once, sign that string, and send that same string. If your HTTP client serializes the body again, whitespace or key order can change and break the signature. In Python, pass
data= instead of json= to requests.Signing the wrong path
Signing the wrong path
Sign the path and query string exactly as you send them, for example
/v1/payments/status/ABC123/ORD8A3F2/TX8A3F2C?expand=true. Don’t include https://terminal.smartretry.com.Lowercase method
Lowercase method
The method in the string to sign must be uppercase (
POST, not post).Trailing newline in shell scripts
Trailing newline in shell scripts
echo adds a newline to the string to sign. Use printf '%s' as in the cURL example.Error responses
SmartRetry recomputes the signature using your stored secret and checks the request in the order below. The first failed check returns a401 response:
401 response
reason_code field to diagnose the issue: