refund-status-changed

Sent as a refund is processed and when it completes or fails.

refund-status-changed follows a refund after you create it. It covers refunds of checkouts and of subscription payments.

When it fires

You create a refund with Refund Checkout Transaction or Refund Subscription Payment. The refund starts in PENDING, and the response to that call tells you so. No event is sent for PENDING. After that, the event fires when the refund:

  • moves to PROCESSING: it was sent to the card network or bank;
  • moves to COMPLETED: the money was returned to the buyer;
  • moves to FAILED: the refund was refused. errorReason says why. A refund can fail straight from PENDING, without passing through PROCESSING.

The same status can be delivered more than once.

What to do

data.statusSuggested action
PROCESSINGNo action.
COMPLETEDRecord the refund as done and tell the buyer if you need to.
FAILEDRead errorReason. Fix the cause and create a new refund, or settle with the buyer another way.

Payload

data is the refund as Get Refund describes it, read when the webhook is sent. Fields with no value are omitted. Amounts use the Money object.

FieldTypeDescription
idstringRefund ID, for example RF-01JD4M2P4R6T8V0X2Z4B6D8F0H.
statusstringPENDING, PROCESSING, COMPLETED or FAILED. See the table above.
typestringWhat was refunded: CHECKOUT (a checkout payment) or SUBSCRIPTION (a subscription payment).
amountMoneyAmount refunded, in the currency of the original charge.
reasonstringThe reason you gave when you created the refund.
errorReasonstringWhy the refund failed. Set when status is FAILED. See the table below.
merchantIdstringYour merchant ID.
buyerIdstringID of the buyer who receives the refund.
buyerEmailstringBuyer's email address.
originalTransactionIdstringID of the charge attempt being refunded. Set for checkout refunds.
checkoutIdstringID of the refunded checkout. Set for checkout refunds.
checkoutAliasstringAlias of that checkout.
subscriptionIdstringID of the subscription, when the refunded charge belongs to one.
subscriptionPaymentIdstringID of the refunded subscription payment, for example RP-01JD2T4V6X8Z0B2D4F6H8K0M2P.
subscriptionPaymentTransactionIdstringID of the subscription payment's charge attempt being refunded.
subscriptionPlanNamestringName of the subscription's plan.
auditInfoobjectcreatedAt, updatedAt (ISO 8601 UTC), createdBy and updatedBy.

errorReason values:

ValueMeaning
INVALID_TRANSACTION_STATUSThe original charge is not in a state that can be refunded.
INVALID_REFUND_TRANSACTION_STATUSThe refund is not in a state that can be processed.
CANNOT_REFUND_MORE_THAN_ORIGINAL_AMOUNTTogether with earlier refunds, this refund is larger than the original charge.
CANNOT_PARTIALLY_REFUNDThe payment method only supports refunding the full amount.
REFUND_NOT_SUPPORTEDThe payment method does not support refunds.
REFUND_REJECTEDThe card network or bank refused the refund.
REFUND_NOT_FOUNDThe refund could not be found while it was being processed.
UNKNOWN_ERRORThe refund failed for an unexpected reason. Contact Payment Labs support.

Example

The full request body Payment Labs sends:

{
  "payorId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
  "event": "refund-status-changed",
  "timestamp": "2026-04-05T10:02:51.118Z",
  "data": {
    "id": "RF-01JD4M2P4R6T8V0X2Z4B6D8F0H",
    "amount": {
      "value": 89.99,
      "wholeValue": 8999,
      "currency": "USD",
      "formattedValue": "$89.99",
      "digits": 2
    },
    "reason": "Buyer cancelled the membership within 7 days",
    "status": "COMPLETED",
    "type": "CHECKOUT",
    "merchantId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
    "buyerId": "U-01JBX5K7M9P1Q3R5S7T9V1W3X5",
    "buyerEmail": "[email protected]",
    "auditInfo": {
      "createdAt": "2026-04-05T09:58:12.000Z",
      "createdBy": "[email protected]",
      "updatedAt": "2026-04-05T10:02:50.640Z",
      "updatedBy": "[email protected]"
    },
    "originalTransactionId": "ST-01JD3K8Q2S4U6W8Y0A2C4E6G8J",
    "checkoutId": "S-01JD3K5N7P9R1T3V5X7Z9B1D3F",
    "checkoutAlias": "Order 5521"
  }
}