Skip to main content

Overview

When a transaction reaches a terminal state (succeeded, failed or, for deposits, expired), winam-payments sends a POST JSON request to your callback_url.

Payments confirmed after expires_at

What happens when a deposit is paid late depends on its collection mode:
payment.succeeded can follow payment.expired for the same winam_tx_id on a customer-initiated deposit. Your endpoint must accept this event and credit the player.
See State Machine.
Webhooks are the recommended way to receive payment outcomes — faster and more reliable than polling. Always provide a callback_url in your deposit and withdrawal requests.

Webhook payload

Signature verification

Each webhook carries an X-Winam-Signature header computed with your application’s webhook secret (given to you once by Winam when your application is registered or its secret is rotated):
raw_body is the exact raw bytes of the HTTP request body, as received. Do not parse and re-serialize the JSON before verifying: any change in spacing or key order breaks the signature. Always verify the signature before processing the webhook:
  1. Parse t and v1 from the header.
  2. Reject the request if |now - t| exceeds 5 minutes (replay protection).
  3. Compute HMAC-SHA256(webhook_secret, t + "." + raw_body) and compare it to v1 with a constant-time comparison.
  4. Only then parse the JSON body.
Secret rotation. When Winam rotates your webhook secret, the new secret is given to you once and is used for all webhooks sent from then on. Update your secret before or right after the rotation; a webhook rejected during the switch can be re-sent with Replay Webhook.

Legacy JWT signature

The former JWT RS256 signature is still sent when Winam has it enabled, but in a different header: X-Winam-Signature-Jwt (it used to be sent in X-Winam-Signature). It can be verified with the public key from Callback Public Key. New integrations should verify the HMAC X-Winam-Signature above.

Retry policy

winam-payments retries 3 times with exponential backoff (1 s → 2 s → 4 s) if your endpoint responds with a status ≥ 400 or does not respond within 5 seconds. Your endpoint must:
  • Respond 2XX within 5 seconds
  • Be idempotent — the same winam_tx_id may be delivered more than once
  • Return 200 even if the event was already processed
If all retries fail, no further delivery attempts are made. Use Replay Webhook for manual recovery.
For the public key endpoint reference, see Callback Public Key.