*** title: Billing overview subtitle: 'Manage subscriptions, invoices, and payment collection for recurring revenue.' ----------------------------------------------------------------------------------------- # How billing works PaymentKit handles recurring billing through three connected concepts: customers hold payment methods, subscriptions define billing schedules, and invoices track amounts owed. ```mermaid flowchart LR subgraph Setup C[Customer] --> PM[Payment Method] P[Product] --> PR[Price] end subgraph Billing S[Subscription] --> I[Invoice] I --> PAY[Payment] end PM --> S PR --> S ``` When you create a subscription, PaymentKit: 1. Generates an invoice for the first billing period 2. Attempts payment using the customer's default payment method 3. Schedules the next billing cycle automatically 4. Handles failures with smart retries and recovery emails # Subscription states Every subscription exists in one of seven states. PaymentKit transitions subscriptions between states based on payment outcomes and scheduled events. ```mermaid stateDiagram-v2 [*] --> Incomplete: Created [*] --> Scheduled: Future start Incomplete --> Trialing: Trial begins Incomplete --> Active: Payment succeeds Incomplete --> Cancelled: Payment fails Scheduled --> Trialing: Start date + trial Scheduled --> Active: Start date arrives Trialing --> Active: Trial ends Trialing --> Paused: Pause requested Trialing --> Cancelled: Cancel requested Active --> Active: Renewal succeeds Active --> PastDue: Payment fails Active --> Paused: Pause requested Active --> Cancelled: Cancel requested PastDue --> Active: Payment recovered PastDue --> Cancelled: Dunning exhausted Paused --> Active: Resume Paused --> Trialing: Resume during trial Paused --> Cancelled: Cancel requested Cancelled --> [*] ``` | State | Description | | -------------- | ---------------------------------------------------------------------------- | | **Incomplete** | Subscription created but awaiting initial payment. | | **Scheduled** | Subscription scheduled for a future start date. | | **Trialing** | Free trial period is active. No charges until the trial ends. | | **Active** | Normal billing cycle. Invoices generated and payments collected on schedule. | | **Past due** | Payment failed. The dunning system retries collection automatically. | | **Paused** | Billing temporarily suspended. No invoices generated while paused. | | **Cancelled** | Subscription terminated. No further billing. This is a terminal state. | # Create a subscription Start billing a customer by creating a subscription with one or more prices. 1. Go to **Billing > Subscriptions** 2. Click **Create Subscription** 3. Select a customer 4. Add prices with quantities 5. Set billing interval and start date 6. Click **Create** ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "customer_id": "cus_abc123", "currency": "USD", "period_start": "2026-02-01T00:00:00Z", "billing_interval": "month", "billing_interval_count": 1, "collection_method": "charge_automatically", "items": [ {"price_id": "price_monthly_pro", "quantity": 1} ] }' ``` ```python from paymentkit import PaymentKit client = PaymentKit(api_key="sk_live_...") subscription = client.subscriptions.create( account_id="acc_abc123", customer_id="cus_abc123", currency="USD", period_start="2026-02-01T00:00:00Z", billing_interval="month", billing_interval_count=1, collection_method="charge_automatically", items=[ {"price_id": "price_monthly_pro", "quantity": 1} ] ) ``` See [Create a subscription](/guides/billing/subscription-create) for trial periods, discounts, and fixed-term options. # Pause a subscription Temporarily stop billing without cancelling. The customer retains access through the paid period, and billing resumes automatically or on request. ## Pause immediately ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/pause \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "pause_behavior": "pause_immediately" }' ``` ## Pause at period end Let the customer use the service through the paid period, then pause: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/pause \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "pause_behavior": "pause_at_end" }' ``` ## Auto-resume after a duration Pause for a set number of billing cycles: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/pause \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "pause_behavior": "pause_immediately", "pause_for_cycles": 2 }' ``` Or resume on a specific date: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/pause \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "pause_behavior": "pause_at_end", "resumption_date": "2026-05-01T00:00:00Z" }' ``` | Parameter | Description | | ------------------ | ------------------------------------------------------------------------------ | | `pause_behavior` | `pause_immediately` or `pause_at_end` | | `pause_for_cycles` | Number of billing cycles to skip before auto-resume | | `resumption_date` | Explicit datetime for auto-resume. Mutually exclusive with `pause_for_cycles`. | See [Pause a subscription](/guides/billing/subscription-pause) for resume behavior and proration details. # Resume a paused subscription Reactivate a paused subscription immediately: 1. Go to **Billing > Subscriptions** 2. Select the paused subscription 3. Click **Resume subscription** ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/resume \ -H "Authorization: Bearer sk_live_..." ``` When resumed: * A prorated invoice is created for the remaining time in the current period * Payment is attempted on the prorated invoice * The billing period advances to the next cycle # Cancel a subscription End a subscription with control over timing and refunds. ## Cancel immediately ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/cancel \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "refund_option": "prorated" }' ``` ## Cancel at period end Let the customer use the service through the paid period: ```bash curl -X PATCH https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id} \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "cancel_at_period_end": true }' ``` ## Cancel on a specific date Schedule cancellation for a future date: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/schedule-cancellation \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "cancel_at": "2026-06-01T00:00:00Z", "refund_option": "none" }' ``` ## Refund options | Option | Behavior | | --------------- | ----------------------------------------------------- | | `none` | Cancel with no refund (default) | | `full` | Refund the full paid amount for the current period | | `prorated` | Refund unused portion calculated by remaining seconds | | `cancel_unpaid` | Void open invoices instead of refunding | ## Undo a scheduled cancellation Remove a pending cancellation before it takes effect: ```bash # Clear cancel_at_period_end curl -X PATCH https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id} \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "cancel_at_period_end": false }' # Clear scheduled cancel_at date curl -X DELETE https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/scheduled-cancellation \ -H "Authorization: Bearer sk_live_..." ``` See [Cancel a subscription](/guides/billing/subscription-cancel) for preview mode and refund calculation details. # Update a subscription ## Change subscription fields Update metadata, payment method, or other settings: ```bash curl -X PATCH https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id} \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "description": "Enterprise plan", "default_payment_method_id": "pm_newcard456" }' ``` | Field | Description | | --------------------------- | ---------------------------------------- | | `description` | Free-text description | | `default_payment_method_id` | Payment method for future collections | | `cancel_at_period_end` | Schedule cancellation at period end | | `trial_end` | Extend or shorten the trial period | | `coupon_id` | Attach a coupon (pass `""` to remove) | | `promotion_code` | Apply a promotion code | | `collection_method` | `charge_automatically` or `send_invoice` | | `net_d` | Payment terms in days | ## Update subscription items Add, remove, or change items with proration control: ```bash curl -X PATCH https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/items \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "items": [ {"id": "si_existing123", "quantity": 10}, {"price_id": "price_addon_storage", "quantity": 1}, {"id": "si_old_addon", "deleted": true} ], "proration_behavior": "always_invoice" }' ``` | Operation | Payload | | --------------- | ------------------------------------------- | | Add item | `{"price_id": "price_xxx", "quantity": 2}` | | Update quantity | `{"id": "si_xxx", "quantity": 10}` | | Swap price | `{"id": "si_xxx", "price_id": "price_yyy"}` | | Remove item | `{"id": "si_xxx", "deleted": true}` | ### Proration behavior | Behavior | Description | | ------------------- | -------------------------------------------------------- | | `always_invoice` | Create invoice immediately and attempt payment | | `create_prorations` | Add prorated items to the next renewal invoice (default) | | `none` | No proration; changes apply at next renewal | See [Update a subscription](/guides/billing/subscription-update) for upgrade/downgrade examples. # Reschedule billing Change when the next invoice is generated: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/reschedule-billing \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "next_billing_date": "2026-03-15T00:00:00Z", "create_proration": true }' ``` Use `is_preview: true` to see the proration amount without applying changes. # Trial periods Offer a free trial before the first charge: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "customer_id": "cus_abc123", "currency": "USD", "billing_interval": "month", "trial_start": "2026-02-01T00:00:00Z", "trial_end": "2026-02-15T00:00:00Z", "items": [{"price_id": "price_monthly_pro", "quantity": 1}] }' ``` During the trial: * Subscription is in **Trialing** state * A \$0 invoice is generated for the trial period * Three days before trial ends, `subscription.trial_will_end` event fires * At trial end, the subscription activates and billing begins # Fixed-term subscriptions Create subscriptions that automatically end after a set number of billing cycles: ```bash curl -X POST https://api.paymentkit.com/api/{account_id}/subscriptions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "customer_id": "cus_abc123", "currency": "USD", "billing_interval": "month", "total_billing_cycles": 12, "items": [{"price_id": "price_monthly_pro", "quantity": 1}] }' ``` The subscription cancels automatically after 12 billing cycles complete. # Payment collection Control how invoices are paid: | Method | Behavior | | ---------------------- | -------------------------------------------------------------------------- | | `charge_automatically` | PaymentKit charges the customer's default payment method at each renewal | | `send_invoice` | PaymentKit generates an invoice and waits for the customer to pay manually | Set `net_d` to control when invoices are due. A value of `0` means due immediately. A value of `30` gives the customer 30 days after invoice finalization. # Failed payments and dunning When a payment fails, PaymentKit automatically: 1. Transitions the subscription to **Past due** 2. Retries payment on a smart schedule 3. Sends dunning emails with a link to update payment method 4. Applies your configured end behavior if all retries fail ## Dunning end behavior Configure what happens when all retry attempts are exhausted: | Behavior | Subscription | Invoice | | ---------------------------- | -------------- | -------------------- | | `cancel_and_uncollectible` | Cancelled | Marked uncollectible | | `cancel_and_open` | Cancelled | Kept open | | `past_due_and_uncollectible` | Stays past due | Marked uncollectible | | `past_due_and_open` | Stays past due | Kept open | See [Automatic retries & emails](/guides/billing/auto-retries-emails) for retry schedules and email configuration. # Preview upcoming invoice See what the next invoice will look like before changes take effect: ```bash curl -X GET https://api.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/preview \ -H "Authorization: Bearer sk_live_..." ``` The response includes line items, totals, and billing dates. # Webhook events PaymentKit emits events at each subscription state change: | Event | Trigger | | ----------------------------- | --------------------------- | | `subscription.created` | Subscription created | | `subscription.updated` | Subscription fields changed | | `subscription.paused` | Subscription paused | | `subscription.resumed` | Paused subscription resumed | | `subscription.cancelled` | Subscription cancelled | | `subscription.trial_will_end` | Trial ends in 3 days | | `invoice.created` | Invoice generated | | `invoice.paid` | Payment succeeded | | `invoice.payment_failed` | Payment failed | See [Webhooks](/guides/integration/webhooks) for setup and event handling. # Invoice states Invoices track payment collection status: | State | Description | | ----------------- | --------------------------------------------- | | **Draft** | Being prepared, not yet finalized | | **Open** | Finalized and awaiting payment | | **Paid** | Payment successfully collected | | **Past due** | Payment overdue, in collection | | **Uncollectible** | Marked as uncollectible after failed recovery | | **Void** | Cancelled, no longer valid | See [Create an invoice](/guides/billing/invoice-create) and [Custom invoices](/guides/billing/invoice-custom) for manual invoice management.