Webhooks
PayItFast sends real-time JSON notifications about key events to your registered endpoint. Webhooks allow you to react immediately to user status changes, payment settlements, failures, and more without polling the API.
Webhook Payload Structure
Every webhook delivers a JSON body with the following structure.
{
"eventId": "EV-231107XXXXX4387",
"entityId": "OR-240726094358",
"entityType": "order",
"orgId": "OG-231207102120",
"status": "fund_settled",
"user": {
"userId": "UX-240625104122",
"firstName": "string",
"lastName": "string",
"country": "string",
"createdAt": "ISO-8601"
},
"order": {
"orderId": "string",
"type": "string",
"fiatTicker": "string",
"cryptoTicker": "string",
"fiatAmount": 0,
"cryptoAmount": 0,
"walletAddress": "string",
"paymentType": "string",
"createdAt": "ISO-8601",
"customerOrderId": "string",
"failureCode": "string",
"failureMessage": "string"
},
"partnerContext": {},
"createdAt": "ISO-8601"
}
| Field | Type | Description |
|---|---|---|
| eventId | string | Unique event identifier |
| entityId | string | User ID or Order ID associated with the event |
| entityType | string | "user" or "order" |
| orgId | string | Organization identifier |
| status | string | Current entity status (e.g., fund_settled, kyc_success) |
| user | object | User details including userId, name, country, and creation date |
| order | object | Order details (empty for user events). Includes amounts, tickers, and payment info. |
| partnerContext | object | Your custom metadata, echoed back from order creation |
| order.failureCode | string | Error code — only present in failure events |
| order.failureMessage | string | Human-readable error message — only present in failure events |
| createdAt | string | ISO-8601 timestamp of when the event was created |
User Events
These webhooks fire when a user's account or KYC status changes.
| Event | Status | Description |
|---|---|---|
| User Created | user_created |
Account established |
| User Approved | user_approved |
Demo transaction capability granted |
| User Rejected | user_rejected |
Account creation failed approval |
| KYC Initiated | kyc_initiated |
KYC verification begins |
| KYC Success | kyc_success |
Verification passed |
| KYC Rejected | kyc_rejected |
Verification failed compliance |
Collections Events
Webhooks for fiat payin (collection) orders.
| Event | Status | Description |
|---|---|---|
| Payment Initiated | initiated |
Order created, user redirected to payment |
| Payment Authorised | fund_settled |
Bank confirmed payment receipt |
| Payment Unauthorised | fund_failed |
Bank declined payment |
| Manual Review | manual_review |
Held for compliance review |
Payout Events
Webhooks for fiat payout orders.
| Event | Status | Description |
|---|---|---|
| Payment Initiated | initiated |
Payout order successfully created |
| Payment Scheduled | fund_scheduled |
Payout scheduled for processing |
| Payment Completed | fund_settled |
Funds received by user, confirmed by bank |
| Payment Failed | fund_failed |
Failed to send to user's account |
| Payment Returned | fund_returned |
Funds returned from user's bank |
Gaming Events
Webhooks for fiat payin with wallet (iGaming) orders.
| Event | Status | Description |
|---|---|---|
| Payment Initiated | initiated |
Order created, awaiting payment |
| Payment Authorised | fund_settled |
Bank confirmed payment |
| Payment Unauthorised | fund_failed |
Bank declined payment |
| Stablecoin Deposit | asset_deposited |
Stablecoin deposited to user's wallet |
| Balance Top Up | completed |
Order complete — trigger balance top-up |
| Expired | expired |
Transaction not completed in time |
| Manual Review | manual_review |
Held for compliance review |
Onramp Events
Webhooks for fiat-to-crypto (onramp) orders.
| Event | Status | Description |
|---|---|---|
| Payment Initiated | initiated |
Order created, awaiting payment |
| Payment Authorised | fund_settled |
Bank confirmed fiat receipt |
| Payment Unauthorised | fund_failed |
Bank declined payment |
| Crypto Settled | asset_settled |
User received cryptocurrency |
| Crypto Settle Failed | asset_settle_failed |
Crypto delivery failed |
| Expired | expired |
Order expired due to inactivity |
Offramp Events
Webhooks for crypto-to-fiat (offramp) orders.
| Event | Status | Description |
|---|---|---|
| Payment Initiated | initiated |
Order created, awaiting stablecoin |
| Crypto Received | asset_deposited |
PayItFast received crypto from user |
| Crypto Receive Failed | asset_deposit_failed |
Crypto not received |
| Payment Sent | fund_settled |
User received fiat |
| Payment Failed | fund_failed |
Bank declined fiat transfer |
| Expired | expired |
Order expired due to inactivity |
Signature Verification
All webhooks are signed with HMAC-SHA256 using a dedicated secret key. You should always verify the signature to ensure the webhook was sent by PayItFast and has not been tampered with.
Verification Steps
- Generate an HMAC-SHA256 hash using your secret key and the raw request body.
- Compare the generated hash with the value in the
X-PayItFast-Hmac-Hashheader. - If they match, the webhook is valid. If they do not match, the payload may have been tampered with — discard it.
Node.js Example
const crypto = require('crypto');
const hash = crypto
.createHmac('sha256', secretKey)
.update(JSON.stringify(requestBody))
.digest('hex');
const isValid = hash === request.headers['x-payitfast-hmac-hash'];
Python Example
import hmac, hashlib
hash = hmac.new(
secret_key.encode(),
request_body.encode(),
hashlib.sha256
).hexdigest()
is_valid = hash == request.headers['X-PayItFast-Hmac-Hash']
Contact PayItFast technical support to obtain your webhook secret key. Store it securely and never expose it in client-side code.
Retry Mechanics
PayItFast automatically retries failed webhook deliveries to ensure you receive every notification.
| Parameter | Value |
|---|---|
| Retry window | Up to 2 hours from the initial attempt |
| Max retries | 8 retry attempts |
| Interval | 15-minute intervals between retries |
| Enabled by default | Yes — no configuration needed |
| Required response | Your endpoint must return HTTP 200 to acknowledge receipt |
| Trigger conditions | Timeouts or connection failures |
Your webhook endpoint must return an HTTP 200 status code to acknowledge receipt. Any other status code (or a timeout) will trigger a retry. Ensure your endpoint processes webhooks idempotently, as retries may deliver the same event more than once.