Installment Tracker
Handle the installment_tracker object in webhook events and process approved, pending, and rejected installment decisions.
Use the installment_tracker object to track the issuer bank's decision for an installment request.
Installment Tracker Webhook
The installment_tracker object is returned in installment.tracker.approved and installment.tracker.rejected webhook payloads. Your webhook handler should read data.installment_tracker.status to identify the current installment decision and decide how to update the order.
Store the tracker status against the related order in your system so your operations, support, or fulfillment teams can track the installment lifecycle.
Event Fields
| Field | Type | Description |
|---|---|---|
event_type | string | The webhook event name. For installment tracker updates, this is installment.tracker.approved or installment.tracker.rejected. |
data | object | The order payload associated with the installment update. |
data.installment_tracker | object | null | The installment tracker object. It can be null when no installment tracker is available for the order. |
data.installment_tracker.id | string | Unique identifier for the installment tracker. |
data.installment_tracker.status | string | The issuer bank's installment decision. Use this value to identify whether the installment is approved, pending, or rejected. |
data.installment_tracker.message | string | null | Rejection reason when the status is R. This is usually null when the status is A or P. |
Installment Status Values
The data.installment_tracker.status field can contain one of these values:
| Value | Status | Description |
|---|---|---|
A | Approved | The issuer bank approved the installment request. |
P | Pending | The installment request is still waiting for a final decision. |
R | Rejected | The issuer bank rejected the installment request. Check message for the rejection reason. |
Installment Tracker Object Examples
Approved Installment
"installment_tracker": {
"id": "70414",
"status": "A",
"message": null
}Rejected Installment
"installment_tracker": {
"id": "70321",
"status": "R",
"message": "Error Message"
}Pending Installment
"installment_tracker": {
"id": "70321",
"status": "P",
"message": null
}Check the
statusfield to determine your next action: process the order onA, retry or wait onP, and surface themessageto your support team onR.
Example Payload
The webhook payload includes the order or transaction payload in data. The sample below uses dummy data and shows an installment.tracker.approved event where status is A.
{
"event_type": "installment.tracker.approved",
"data": {
"id": "order_123456789",
"ref_id": "merchant-order-1001",
"status": "success",
"type": "PRODUCTION",
"amount": "250.00000",
"discount": "25.00000",
"shipping": "15.00000",
"taxes": "10.00000",
"total_amount": "250.00",
"payment_amount": "250.00",
"refunded_amount": "0.00",
"fees": "0.00000",
"amwal_fee": "2.50",
"amwal_tax_vat": "0.38",
"convenience_fee": "0.00",
"merchant_payout": "247.12",
"payment_method": "Card",
"payment_option": "Installment",
"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",
"installment_status": "approved",
"installment_duration": 3,
"installment_fee": "0.00",
"installment_fee_vat": "0.00",
"installment_tracker": {
"id": "tracker_12345",
"status": "A",
"message": null
},
"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": true,
"refund_tracker": null,
"order_details": null,
"failure_reason": null
}
}Use the exact data.installment_tracker.status value from the payload when updating the order in your system. Other fields in data provide transaction, customer, merchant, payment, shipping, and installment context that you can store for reconciliation or support workflows.
Handle installment tracker updates
Use the installment_tracker object in your installment tracker webhook handler to decide whether to fulfill the order, wait for another update, or escalate the rejection reason.
async function handleInstallmentTrackerEvent(webhook) {
try {
const installmentTracker = webhook?.data?.installment_tracker;
if (!installmentTracker) {
console.log('No installment tracker found for this event.');
return { status: 'ignored' };
}
const { id, status, message } = installmentTracker;
switch (status) {
case 'A':
// Mark the order as ready for fulfillment after the issuer bank approves the installment request.
console.log(`Installment approved for tracker ${id}`);
return { status: 'approved', tracker_id: id };
case 'P':
// Keep the order in a waiting state until Amwal sends the next update.
console.log(`Installment pending for tracker ${id}`);
return { status: 'pending', tracker_id: id };
case 'R':
// Record the rejection reason so your operations or support team can review it.
console.error(`Installment rejected for tracker ${id}: ${message || 'No rejection message provided'}`);
return {
status: 'rejected',
tracker_id: id,
message: message || 'No rejection message provided'
};
default:
console.warn(`Unknown installment status for tracker ${id}: ${status}`);
return { status: 'unknown', tracker_id: id, raw_status: status };
}
} catch (error) {
console.error('Failed to process installment tracker:', error.message);
return { status: 'error', message: error.message };
}
}
const webhookPayloads = [
{
event_type: 'installment.tracker.approved',
data: {
installment_tracker: {
id: '70414',
status: 'A',
message: null
}
}
},
{
event_type: 'installment.tracker.approved',
data: {
installment_tracker: {
id: '70321',
status: 'P',
message: null
}
}
},
{
event_type: 'installment.tracker.rejected',
data: {
installment_tracker: {
id: '70322',
status: 'R',
message: 'Issuer bank rejected the installment request'
}
}
},
{
event_type: 'installment.tracker.approved',
data: {}
}
];
async function runExamples() {
for (const payload of webhookPayloads) {
const result = await handleInstallmentTrackerEvent(payload);
console.log('Processing result:', result);
}
}
runExamples();Expected output:
Installment approved for tracker 70414
Processing result: { status: 'approved', tracker_id: '70414' }
Installment pending for tracker 70321
Processing result: { status: 'pending', tracker_id: '70321' }
Installment rejected for tracker 70322: Issuer bank rejected the installment request
Processing result: {
status: 'rejected',
tracker_id: '70322',
message: 'Issuer bank rejected the installment request'
}
No installment tracker found for this event.
Processing result: { status: 'ignored' }Recommended Processing
When you receive an installment tracker update:
- Treat
data.installment_tracker.statusas the source of truth for the installment decision. - Support the
A,P, andRstatus values in your order management system. - Store
messageand notify your support or operations team when the installment tracker status isR. - Keep the original webhook payload for audit and reconciliation.
Updated 10 days ago