Invoices and payment collection
Invoices are the billing-period record for subscription integrations. Use invoice events to decide when a paid period exists, when access should be extended, and when payment recovery should begin.
What this page covers
- Why subscriptions create invoices
- What
invoice.paidmeans - What
invoice.payment_failedmeans - How invoice and payment state should affect access decisions
- How Payment and PaymentIntent events fit into reconciliation
Before you use this page
Read How subscriptions work and choose a creation flow. For the beginner path, start with Create subscriptions with Checkout.
Why invoices matter
A subscription describes the recurring agreement. An invoice describes a specific billing period and the payment attempts made to collect it.
For a subscription integration, your backend should treat invoices as the billing-period source of truth:
- A subscription reaches a billing moment.
- Paypercut creates or updates an invoice for that billing period.
- Paypercut attempts to collect payment.
- Paypercut sends an invoice event.
- Your backend grants, extends, or recovers access based on the event and latest state.
Initial and renewal invoices
Subscription-related invoices can represent different billing moments:
| Billing moment | Typical meaning |
|---|---|
| Initial subscription billing | First paid period for a new subscription. |
| Renewal billing | A later billing period for an existing subscription. |
| Retry or recovery attempt | Another attempt to collect an invoice that was not paid. |
Use the invoice parent and billing_reason fields when you need to understand why the invoice exists. Subscription invoices include parent subscription details that let you connect the invoice back to the subscription.
invoice.paid
Use invoice.paid as the main paid-period signal.
When your backend receives invoice.paid:
- Verify the webhook signature.
- Process the event idempotently.
- Read the invoice ID from
data.object.id. - Read the linked subscription from
data.object.parent.subscription_details.subscriptionwhen present. - Map the subscription to your internal user or account.
- Grant or extend access for the paid billing period.
- Store the invoice ID and processing result.
Do not process a paid invoice twice if the webhook is delivered more than once.
invoice.payment_failed
Use invoice.payment_failed as the payment recovery signal.
When your backend receives invoice.payment_failed:
- Verify the webhook signature.
- Process the event idempotently.
- Identify the invoice and linked subscription.
- Fetch the latest invoice or subscription state if your access decision depends on current status.
- Notify the customer or show recovery UI.
- Keep access behavior aligned with your product policy and subscription state.
An invoice payment failure means collection failed for that attempt. It does not mean every subscription should immediately lose access. Define your access policy and reconcile against latest state before taking customer-visible action.
Payment and PaymentIntent events
Payment and PaymentIntent events can help support teams debug payment attempts, provider responses, and reconciliation. They are not the main subscription access contract for the beginner path.
Use invoice events for subscription billing-period decisions because invoices connect the billing period, customer, subscription, amount, status, and payment attempts.
Access decisions
| Situation | Recommended backend action |
|---|---|
invoice.paid for a subscription invoice |
Grant or extend access idempotently. |
invoice.payment_failed |
Start recovery and fetch latest state before changing access. |
| Payment event without invoice context | Use for support or reconciliation; do not grant subscription access from this alone. |
| Browser success redirect | Show pending or confirmation UI; do not grant production access from this alone. |
Troubleshooting
| Symptom | Check |
|---|---|
| Paid customers do not receive access | Confirm invoice.paid is subscribed, delivered, signature-verified, and mapped to the internal account. |
| Access is granted twice | Store processed event IDs or invoice IDs with the action taken. |
| Failed renewals are missed | Confirm invoice.payment_failed is enabled for the webhook endpoint. |
| Support cannot match a payment to a subscription | Use invoice parent subscription details and invoice payment data before falling back to payment-level events. |
Unsupported in this beginner path
Do not document or build this path around send_invoice. The current beginner subscription flow uses automatic collection with Checkout and invoice events.

