ChargeBack

Handle chargeback dispute webhook events and use disputed_status to identify the order dispute status.

Use the order.disputed webhook event to identify when an order enters or changes chargeback dispute status.

Chargeback Dispute Webhook

Amwal sends the order.disputed webhook when an order is associated with a chargeback dispute. Your webhook handler should read the disputed_status field from the webhook payload to identify the current chargeback status for the order.

Store the dispute status against the related order in your system so your operations, support, or finance teams can track the chargeback lifecycle.

Event Type

FieldTypeDescription
event_typestringThe webhook event name. For chargebacks, this is order.disputed.
dataobjectThe order payload associated with the dispute.
data.disputed_statusstringThe current chargeback dispute status for the order. Use this value to identify the chargeback status.
data.idstringThe Amwal order ID associated with the dispute, when included in the payload.
data.ref_idstringThe merchant reference ID associated with the order, when included in the payload.

Dispute Status Values

The data.disputed_status field can contain one of these values:

ValueDescription
PENDINGThe chargeback dispute is open or waiting for a final result.
RESOLVEDThe chargeback dispute has been resolved.
LOSTThe chargeback dispute was lost.

Example Payload

The order.disputed webhook includes the order or transaction payload in data. The sample below shows a dispute payload where disputed_status is RESOLVED.

{
  "event_type": "order.disputed",
  "data": {
    "id": "order_123456789",
    "ref_id": "merchant-order-1001",
    "status": "success",
    "disputed_status": "RESOLVED",
    "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": "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",
    "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,
    "payment_link_id": "",
    "payment_link_callback_url": "",
    "payment_link_description": "",
    "payment_link_only_show_pay_in_full": true,
    "payment_link_only_show_bank_installments": true,
    "payment_link_passkey_enabled": true
  }
}

Use the exact data.disputed_status value from the payload when updating the order in your system. Other fields in data provide transaction, customer, merchant, payment, and shipping context that you can store for reconciliation or support workflows.

Handle an order.disputed Event

  1. Receive the webhook request on your configured webhook endpoint.
  2. Verify that event_type is order.disputed.
  3. Read data.disputed_status from the payload.
  4. Update the matching order in your system with the latest dispute status.
  5. Return HTTP 200 after your system accepts the event.
function processEvent(webhook) {
  if (webhook.event_type !== 'order.disputed') {
    return {
      accepted: false,
      reason: `Unsupported event type: ${webhook.event_type}`
    };
  }

  const order = webhook.data;

  if (!order || !order.disputed_status) {
    return {
      accepted: false,
      reason: 'Missing disputed_status in order.disputed payload.'
    };
  }

  return {
    accepted: true,
    eventType: webhook.event_type,
    orderId: order.id || null,
    refId: order.ref_id || null,
    disputedStatus: order.disputed_status
  };
}

Expected result after processing the event:

{
  "accepted": true,
  "eventType": "order.disputed",
  "orderId": "<amwal_order_id>",
  "refId": "<merchant_reference_id>",
  "disputedStatus": "<dispute_status_from_payload>"
}

Recommended Processing

When you receive an order.disputed event:

  • Treat data.disputed_status as the source of truth for the order’s chargeback status.
  • Support the PENDING, RESOLVED, and LOST status values in your order management system.
  • Save the latest disputed_status value on the related order record.
  • Keep the original webhook payload for audit and reconciliation.
  • Notify the relevant internal team when the dispute status changes.
  • Return 400 if the payload is missing data.disputed_status.

Related Webhook Documentation

For webhook endpoint setup, request handling, and response requirements, see Receiving Webhook Events.