Billing Cycles
Billing cycles represent individual billing periods within a subscription contract. Each cycle tracks when a billing attempt should occur, whether it was successful, and the resulting order. Understanding billing cycles is essential for managing subscription payments and deliveries.What is a Billing Cycle?
A billing cycle is a specific occurrence of a scheduled billing attempt for a subscription contract. Each cycle contains:- A cycle index (starting at 0 for the first cycle)
- The expected billing attempt date
- Billing attempt results and any associated orders
- Skip status (if the customer skipped this cycle)
- Current billing cycle status
Billing cycles are automatically created by Shopify based on the subscription contract’s billing policy.
Querying Billing Cycles
The app uses GraphQL to fetch billing cycle information:Billing Schedules
The reference app uses aBillingSchedule model to control when billing cycles are processed for each shop:
Schedule Configuration
BillingSchedule Fields
BillingSchedule Fields
- shop: The Shopify shop domain
- hour: The hour of day (0-23) when billing should occur
- timezone: The timezone for the scheduled hour
- active: Whether billing is enabled for this shop
- createdAt/updatedAt: Timestamps for tracking changes
Billing Attempt Process
The app processes billing cycles through a series of background jobs:1. Recurring Billing Job
The main job that kicks off the billing process:Billing jobs run at the start of each hour and process all shops scheduled for that time.
2. Job Execution Flow
- Step 1: Schedule
- Step 2: Query Cycles
- Step 3: Charge
- Step 4: Handle Results
RecurringBillingChargeJob identifies the current hour and queues shop-specific billing jobs.Billing Cycle Status
Billing cycles can be in different states:- UNBILLED: Cycle is scheduled but hasn’t been processed yet
- BILLED: Billing attempt was successful and an order was created
- SKIPPED: Customer or merchant skipped this billing cycle
Skipping Billing Cycles
Customers can skip upcoming billing cycles:Querying Subscription with Billing Cycle
The app provides a helper to find contracts with specific billing cycle data:Billing Attempts
Each billing cycle can have multiple billing attempts if payments fail:Attempt Tracking
The billing cycle tracks all attempts:The
ready field indicates whether Shopify has finished processing the billing attempt. Always check this before taking action on attempt results.Past Billing Cycles
The app provides queries to fetch historical billing cycles:Upcoming Billing Cycles
The app calculates upcoming billing cycles to show customers when their next charges will occur:Billing Cycle Index
The cycle index is a zero-based counter that increments with each billing cycle:- First billing cycle:
cycleIndex = 0 - Second billing cycle:
cycleIndex = 1 - Third billing cycle:
cycleIndex = 2
- Tracking dunning attempts per cycle
- Applying cycle-based discounts
- Displaying order history to customers
Example: Cycle-based Pricing
Example: Cycle-based Pricing
Best Practices
- Set appropriate billing hours: Schedule billing during times when your support team is available to handle issues
- Monitor timezone settings: Ensure billing schedules respect customer timezones for better experience
- Track cycle indices: Use cycle index for analytics and understanding subscription lifecycle patterns
- Handle skipped cycles: Display skipped cycles clearly to customers to avoid confusion
- Check ready status: Always verify billing attempts are ready before processing results
Error Handling
Billing attempts can fail for various reasons:- Payment method expired or declined
- Insufficient inventory
- Invalid shipping address
- Network issues
Related Resources
- Subscription Contracts - Learn about the contracts that generate billing cycles
- Dunning Management - Understand how failed billing attempts are retried
- Selling Plans - Learn about billing policies in selling plans