payment-changed

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 status the 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.updatedAt with the copy you hold. Replace your copy only if the delivery is newer.
  • Read status, isEditable, isCancellable and isSubmittable to 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.

FieldTypeDescription
idstringPayment ID, for example P-01JC8Z4M6Q2W3E4R5T6Y7U8I9O.
batchIdstringID of the batch that holds the payment.
batchNamestringName of that batch.
referenceIdstringYour own reference for this payment. Use it to match the payment to a record in your system.
statusstringCurrent status of the payment. See Payment statuses.
submittedbooleantrue once the payment has been submitted for processing.
completedbooleantrue once the payment has been paid.
sourceAmountMoneyAmount you pay, in the payment's source currency.
destinationAmountMoneyAmount the payee receives, in the payee's currency. Set once the conversion is known.
refundAmountMoneyAmount returned to your ledger account after the payout came back. Set when status is RETURNED.
ledgerAccountstringID of the ledger account that funds the payment.
payeeMemostringMessage shown to the payee with the payment.
payorMemostringInternal note for your team. The payee does not see it.
paymentCategorystringWhat 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.
taxJurisdictionstringTax rules applied to the payment: us, de, fi, gb, my, pl, sa, se, or none.
chargedServiceFeeMoneyService fee charged for this payment, in USD.
refundedServiceFeeMoneyPart of the service fee given back, in USD, for example after a cancellation.
isServiceFeeRefundablebooleantrue if cancelling the payment now would return the service fee.
cancellationReasonstringWhy the payment was cancelled or expired. Set when status is CANCELLED or EXPIRED.
virtualPaymentbooleantrue for a virtual payment, which books fees and tax withholdings without sending money to the payee.
isEditablebooleantrue if you can still change the payment with Update Payment.
isCancellablebooleantrue if you can still cancel the payment with Cancel Payment.
isSubmittablebooleantrue if you can submit the payment now: it can be submitted and the payee is payable.
isAutoSubmittablebooleantrue if the payment can be submitted automatically later, once the payee becomes payable.
isAutoSubmitOnbooleantrue if the payment is set to submit automatically once the payee becomes payable.
allowedPaymentMethodsstring[]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.
lastActivitystringDate and time of the latest activity on the payment (submission, or else the last update), in ISO 8601 UTC.
tagsobject[]Tags on the payment. Each has a key (string) and a value (string or array of strings).
tagKeysstring[]The keys of tags, for filtering.
payeeobjectThe payee being paid. See the table below.
payablePayeeobjectThe same object as payee, kept for older integrations. Read payee instead.
auditInfoobjectTimestamps and authors. See the table below.

payee object:

FieldTypeDescription
idstringPayee ID, the same value as userId.
userIdstringPayee ID.
payorIdstringYour payor ID.
referenceIdstringYour reference for the payee.
emailstringPayee's email address.
payablebooleantrue 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.
currentStepstringOnboarding step the payee must finish next: identityVerification, personalInformation, paymentMethods, or taxForms. Absent once onboarding is complete.
onboardedbooleantrue 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.

FieldTypeDescription
createdAtstringWhen the payment was created.
createdBystringWho created it.
updatedAtstringWhen the payment last changed. Use it to discard deliveries older than the state you already hold.
updatedBystringWho changed it last.
submittedAtstring or nullWhen the payment was submitted. null until then.
estimateDeliveryAtstring or nullWhen the payee is expected to receive the money. null until known.

Payment statuses

StatusMeaning
DRAFTCreated and not submitted. You can edit, submit or cancel it.
SUBMITTEDSubmitted and queued. It stays here while funding and checks complete.
WAITING_PAYABILITYSubmitted with auto-submit on, waiting for the payee to finish onboarding. It continues on its own once the payee is payable.
WAITING_PAYMENT_METHODWaiting for the payee to add or fix a payout method.
WAITING_COMPLIANCEHeld for a compliance review.
RESTRICTEDCannot be paid to the payee's country under the batch's country restrictions.
PROCESSINGSent to the payout network. The money is in flight.
COMPLETEDPaid to the payee.
FAILEDThe payout attempt failed. The payment can be submitted again.
RETURNEDPaid, then sent back by the receiving bank or provider. refundAmount shows what came back to your ledger account. The payment can be submitted again.
CANCELLEDCancelled. It will not be paid.
EXPIREDNot 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
  }
}