***
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.