Expiration and auto-renewal
All orders require an explicit expiration window. Expiration defines how long a customer has to complete payment and prevents orders from remaining open indefinitely.
Expiration behavior is controlled by the required expiration_minutes parameter and the expiration_auto_renewal capability.
Expiration window (required)
When creating an order, merchants must specify the expiration window using expiration_minutes.
{
"expiration_minutes": 30
}Validation rules
expiration_minutesis required- Minimum value: 1 minute
- Maximum value: 3 days (4,320 minutes)
Requests that omit expiration_minutes or provide an invalid value will be rejected.
Expiration date calculation
The expiration date of an order is calculated as:
expiration_date = created_at + expiration_minutes
Each time an order is renewed, a new expiration_date is calculated using the same rule.
Expiration behavior
If an order reaches its expiration_date and auto-renewal is disabled:
- Orders with no payments transition to
expired - Orders with partial payments transition to
partially_paid_expired
Automatic renewal
If capabilities.expiration_auto_renewal is set to true, the order expiration is automatically extended instead of transitioning to an expired state.
Auto-renewal behavior
-
The expiration window is extended by the same
expiration_minutesvalue -
The order remains in its current state:
awaiting_paymentpartially_paid
-
The order does not enter
expiredorpartially_paid_expiredwhile renewal limits allow
Amount and rate recalculation on renewal
Each time an order is automatically renewed, amounts and exchange rates are recalculated.
This means that on every renewal cycle:
- Item amounts are recalculated
- Currency conversions are re-evaluated
- New exchange rates are applied
total_amountandremaining_amountare updated accordingly- The
ratesobject is replaced with the newly applied conversion rates
This behavior ensures that long-lived orders remain aligned with current market prices and FX conditions.
What changes on renewal
| Field | Behavior |
|---|---|
rates | Recomputed using the latest available exchange rates |
total_amount | Recalculated based on updated rates |
remaining_amount | Recalculated after applying any existing payments |
expiration_date | Extended by expiration_minutes |
What does NOT change
- Items and modifiers
- Quantities
- Payment currency
- Order capabilities
- Already applied payments
Previously applied payments continue to reduce the recalculated total when computing remaining_amount.
Practical implications
- A customer may see a different amount due after a renewal if exchange rates have changed.
- Merchants should always rely on the latest Order object when displaying payment instructions.
- Webhook consumers should treat renewed orders as updated orders and re-read totals and rates.
Note
Recalculation occurs only on auto-renewal. Orders that expire without renewal retain their last calculated values.
Auto-renewal limits
Auto-renewal is capped to protect system stability and ensure that orders do not remain active indefinitely.
Two limits are enforced:
-
Maximum total lifetime
An order cannot remain active for more than 15 days (21,600 minutes), regardless of configuration. -
Operational renewal caps
Short expiration windows are capped to avoid excessive renewal cycles.
The effective number of renewal cycles is calculated as:
maxRenewalsByLifetime = floor(21600 / expiration_minutes) - 1
maxRenewals = min(maxRenewalsByLifetime, maxRenewalsByTier)
Renewal tier caps
| expiration_minutes | maxRenewalsByTier | Typical max lifetime |
|---|---|---|
| 1–5 | 60 | up to ~5 hours |
| 6–15 | 96 | up to ~1 day |
| 16–60 | 72 | up to ~3 days |
| 61–180 | 80 | up to ~10 days |
| 181–720 | 40 | up to ~15 days (lifetime limit applies) |
| 721–1440 | 20 | up to ~15 days (lifetime limit applies) |
| > 1440 | 14 | up to ~15 days (lifetime limit applies) |
Once the renewal limit is reached:
-
Auto-renewal stops
-
The order transitions to:
expiredif no payments were receivedpartially_paid_expiredif partially paid
Practical examples
Short-lived checkout
expiration_minutes = 5expiration_auto_renewal = true
The order can renew up to 60 times, resulting in a maximum lifetime of approximately 5 hours.
Standard checkout
expiration_minutes = 30expiration_auto_renewal = true
The order can renew up to 72 times, for a maximum lifetime of approximately 36 hours.
Long-lived invoice
expiration_minutes = 1,440(1 day)expiration_auto_renewal = true
The order can renew up to 14 times, for a maximum lifetime of 15 days.
Important notes
- Orders cannot exist without an expiration window.
- Auto-renewal extends the order lifetime but never indefinitely.
- Renewal limits are enforced automatically and cannot be overridden.
- Expiration and renewal behavior is deterministic and consistent across environments.
Updated 7 months ago