subscription-payment-status-changed

Sent as each subscription billing cycle is charged, succeeds or fails.

subscription-payment-status-changed follows the payment for one billing cycle of a subscription. Each cycle has its own subscription payment, with an ID that starts with RP-.

When it fires

  • A billing cycle is due. Payment Labs creates the cycle's payment and charges the subscription's instrument. The payment is PENDING.
  • A charge attempt succeeds: the payment becomes COMPLETED.
  • A charge attempt fails: the payment becomes FAILED.

A failed cycle is retried about 24 hours later, up to three attempts within four days. Each retry sends this event again, so a payment can go from FAILED to COMPLETED. Treat FAILED as final only once subscription-status-changed reports the subscription as OVERDUE.

Refunds do not fire this event. Follow them with refund-status-changed.

What to do

data.statusSuggested action
PENDINGNo action.
COMPLETEDRecord the cycle as paid.
FAILEDOptionally ask the buyer to update their payment method. Payment Labs retries on its own.

Payload

data is the subscription payment as List Subscription Payments describes it, read when the webhook is sent. Fields with no value are omitted. Amounts use the Money object.

FieldTypeDescription
idstringSubscription payment ID, for example RP-01JD6B2D4F6H8K0M2P4R6T8V0X.
statusstringPENDING (due or being charged), COMPLETED (paid) or FAILED (the latest attempt failed).
subscriptionIdstringID of the subscription.
subscriptionPlanIdstringID of the subscription's plan.
subscriptionPlanNamestringName of that plan.
merchantIdstringYour merchant ID.
userIdstringID of the buyer.
dueDatestringBilling date of this cycle, as YYYY-MM-DD.
amountMoneyAmount charged for this cycle.
checkoutInstrumentIdstringID of the card or account charged.
instrumentTypestringType of that instrument, for example payment-card-3. Same values as enabledCheckoutInstruments on checkout-status-changed.
checkoutIdstringID of the checkout used to charge this cycle.
hasRefundsbooleantrue once a refund has been created for this payment.

Example

The full request body Payment Labs sends:

{
  "payorId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
  "event": "subscription-payment-status-changed",
  "timestamp": "2026-04-01T00:11:05.731Z",
  "data": {
    "id": "RP-01JD6B2D4F6H8K0M2P4R6T8V0X",
    "subscriptionPlanId": "RD-01JD49X1Z3B5D7F9H1K3M5P7R9",
    "subscriptionPlanName": "Monthly membership",
    "merchantId": "C-01JBX2Q8F4H6K8M0N2P4R6T8VW",
    "userId": "U-01JBX5K7M9P1Q3R5S7T9V1W3X5",
    "subscriptionId": "R-01JD5A1C3E5G7J9L1N3Q5S7U9W",
    "dueDate": "2026-04-01",
    "checkoutInstrumentId": "SI-01JD3K7M9P1R3T5V7X9Z1B3D5F",
    "instrumentType": "payment-card-3",
    "amount": {
      "value": 19.99,
      "wholeValue": 1999,
      "currency": "USD",
      "formattedValue": "$19.99",
      "digits": 2
    },
    "status": "COMPLETED",
    "hasRefunds": false,
    "checkoutId": "S-01JD6B1C3E5G7J9L1N3Q5S7U9W"
  }
}