Refund Tracker
Track refund and partial refund decisions from the order.updated webhook event.
Use the refund_tracker array in the order.updated webhook event to track refund and partial refund decisions.
Refund Tracker Webhook
Amwal sends refund tracker updates in the order.updated webhook event. Your webhook handler should read data.refund_tracker to identify whether each refund record is pending, refunded, cancelled, or failed.
Store each refund tracker record against the related order in your system so your operations, support, or finance teams can track the refund lifecycle.
Event Fields
| Field | Type | Description |
|---|---|---|
event_type | string | The webhook event name. For refund tracker updates, this is order.updated. |
data | object | The order payload associated with the refund update. |
data.refund_tracker | array | null | List of refund tracker records. It can be null when no refund tracker is available for the order. |
data.refund_tracker[].id | string | Unique identifier for the Amwal refund tracker record. |
data.refund_tracker[].rrn | string | Bank Refund Reference Number returned for the refund tracker record. |
data.refund_tracker[].amount | string | Refund amount for this tracker record. |
data.refund_tracker[].status | string | Refund decision status. Use this value to identify whether the refund is pending, refunded, cancelled, or failed. |
data.refund_tracker[].gateway_key_type | string | Gateway key type returned for the refund tracker record. |
data.refund_tracker[].gateway_transaction_id | string | Gateway transaction identifier returned for the refund record. |
Refund Status Values
The data.refund_tracker[].status field can contain one of these values:
| Value | Status | Description |
|---|---|---|
P | Pending | The refund request is waiting for a final decision. |
R | Refunded | The refund was completed. |
C | Cancelled | The refund was cancelled. |
F | Failed | The refund failed. |
Refund Tracker Object Example
The refund_tracker field is returned as an array of refund status records.
"refund_tracker": [
{
"id": "9876",
"rrn": "xxxx RRN Number xxxxx",
"amount": "202.95",
"status": "R",
"gateway_key_type": "RefundReference",
"gateway_transaction_id": "trx id"
}
]Check the
statusfield on each refund tracker record to determine your next action: wait onP, mark the refund complete onR, stop refund processing onC, and escalate failures onF.
Example Payload
The order.updated webhook includes the order or transaction payload in data. The sample below uses dummy data and shows a refund tracker where one refund record is completed and another is pending.
{
"event_type": "order.updated",
"data": {
"id": "order_123456789",
"ref_id": "merchant-order-1001",
"status": "refunded",
"type": "PRODUCTION",
"amount": "250.00000",
"discount": "25.00000",
"shipping": "15.00000",
"taxes": "10.00000",
"total_amount": "250.00",
"payment_amount": "250.00",
"refunded_amount": "150.00",
"fees": "0.00000",
"amwal_fee": "2.50",
"amwal_tax_vat": "0.38",
"convenience_fee": "0.00",
"merchant_payout": "97.12",
"payment_method": "Card",
"payment_option": "Pay In Full",
"paymentBrand": "VISA",
"funding_method": "credit",
"card_type": "CREDIT",
"card_last_4_digits": "1234",
"card_payment_brand": "VISA",
"issuer": "Demo Bank",
"card_bank_issuer": "demo bank",
"created_at": "2026-04-28T20:41:00.356051+03:00",
"merchant_id": "merchant_123456789",
"merchant_business_name": "Demo Store",
"merchant_country_code": "SA",
"store_domain": "https://demo-store.example.com",
"client_email": "[email protected]",
"client_first_name": "Example",
"client_last_name": "Customer",
"client_phone_number": "+966500000000",
"refund_tracker": [
{
"id": "refund_tracker_1001",
"rrn": "123456789012",
"amount": "100.00",
"status": "R",
"gateway_key_type": "RefundReference",
"gateway_transaction_id": "refund_trx_1001"
},
{
"id": "refund_tracker_1002",
"rrn": "123456789013",
"amount": "50.00",
"status": "P",
"gateway_key_type": "RefundReference",
"gateway_transaction_id": "refund_trx_1002"
}
],
"address_details": {
"city": "Riyadh",
"state": "Riyadh Province",
"country": "SA",
"street1": "Example Street",
"postcode": "12345",
"first_name": "Example",
"last_name": "Customer",
"email": "[email protected]"
},
"shipping_details": {
"id": "standard_shipping:1",
"tax": 1.5,
"label": "Standard shipping",
"price": 15
},
"is_refundable": false,
"installment_tracker": null,
"order_details": null,
"failure_reason": null
}
}Use the exact data.refund_tracker[].status value from the payload when updating each refund record in your system. Other fields in data provide transaction, customer, merchant, payment, shipping, and refund context that you can store for reconciliation or support workflows.
Handle refund tracker updates
Use the refund_tracker array in your order.updated handler to process each refund decision and update your internal refund state.
async function handleOrderUpdated(webhook) {
try {
const refundTracker = webhook?.data?.refund_tracker;
if (!Array.isArray(refundTracker)) {
console.log('No refund tracker records found for this event.');
return { status: 'ignored' };
}
if (refundTracker.length === 0) {
console.log('Refund tracker is present but empty.');
return { status: 'empty' };
}
for (const record of refundTracker) {
switch (record.status) {
case 'R':
console.log(`Refund completed for tracker ${record.id}: ${record.amount}`);
break;
case 'C':
console.log(`Refund cancelled for tracker ${record.id}`);
break;
case 'P':
console.log(`Refund pending for tracker ${record.id}`);
break;
case 'F':
console.error(`Refund failed for tracker ${record.id}`);
break;
default:
console.warn(`Unknown refund status for tracker ${record.id}: ${record.status}`);
}
}
return { status: 'processed', records: refundTracker.length };
} catch (error) {
console.error('Failed to process refund tracker:', error.message);
return { status: 'error', message: error.message };
}
}
const webhookPayload = {
event_type: 'order.updated',
data: {
refund_tracker: [
{
id: '9876',
rrn: 'xxxx RRN Number xxxxx',
amount: '202.95',
status: 'R',
gateway_key_type: 'RefundReference',
gateway_transaction_id: 'trx id'
},
{
id: '9877',
rrn: 'xxxx RRN Number yyyyy',
amount: '50.00',
status: 'P',
gateway_key_type: 'RefundReference',
gateway_transaction_id: 'trx id 2'
}
]
}
};
handleOrderUpdated(webhookPayload).then(result => {
console.log('Processing result:', result);
});Expected output:
Refund completed for tracker 9876: 202.95
Refund pending for tracker 9877
Processing result: { status: 'processed', records: 2 }Recommended Processing
When you receive an order.updated event with refund tracker records:
- Treat
data.refund_tracker[].statusas the source of truth for each refund decision. - Support the
P,R,C, andFstatus values in your order management system. - Update each refund record independently because
refund_trackeris an array and can contain multiple refund or partial refund records. - Mark a refund as completed only when the tracker status is
R. - Keep the refund pending when the tracker status is
P. - Stop refund processing when the tracker status is
C. - Notify your support or operations team when the tracker status is
F. - Keep the original webhook payload for audit and reconciliation.
Updated 9 days ago