Expose subscription service period on payments, and payment ID on subscription.renewed
Problem
There is currently no way, via the API, to determine which subscription billing cycle a given payment funded.
This blocks any merchant who wants to gate fulfilment on a paid period rather than on a webhook arriving. It affects credit grants, entitlement provisioning, revenue recognition and reconciliation.
What is missing today
1. No service period on the payment.
PaymentResponse exposes invoice_id, but there is no public endpoint that turns an invoice ID into a period:
/invoices/payments/{payment_id},/invoices/payouts/{payout_id}and/invoices/refunds/{refund_id}return PDFs, not JSON resources- There is no
GET /invoices/{invoice_id} GET /payments/{payment_id}/line-itemsreturnsitems_id,amount,tax,refundable_amount,descriptionandname, with no period start or end
The immutable period does exist internally on the subscription line item as starts_at / ends_at. It is simply not reachable by a merchant.
2. subscription.renewed does not carry the payment ID.
The event provides the subscription and date information but not the payment that funded the renewal. Listing payments by subscription produces candidates but cannot conclusively identify which charge funded which cycle.
3. Billing dates cannot be used as a substitute.
next_billing_date advances before any payment exists, and previous_billing_date advances when the invoice is created with no payment condition. Neither is evidence that a cycle was paid. For on-demand subscriptions next_billing_date is not maintained at all.
So there is no field a merchant can trust to answer "has this period been paid for".
Requested
- Expose
period_startandperiod_endon the payment object, or add a public invoice read endpoint that returns the subscription line item period. - Include the payment ID in the
subscription.renewedpayload. - Ideally expose a price or product version reference alongside the period, so a merchant can tell which plan a cycle was billed at after a plan change.
Why this matters
Without it, merchants fall back to grouping payments by invoice_id and inferring cycles, which is fragile:
- Retries share one invoice, so invoice-to-payment is one-to-many
- The internally recorded period start is stamped at invoice generation rather than at the billing boundary, so a delayed renewal job drifts it
- Any merchant recovering from missed or replayed webhooks has no authoritative record to reconcile against
This comes up repeatedly with merchants building metered or credit-based products on top of subscriptions, where fulfilment must be tied to a paid period rather than to webhook delivery.
0 Comments
Sign in to comment
No comments yet. Be the first to share your thoughts!
