Sent whenever anything on a payment changes, including its status.
payment-changed tells you that something on a payment changed. It is the most frequent payout event. Subscribe to it only if you keep a full copy of each payment. If you only need to follow the payout, use payment-status-changed instead.
When it fires
- You update the payment with Update Payment, or change its tags or category.
- Payment Labs finishes setting up a new payment, for example after calculating its service fee.
- Processing updates the payment, including changes that leave
statusthe same. This includes the statuses that also fire payment-status-changed. - The payment is cancelled or expires.
- A tax withholding on the payment is reversed and its amounts change.
Rules that change the timing:
- When processing moves a payment to
WAITING_COMPLIANCE, the event can arrive later than the status change. - For a virtual payment, processing fires this event only when the payment reaches
COMPLETED. Your own edits still fire it. - One action can produce more than one delivery. A cancellation, for example, usually sends two.
What to do
- Compare
auditInfo.updatedAtwith the copy you hold. Replace your copy only if the delivery is newer. - Read
status,isEditable,isCancellableandisSubmittableto decide what your system may do next with the payment.
Payload
data is the payment as Get Payment describes it, read when the webhook is sent. Fields with no value are omitted. Amounts use the Money object.
| Field | Type | Description |
|---|---|---|
id | string | Payment ID, for example P-01JC8Z4M6Q2W3E4R5T6Y7U8I9O. |
batchId | string | ID of the batch that holds the payment. |
batchName | string | Name of that batch. |
referenceId | string | Your own reference for this payment. Use it to match the payment to a record in your system. |
status | string | Current status of the payment. See Payment statuses. |
submitted | boolean | true once the payment has been submitted for processing. |
completed | boolean | true once the payment has been paid. |
sourceAmount | Money | Amount you pay, in the payment's source currency. |
destinationAmount | Money | Amount the payee receives, in the payee's currency. Set once the conversion is known. |
refundAmount | Money | Amount returned to your ledger account after the payout came back. Set when status is RETURNED. |
ledgerAccount | string | ID of the ledger account that funds the payment. |
payeeMemo | string | Message shown to the payee with the payment. |
payorMemo | string | Internal note for your team. The payee does not see it. |
paymentCategory | string | What the payment is for. Drives tax treatment. One of online-esport-prize, in-person-esport-prize, in-person-esport-prize-out-of-jurisdiction, athlete-prize, online-misc-prize, online-contest-prize, in-person-misc-prize, in-person-contest-prize, remote-contractors, in-person-contractors, reimbursement, royalties. |
taxJurisdiction | string | Tax rules applied to the payment: us, de, fi, gb, my, pl, sa, se, or none. |
chargedServiceFee | Money | Service fee charged for this payment, in USD. |
refundedServiceFee | Money | Part of the service fee given back, in USD, for example after a cancellation. |
isServiceFeeRefundable | boolean | true if cancelling the payment now would return the service fee. |
cancellationReason | string | Why the payment was cancelled or expired. Set when status is CANCELLED or EXPIRED. |
virtualPayment | boolean | true for a virtual payment, which books fees and tax withholdings without sending money to the payee. |
isEditable | boolean | true if you can still change the payment with Update Payment. |
isCancellable | boolean | true if you can still cancel the payment with Cancel Payment. |
isSubmittable | boolean | true if you can submit the payment now: it can be submitted and the payee is payable. |
isAutoSubmittable | boolean | true if the payment can be submitted automatically later, once the payee becomes payable. |
isAutoSubmitOn | boolean | true if the payment is set to submit automatically once the payee becomes payable. |
allowedPaymentMethods | string[] | Payout methods the payee may use for this payment, for example bank-transfer-1 or paypal. Absent when every method enabled for your account is allowed. |
lastActivity | string | Date and time of the latest activity on the payment (submission, or else the last update), in ISO 8601 UTC. |
tags | object[] | Tags on the payment. Each has a key (string) and a value (string or array of strings). |
tagKeys | string[] | The keys of tags, for filtering. |
payee | object | The payee being paid. See the table below. |
payablePayee | object | The same object as payee, kept for older integrations. Read payee instead. |
auditInfo | object | Timestamps and authors. See the table below. |
payee object:
| Field | Type | Description |
|---|---|---|
id | string | Payee ID, the same value as userId. |
userId | string | Payee ID. |
payorId | string | Your payor ID. |
referenceId | string | Your reference for the payee. |
email | string | Payee's email address. |
payable | boolean | true if the payee had completed onboarding and could be paid when the payment was last updated. Subscribe to payee-payability-changed for the live value. |
currentStep | string | Onboarding step the payee must finish next: identityVerification, personalInformation, paymentMethods, or taxForms. Absent once onboarding is complete. |
onboarded | boolean | true if the payee's personal information had been accepted when the payment was last updated. It does not cover payout methods or tax forms: use payable to know whether the payee could be paid. |
auditInfo object. All dates are ISO 8601 UTC strings.
| Field | Type | Description |
|---|---|---|
createdAt | string | When the payment was created. |
createdBy | string | Who created it. |
updatedAt | string | When the payment last changed. Use it to discard deliveries older than the state you already hold. |
updatedBy | string | Who changed it last. |
submittedAt | string or null | When the payment was submitted. null until then. |
estimateDeliveryAt | string or null | When the payee is expected to receive the money. null until known. |
Payment statuses
| Status | Meaning |
|---|---|
DRAFT | Created and not submitted. You can edit, submit or cancel it. |
SUBMITTED | Submitted and queued. It stays here while funding and checks complete. |
WAITING_PAYABILITY | Submitted with auto-submit on, waiting for the payee to finish onboarding. It continues on its own once the payee is payable. |
WAITING_PAYMENT_METHOD | Waiting for the payee to add or fix a payout method. |
WAITING_COMPLIANCE | Held for a compliance review. |
RESTRICTED | Cannot be paid to the payee's country under the batch's country restrictions. |
PROCESSING | Sent to the payout network. The money is in flight. |
COMPLETED | Paid to the payee. |
FAILED | The payout attempt failed. The payment can be submitted again. |
RETURNED | Paid, then sent back by the receiving bank or provider. refundAmount shows what came back to your ledger account. The payment can be submitted again. |
CANCELLED | Cancelled. It will not be paid. |
EXPIRED | Not paid in time and closed automatically. It will not be paid. |
New statuses may be added. Treat a value you do not recognise as "in progress" and fetch the payment if you need detail.
Example
The full request body Payment Labs sends:
{
"payorId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
"event": "payment-changed",
"timestamp": "2026-03-14T15:09:26.535Z",
"data": {
"id": "P-01JC8Z4M6Q2W3E4R5T6Y7U8I9O",
"batchId": "B-01JC8Z1B2C3D4E5F6G7H8J9K0M",
"batchName": "March tournament prizes",
"referenceId": "prize-2026-03-0042",
"payee": {
"id": "U-01JBX6M2N8P4Q6R8S0T2V4W6Y8",
"userId": "U-01JBX6M2N8P4Q6R8S0T2V4W6Y8",
"payorId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
"referenceId": "player-1042",
"email": "[email protected]",
"payable": true,
"onboarded": true
},
"payablePayee": {
"id": "U-01JBX6M2N8P4Q6R8S0T2V4W6Y8",
"userId": "U-01JBX6M2N8P4Q6R8S0T2V4W6Y8",
"payorId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
"referenceId": "player-1042",
"email": "[email protected]",
"payable": true,
"onboarded": true
},
"payorMemo": "Second place, spring finals",
"auditInfo": {
"createdBy": "[email protected]",
"updatedBy": "[email protected]",
"createdAt": "2026-03-14T14:02:11.000Z",
"updatedAt": "2026-03-14T15:09:25.120Z",
"submittedAt": "2026-03-14T14:30:00.000Z",
"estimateDeliveryAt": "2026-03-16T14:30:00.000Z"
},
"isAutoSubmitOn": false,
"submitted": true,
"completed": false,
"sourceAmount": {
"value": 1250,
"wholeValue": 125000,
"currency": "USD",
"formattedValue": "$1,250.00",
"digits": 2
},
"status": "PROCESSING",
"paymentCategory": "online-esport-prize",
"payeeMemo": "Congratulations on your spring finals result",
"ledgerAccount": "01JB2Y7X6W5V4U3T2S1R0Q9P8N",
"virtualPayment": false,
"tagKeys": [
"season"
],
"tags": [
{
"key": "season",
"value": "spring-2026"
}
],
"chargedServiceFee": {
"value": 2.5,
"wholeValue": 250,
"currency": "USD",
"formattedValue": "$2.50",
"digits": 2
},
"taxJurisdiction": "us",
"destinationAmount": {
"value": 1250,
"wholeValue": 125000,
"currency": "USD",
"formattedValue": "$1,250.00",
"digits": 2
},
"lastActivity": "2026-03-14T14:30:00.000Z",
"isAutoSubmittable": false,
"isSubmittable": false,
"isEditable": false,
"isCancellable": false,
"isServiceFeeRefundable": false
}
}