Invoices
Invoices record what Paypercut attempted to collect for a billing period. Use them to reconcile subscription charges, provision access after a successful payment, and recover when a recurring payment fails.
Invoices are created by billing flows such as subscription creation, subscription renewal, and automatic retry attempts. The invoice object returned by the API is the same object sent in invoice webhook events.
How invoices fit into subscriptions
A subscription controls the recurring agreement with the customer: items, prices, billing interval, trial state, and cancellation rules. An invoice records a specific billing period and the payment attempts made to collect it.
For a subscription renewal, the flow is:
- Paypercut reaches the next billing date for the subscription.
- Paypercut creates an invoice for the billing period and subscription items.
- Paypercut attempts to collect the invoice using the subscription payment method.
- Paypercut sends an invoice event with the invoice in
data.object. - Your integration updates access, fulfillment, notifications, or recovery state based on the event type.
Invoice events
Subscribe to invoice events when your system needs to react to recurring billing outcomes.
| Event | When it is sent | Typical action |
|---|---|---|
invoice.paid |
The invoice was successfully paid. | Grant or continue access, mark the billing period as paid, and fulfill any subscription delivery tied to the period. |
invoice.payment_failed |
Paypercut attempted to collect payment for the invoice and the attempt failed. | Notify the customer, prompt for a new payment method, and keep access behavior aligned with the subscription status. |
The event data.object is the invoice resource. Use data.object.id as the invoice identifier and data.object.parent.subscription_details.subscription to connect the invoice back to the subscription when the invoice was generated from subscription billing.
{
"id": "01KA9TBINVOICEPAID123456",
"type": "invoice.paid",
"created": "2026-03-01T00:00:12Z",
"livemode": true,
"data": {
"object": {
"id": "01KA9TBINVOICE123456789",
"object": "invoice",
"customer": "01KA9SXYZ123456789ABCDEFGH",
"status": "paid",
"billing_reason": "subscription_cycle",
"collection_method": "charge_automatically",
"currency": "USD",
"amount_due": 2000,
"amount_paid": 2000,
"amount_remaining": 0,
"parent": {
"type": "subscription_details",
"subscription_details": {
"subscription": "01KA9TSUBSCRIPTION123"
}
}
}
}
}
Handle paid invoices
Treat invoice.paid as the billing signal that the invoice amount has been collected.
Common actions:
- Mark the billing period as paid in your system.
- Grant or continue access for the subscription period in
period.startandperiod.end. - Fulfill the product, media, or delivered resource associated with the invoice line.
- Store the invoice ID so repeated webhook deliveries do not trigger duplicate fulfillment.
If your integration receives a separate event when delivered media or a delivered resource expires, process it as a resource lifecycle event. Use the event type as the action and the data.object payload as the resource that changed. Do not infer expiry from invoice.paid; invoices describe billing state, while delivered resources describe access or fulfillment state.
Handle failed invoice payments
Treat invoice.payment_failed as the signal that Paypercut could not collect the invoice on that attempt.
Common actions:
- Notify the customer that payment failed.
- Ask the customer to update their payment method.
- Keep access behavior aligned with your subscription rules and the subscription status.
- Inspect
payments.datato see the failed invoice payment attempt. - Use
amount_remainingto show the outstanding amount.
Payment failures can happen on the first invoice or on a renewal invoice. Use the invoice parent and billing_reason fields to decide which recovery flow to show in your product.
An invoice.payment_failed event does not mean the invoice status is payment_failed. The invoice usually remains open while payment is still due, and the failed attempt appears in payments.data.
Invoice object
Important fields for integrations:
| Field | Description |
|---|---|
id |
Unique invoice identifier. |
status |
Current invoice lifecycle status, such as open, paid, void, or uncollectible. |
customer |
Customer associated with the invoice. In the API reference, pass expand[]=customer to return the full Customer object. |
amount_due, amount_paid, amount_remaining |
Monetary totals in the smallest currency unit. |
period |
Billing period covered by the invoice. |
parent |
Resource that caused the invoice to be created. Subscription invoices include subscription_details.subscription. |
lines |
Invoice line items. Each line can include pricing and subscription item details. |
payments |
Payment attempts made to collect the invoice. |
status_transitions |
Timestamps for lifecycle transitions such as finalization and payment. |
metadata |
Merchant-defined key-value data copied onto the invoice. |
Implementation checklist
- Configure a webhook endpoint and subscribe to
invoice.paidandinvoice.payment_failed. - Verify webhook signatures before parsing the event.
- Process webhook events idempotently by storing the event ID or invoice ID and event type.
- Retrieve the invoice from the API when your handler needs the latest state before making a customer-visible decision.
- Keep billing state separate from fulfillment state when you also consume delivered or expired resource events.

