Amwal Tech logoDocs

Refund an Installment

Issue full or partial refunds for completed bank installment transactions. Amwal coordinates with the customer's issuing bank to adjust or cancel future installment billings.


Refund State Flow

A 200 response only means the refund was accepted — settlement happens afterward and asynchronously. The diagram below covers request-time validation, the PR settlement path, the known issue with repeated refunds on the same transaction, and the resulting status changes on both the transaction and the payment link.

Rendering diagram...

Multiple Partial Refunds (1-Hour Window)

When you submit multiple partial refund requests for the same transaction ID within one hour, the first request is marked as Refunded and subsequent requests are marked as Pending. This behavior is identical in both sandbox and live environments.


Endpoint

POST /transactions/refund/{transaction_id}/

Trailing slash is required

The trailing slash after {transaction_id} is not optional. Omitting it returns an HTTP redirect instead of processing the refund.

Path Parameters

ParameterTypeRequiredDescription
transaction_idString (UUID)YesThe unique Transaction UUID to refund (e.g. 60b43176-5991-4475-8ef6-c73c2417c805).

Request Headers

Pass your merchant public key in the required X-Amwal-Key header:

  • Sandbox: X-Amwal-Key: sandbox-amwal-xxx
  • Production: X-Amwal-Key: prod-amwal-xxx
Authorization: YOUR_SECRET_KEY
X-Amwal-Key: sandbox-amwal-xxx
Content-Type: application/json
HeaderTypeRequiredDescription
AuthorizationStringYesYour Amwal Secret Key (e.g. <YOUR_SECRET_KEY_UUID>).
X-Amwal-KeyStringYesMerchant Public Key (sandbox-amwal-xxx in Sandbox, prod-amwal-xxx in Production).
Content-TypeStringYesMust be set to application/json.

Request Body

{
  "refund_amount": 100.00,
  "reason": "Customer returned partial order items",
  "metadata": {
    "rma_number": "RMA-9842"
  }
}

Request Parameters

FieldTypeRequiredDescription
refund_amountNumberYesAmount to refund in SAR. Rejected with 400 if it exceeds the transaction's remaining refundable balance.
reasonStringNoInternal audit reason for the refund.
metadataObjectNoOptional merchant tracking metadata (e.g. rma_number).

Response (200 OK)

{
  "status": "success",
  "key_type": "RefundReference",
  "key": "2026001726"
}

Response Parameters

FieldTypeDescription
statusStringOutcome of the refund acceptance: "success".
key_typeStringReference identifier type: "RefundReference".
keyStringGateway-generated refund reference tracking number (e.g. "2026001726"). Use this reference for bank inquiry and audit tracking.

key is the gateway's refund reference number. This response confirms the refund was accepted by the gateway. To inspect the resulting transaction state, remaining balance, and settlement progress, call Get Payment Link Details or Get Transaction Details. Once applied, the transaction's status becomes partially refunded or refunded (see Transaction Status), its refunded_amount reflects the total refunded so far, and a refund_tracker array is populated with one entry per refund (including the gateway transaction id and RRN).


Settlement Is Asynchronous & Multiple Partial Refunds

A successful 200 response confirms that the refund request was accepted by Amwal. Settlement with the customer's issuing bank happens afterward.

Refund Tracker Statuses

You can inspect the status of each refund entry in the transaction's refund_tracker array:

refund_tracker[].statusMeaningDescription
RRefunded (Settled)The refund has completed and settled. The bank's Retrieval Reference Number (rrn) is populated.
PPendingThe refund has been accepted and is queued for settlement at the card gateway or bank.

Multiple Partial Refunds within One Hour

When you submit multiple partial refund requests for the same transaction ID within one hour:

  1. First Request: The first request is processed and marked as Refunded (status: "R" upon settlement).
  2. Subsequent Requests: Subsequent requests within that 1-hour window are accepted and marked as Pending (status: "P").
  3. Consistent Behavior: This behavior is identical across both sandbox and live production environments.
{
  "refund_tracker": [
    {
      "amount": 50.0,
      "status": "R",
      "rrn": "2026001726",
      "created_at": "2026-09-02T10:00:00Z"
    },
    {
      "amount": 25.0,
      "status": "P",
      "rrn": null,
      "created_at": "2026-09-02T10:15:00Z"
    }
  ]
}

Tracking Settlement & Webhook Notifications

The top-level refunded_amount updates immediately with the sum of all accepted refund amounts. To monitor individual settlement transitions from P (Pending) to R (Refunded), inspect the refund_tracker array via Get Transaction Details or listen for order.updated webhook events.

Pending Refund Processing by Environment

  • Live environment: The Finance team reviews pending refund requests and processes them as appropriate. You receive an order.updated webhook notification when the refund status changes. If a refund remains pending for 24 business hours, contact Amwal support so we can take further action.
  • Sandbox environment: Pending refunds are not processed automatically. To test the related webhook event, share the transaction IDs with Amwal support so we can process the pending refunds.

Errors

StatusBodyCause
400{"message": "Maximum amount to be refunded is <amount>", "validation_errors": [...], "fields_errors": []}refund_amount exceeds the transaction's remaining refundable balance.
400{"message": "Your balance is not sufficient to initiate any refund process. You can retry when you have a balance exceeding the amount you are trying to refund.", "validation_errors": [{"Name": "Supplier", "Error": "Insufficient balance for supplier <id>"}], "fields_errors": []}merchant/supplier account does not have enough available balance to cover this refund — a separate check from the transaction-level remaining-balance one above. Retry once your balance is sufficient.
400{"message": "The transaction is already under processing!", "validation_errors": [{"Name": "Key", "Error": "The transaction is already under processing!"}], "fields_errors": []}A previous refund on this same transaction hasn't finished processing yet. Transient — retrying after a short delay (a few seconds) usually succeeds. See the "Refund State Flow" diagram above and "Settlement Is Asynchronous" section below.
403{"detail": "You are not allowed to refund this transaction"}transaction_id does not exist, or does not belong to the authenticated merchant. Note this is 403, not 404.
403{"detail": "This transaction is not refundable"}The transaction is outside the refund eligibility window — see "Refund Time Window" below. Same response shape as the row above; check how old the transaction is to tell the two apart.

Important Notes

TopicDetail
Sufficient balanceYour merchant account must have enough available balance to process a refund (see the "Insufficient balance for supplier" error above).
Online refundsTypically take 3–5 business days to settle once accepted.
Bank installment refundsProcessing time varies, usually 5–7 business days.
Refund time windowRefunds are only accepted within 60–90 days of the original transaction. An older transaction returns 403 {"detail": "This transaction is not refundable"}.
Reference trackingKeep the key value from the 200 response — it's the gateway's refund reference and is what customer service will need to look up the refund later.

On this page