Accounting Operation — This webhook fires on settlement lifecycle events (completion, refund, refund cancellation). It reports money movements between your
pending_balance, available_balance, and your bank account.Information
POST request to your configured settlement_notif_url whenever a settlement batch reaches a final state, or when a settled transaction is refunded / has its refund cancelled.
This webhook may share a callback URL with other event types. Always route by the
event value in the body. See Shared webhook endpoints.Events
This single webhook covers three settlement events, distinguished by theevent field:
Settlement currently supports money-in transactions only (Virtual Account, QRIS, Payment Link, E-Wallet). Refund events apply only to settlements using the
balance or auto-balance method.Request Details
Headers
The
Authorization token for settlement webhooks is a randomly generated string — not a user access token. Settlement events are triggered by an admin approval, a scheduler, or a refund action (system events), not a user request. Extract the token as-is and use it in the string to sign. See Security and signature validation.Body Parameters — common envelope
Every settlement webhook shares the same top-level envelope:number
required
HTTP Status Code. Always
200.boolean
required
Indicates a successful event. Always
true.string
required
Event type identifier. One of
"settlement.completed", "settlement.refunded", "settlement.refund_cancelled".string
required
Event timestamp in format
"d M Y H:i:s". Example: "18 Jun 2026 10:00:00"object
required
Container for the settlement details (and, for refund events, the refund details).
data.settlement (present on all events)
object
required
The settlement batch the event relates to.
data.total_transactions (settlement.completed only)
integer
required
Number of transactions included in the completed settlement batch. Example:
5data.refund (settlement.refunded & settlement.refund_cancelled only)
object
required
Details of the individual transaction that was refunded or had its refund cancelled.
Payload Examples
settlement.completed
settlement.completed (bank-account)
settlement.refunded
settlement.refund_cancelled
Security and responses
Return HTTP200 promptly after validating the request. For retry behavior, see Webhook retry mechanism.
Verify every webhook using Security and signature validation. Use your configured settlement_notif_url path when building StringToSign.
Handle duplicate deliveries idempotently using stable identifiers from the payload — for settlement.completed use data.settlement.reference_no; for refund events combine data.settlement.reference_no with data.refund.settlement_detail_id (and the event).
Settlement Specific Notes
One callback URL, three events
One callback URL, three events
All three events are delivered to the same
settlement_notif_url. Always branch on the event field. A settlement.completed payload has total_transactions; refund events have a refund object instead.Sequential vs auto settlement
Sequential vs auto settlement
is_auto_created = false means a sequential settlement approved by Finance (approved_by is the approver’s name). is_auto_created = true means a parallel auto settlement created by the scheduler (approved_by = "SYSTEM"). Both arrive as settlement.completed.amount vs total_to_transfer
amount vs total_to_transfer
amount is the total net amount of the settled transactions. total_to_transfer is what was actually moved out — amount - settlement_fee. The settlement_fee is only non-zero for the bank-account method.Refunds only for balance methods
Refunds only for balance methods
settlement.refunded and settlement.refund_cancelled fire only for settlements using the balance or auto-balance method. Refund deducts (and cancel restores) the transaction’s net amount from your available_balance — fees are not refunded.Refund state via flags
Refund state via flags
Track refund state with
is_refunded and is_refund_cancelled. An active refund is is_refunded=true, is_refund_cancelled=false. A cancelled refund is is_refunded=true, is_refund_cancelled=true — note is_refunded stays true.Nullable fields
Nullable fields
transfer_status and the recipient.* fields are populated only for the bank-account method and are null for all other methods. Actor fields (refunded_by, refund_cancelled_by, actor) and account_id may be null. Handle null gracefully.Timestamp format & timezone
Timestamp format & timezone
All timestamps (
timestamp, approved_at, start_date, end_date, refunded_at, refund_cancelled_at) use the format "d M Y H:i:s" (e.g. "18 Jun 2026 10:00:00") in Asia/Jakarta (WIB) timezone — not UTC.