Webhook Event Types
Amwal delivers real-time HTTP POST notifications to your registered webhook URL for each distinct transition in a payment's lifecycle.
Supported Event Types
| Event Type | Description | Trigger Condition |
|---|---|---|
order.created | New order initiated | Customer starts checkout process |
order.success | Payment successful | Payment confirmed and completed |
order.failed | Payment failed | Payment declined, failed, or cancelled |
order.updated | Order Refund | Contain the Bank gateway refund details. |
installment.tracker.approved | The installment is approved | Contain the Installment tracker object with its status "A" |
installment.tracker.rejected | The installment is rejected | Contain the Installment tracker object with its status "R" |
order.disputed | Chargeback dispute update | Contains disputed_status to identify the chargeback status: PENDING, RESOLVED, or LOST. |
payment_link.expired | Payment link expired | The payment link reaches its configured expiration time. |
modal.closed | Payment modal closed | The customer closes the payment modal. |
Webhook Envelope Schema
All webhook requests deliver a JSON payload structured with the following top-level attributes:
| Field | Type | Description |
|---|---|---|
event_type | String | The event identifier name (e.g. order.success, order.updated). Also aliased as event. |
timestamp | String (ISO 8601) | UTC timestamp when the webhook event was generated. |
data | Object | Full event payload containing transaction, order, and customer records. |
1. order.created (New Order Initiated)
Dispatched when a customer opens a payment link or launches the checkout modal session.
{
"event_type": "order.created",
"timestamp": "2026-05-14T11:20:00Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "299.99",
"currency": "SAR",
"status": "pending",
"client_first_name": "Ahmed",
"client_last_name": "Al-Rashid",
"client_email": "customer@example.com",
"client_phone_number": "+966501234567",
"order_details": {
"order_id": "ORD-9876",
"payment_link_metadata": {
"terminal_id": "POS-001"
}
},
"created_at": "2026-05-14T11:20:00.000Z"
}
}order.created Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Unique transaction identifier initiated for this checkout session. |
payment_link_id | String (UUID) | Payment link associated with this order. |
status | String | Current state: "pending". |
amount | String / Number | Order amount in SAR. |
currency | String | Currency ISO code (SAR). |
client_first_name | String / Null | Customer's first name. |
client_last_name | String / Null | Customer's last name. |
client_email | String / Null | Customer's email address. |
client_phone_number | String / Null | Customer's phone number. |
order_details.order_id | String / Null | External merchant order identifier. |
order_details.payment_link_metadata | Object | Merchant custom metadata dictionary. |
created_at | String (ISO 8601) | Initiation timestamp in UTC. |
2. order.success (Payment Successful)
Dispatched immediately when an installment or card payment is confirmed and approved by the issuing bank.
{
"event_type": "order.success",
"timestamp": "2026-05-14T11:22:10Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "success",
"amount": "299.99",
"currency": "SAR",
"payment_method": "Card",
"payment_option": "Installment",
"bank_name": "Al Rajhi Bank",
"installment_duration": 6,
"installment_status": "Approved",
"monthly_installment": "50.00",
"paymentBrand": "VISA",
"number": "411111xxxxxx1111",
"client_first_name": "Ahmed",
"client_last_name": "Al-Rashid",
"client_email": "customer@example.com",
"client_phone_number": "+966501234567",
"order_details": {
"order_id": "ORD-9876",
"payment_link_metadata": {
"terminal_id": "POS-001"
}
},
"created_at": "2026-05-14T11:22:10.534Z"
}
}order.success Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Unique Amwal transaction identifier. |
payment_link_id | String (UUID) | Associated payment link ID. |
status | String | Authorization outcome: "success". |
amount | String / Number | Authorized transaction amount in SAR. |
currency | String | Currency ISO code (SAR). |
payment_method | String | Payment channel ("Card"). |
payment_option | String | Mode of payment: "Installment" or "Pay In Full". |
bank_name | String | Partner bank name (e.g. "Al Rajhi Bank", "Saudi National Bank (SNB)"). |
installment_duration | Integer / Null | Selected installment tenure in months (3, 6, 12, 24). |
installment_status | String / Null | Bank installment approval status: "Approved". |
monthly_installment | String / Number | Monthly installment billing amount charged to the cardholder. |
paymentBrand | String | Card network: "VISA", "MASTERCARD", "MADA". |
number | String | Masked card number. |
client_first_name | String | Customer first name. |
client_last_name | String | Customer last name. |
client_email | String | Customer email address. |
client_phone_number | String | Customer mobile number. |
order_details.order_id | String / Null | Merchant order ID. |
order_details.payment_link_metadata | Object | Custom merchant metadata dictionary. |
created_at | String (ISO 8601) | Timestamp of authorization in UTC. |
3. order.failed (Payment Failed)
Dispatched when a payment attempt fails 3DS authentication, is declined by the bank, or is cancelled.
{
"event_type": "order.failed",
"timestamp": "2026-05-14T11:25:00Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "fail",
"amount": "299.99",
"currency": "SAR",
"failure_reason": "Insufficient funds",
"created_at": "2026-05-14T11:25:00Z"
}
}order.failed Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Transaction identifier. |
status | String | Failure outcome: "fail". |
failure_reason | String | Detailed decline reason code from the bank gateway (e.g. "Insufficient funds", "3DS authentication failed"). See Transaction Failed Reasons. |
4. order.updated (Order Refund)
Dispatched when a partial or full refund is processed, containing bank gateway refund tracker details.
{
"event_type": "order.updated",
"timestamp": "2026-05-15T14:30:00Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "partially refunded",
"amount": "299.99",
"currency": "SAR",
"refunded_amount": "100.00",
"remaining_amount": "199.99",
"refund_tracker": [
{
"id": "4905",
"status": "R",
"amount": "100.00",
"gateway_transaction_id": "2026001732",
"gateway_key_type": "RefundReference",
"rrn": "623709256127"
}
],
"created_at": "2026-05-14T11:22:10.534Z"
}
}order.updated Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Transaction identifier. |
status | String | Updated transaction state: "partially refunded" or "refunded". |
amount | String / Number | Original transaction amount in SAR. |
refunded_amount | String / Number | Total cumulative refund amount accepted across all refund requests. |
remaining_amount | String / Number | Remaining net balance after refunds. |
refund_tracker | Array of Objects | Array of refund execution objects containing gateway reference numbers and settlement status (status: "R"). |
5. installment.tracker.approved (Installment Approved)
Dispatched when partner bank authorization approves the installment conversion plan, containing the installment tracker object with status "A".
{
"event_type": "installment.tracker.approved",
"timestamp": "2026-05-14T11:22:15Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "299.99",
"currency": "SAR",
"bank_name": "Al Rajhi Bank",
"installment_duration": 6,
"installment_tracker": {
"id": "275460",
"status": "A",
"message": "Operation Successful"
}
}
}installment.tracker.approved Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Transaction identifier. |
bank_name | String | Partner bank confirming the installment plan. |
installment_duration | Integer | Approved installment duration in months (3, 6, 12, 24). |
installment_tracker.status | String | Approval code: "A" (Approved). |
installment_tracker.message | String | Status message from bank gateway (e.g. "Operation Successful"). |
6. installment.tracker.rejected (Installment Rejected)
Dispatched when partner bank authorization declines the installment conversion plan, containing the installment tracker object with status "R".
{
"event_type": "installment.tracker.rejected",
"timestamp": "2026-05-14T11:22:15Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "299.99",
"currency": "SAR",
"bank_name": "Saudi National Bank (SNB)",
"installment_duration": 6,
"installment_tracker": {
"id": "275461",
"status": "R",
"message": "Installment Plan Declined by Issuing Bank"
}
}
}installment.tracker.rejected Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Transaction identifier. |
bank_name | String | Partner bank declining the installment request. |
installment_tracker.status | String | Rejection code: "R" (Rejected). |
installment_tracker.message | String | Reason message returned by bank gateway. |
7. order.disputed (Chargeback Dispute Update)
Dispatched when a cardholder files a dispute or when the dispute state changes. Contains disputed_status indicating whether the dispute is PENDING, RESOLVED, or LOST.
{
"event_type": "order.disputed",
"timestamp": "2026-06-01T10:00:00Z",
"data": {
"id": "60b43176-5991-4475-8ef6-c73c2417c805",
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "299.99",
"currency": "SAR",
"disputed_status": "PENDING",
"dispute_id": "disp_89124",
"reason": "Cardholder unrecognized charge",
"due_date": "2026-06-15T23:59:59Z"
}
}order.disputed Data Parameters
| Field | Type | Description |
|---|---|---|
id | String (UUID) | Transaction identifier under dispute. |
disputed_status | String | Current dispute state: PENDING (awaiting evidence), RESOLVED (merchant won dispute), or LOST (chargeback upheld). |
dispute_id | String | Unique dispute case identifier. |
reason | String | Bank chargeback reason description. |
due_date | String (ISO 8601) | Deadline to upload rebuttal documentation in the Merchant Portal. |
8. payment_link.expired (Payment Link Expired)
Dispatched when an unpaid link reaches its configured expiration time (selectedDate).
{
"event_type": "payment_link.expired",
"timestamp": "2026-12-31T23:59:59Z",
"data": {
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"store_id": "f24267bd-79f4-433f-a9f2-485c171301e4",
"status": "Expired",
"amount": "299.99",
"currency": "SAR",
"created_at": "2026-05-14T11:18:49Z"
}
}payment_link.expired Data Parameters
| Field | Type | Description |
|---|---|---|
payment_link_id | String (UUID) | Payment link identifier that expired. |
store_id | String (UUID) | Store ID associated with the expired link. |
status | String | Final link state: "Expired". |
amount | String / Number | Link amount in SAR. |
9. modal.closed (Payment Modal Closed)
Dispatched when a customer explicitly dismisses or closes the hosted checkout modal before completing payment.
{
"event_type": "modal.closed",
"timestamp": "2026-05-14T11:21:00Z",
"data": {
"payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
"store_id": "f24267bd-79f4-433f-a9f2-485c171301e4",
"status": "closed",
"action": "customer_dismissed"
}
}modal.closed Data Parameters
| Field | Type | Description |
|---|---|---|
payment_link_id | String (UUID) | Payment link identifier for the closed session. |
store_id | String (UUID) | Associated store ID. |
status | String | Modal status: "closed". |
action | String | Action triggered: "customer_dismissed". |
Webhook Implementation Examples
Complete, production-ready backend webhook receiver examples with RSA-PSS SHA-256 signature verification and event routing in Node.js, Python, PHP, and Go.
Statement Report API
Export merchant settlement reports and payout data programmatically by date range using the Reports API.
