Webhooks
How miaPOS notifies your backend when a payment changes state. Signed, idempotent, retried with backoff.
Overview
Webhooks are the authoritative channel for payment results. The browser redirect after checkout is for UX only — never fulfill an order based on the redirect alone. miaPOS POSTs every state change to your registered callbackUrl with a signed payload.
Payload
POST /your-callback-url HTTP/1.1
Content-Type: application/json
X-MiaPos-Signature: base64(rsa_sha256(body))
X-MiaPos-Event: payment.completed
X-MiaPos-Delivery: evt_01HZP2K7...
{
"event": "payment.completed",
"paymentId": "pay_01HZP2...",
"orderId": "ORD-2026-00123",
"amount": 100.00,
"currency": "MDL",
"status": "COMPLETED",
"completedAt": "2026-05-30T14:23:45Z"
}
Verify the signature
Every webhook is signed with miaPOS' private key. Verify before trusting the payload.
- Read the raw request body (exact bytes — don't re-serialize).
- Decode the
X-MiaPos-Signatureheader (base64). - Verify with the miaPOS public key fetched from
GET /ecomm/api/v1/public-key.
Full algorithm and reference code in Signature verification.
Retries and idempotency
Respond 2xx within 10 s to acknowledge. Any other response (or timeout) is retried with exponential backoff: 1m, 5m, 15m, 1h, 6h, 24h (6 attempts total over ~30 h).
Every delivery carries a unique X-MiaPos-Delivery id. Treat it as the idempotency key — store seen ids and short-circuit duplicates.
Event types
payment.completed— paid and settledpayment.failed— declined by payer's bank or schemepayment.expired— TTL reached before payer actedpayment.refunded— full or partial refund processed