Appearance
Callbacks & Return Flow
Callback Mechanism
When a payment session reaches a terminal state, Spayon sends a signed POST request to your configured callback_url.
Callback Request
http
POST YOUR_CALLBACK_URL
Content-Type: application/json
X-Signature: <HMAC_SHA256_SIGNATURE>Callback Payload
json
{
"sessionId": "4ae3108a-3a1c-42df-bce9-503bbd70ab24",
"status": "paid",
"productName": "Iphone 16S",
"price": "10",
"currency": "AMD",
"createdAt": "2025-06-11T17:02:51.118Z",
"updatedAt": "2025-06-11T17:03:15.202Z",
"orderId": "ORDER_123456"
}All timestamps are in UTC, ISO 8601 format.
Status Values
| Status | Description |
|---|---|
paid | Payment completed successfully |
failed | Payment failed or was cancelled |
pending | Payment is still being processed |
expired | Session has expired |
Signature Verification
Every callback includes an X-Signature header. Always verify this signature before processing the payload to ensure the request originated from Spayon.
X-Signature = HMAC_SHA256(callback_secret, raw_request_body)callback_secret— obtained from your Vendor Admin Panelraw_request_body— the exact raw JSON bytes received (before any parsing)
WARNING
Compute the HMAC over the raw body bytes, not a re-serialized version. JSON key ordering or whitespace differences will cause verification to fail.
Verification Example
js
const crypto = require('crypto')
function verifySignature(rawBody, receivedSignature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(receivedSignature)
)
}python
import hmac
import hashlib
def verify_signature(raw_body: bytes, received_signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
raw_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, received_signature)Retry Logic
| Property | Value |
|---|---|
| Retries | Up to 3 attempts |
| Retry interval | 5 minutes between attempts |
| On timeout | No callback sent for sessions that never reached a terminal state |
TIP
Your callback endpoint must return a 2xx response quickly. If your endpoint is slow or returns an error, Spayon will retry.
Return URL Flow
After payment completes (success or failure), the user is redirected to your return_url. If the user clicks the back button on the payment page, they are redirected to your cancel_url (if configured).
The session_id is always appended as a query parameter:
https://example.com/thank-you?session_id=4ae3108a-3a1c-42df-bce9-503bbd70ab24Cancel URL behavior
Redirecting to the cancel_url does not change the session status. The session remains active until it expires (15 minutes) or payment is processed. Do not treat a cancel redirect as a definitive cancellation.
| URL | Triggered when |
|---|---|
return_url | Payment completes (any status) |
cancel_url | User clicks the back button on the payment page |