Stripe charges your end users; ShipRev keeps a record of each charge and moves the subscription along with it. Both happen when Stripe's events reach the application's webhook endpoint, set up as described in Payments.
Invoice records
ShipRev writes one invoice record for each payment Stripe reports on a buyer organization: the first payment at checkout, each renewal, the difference charged for a plan change, a failed payment, and a wallet top-up paid at checkout.
| Field | Meaning |
|---|---|
invoice_id | ShipRev's ID of the record |
amount | The amount in the currency's major unit, as a decimal string, such as "49.000000" |
currency | The ISO 4217 currency code |
status | PAID or PAYMENT_FAILED |
paid_at | When the payment was made; null for a failed one |
A record is written once and never changed or deleted. There is one record per Stripe invoice or checkout, written from the first event about it, so an event that Stripe delivers twice still leaves one record. The same holds when a renewal fails and Stripe later collects that invoice on a retry: the record stays PAYMENT_FAILED, while the subscription returns to ACTIVE as described below. Stripe's own invoice shows its final status.
End users list their organization's records with GET /public/v1/invoices. Stripe's own invoices, with their documents, are in Stripe's billing portal and your Stripe Dashboard; see Cancel and resume for opening the billing portal.
How the subscription follows the events
| Event | Subscription |
|---|---|
checkout.session.completed | Pending becomes ACTIVE |
invoice.paid | Stays or becomes ACTIVE, and its period moves to the one paid for. A plan change's difference does not move the period |
invoice.payment_failed | Becomes PAST_DUE |
customer.subscription.updated | Follows a plan change, and a cancellation scheduled or undone, as Stripe has them now |
customer.subscription.deleted | Becomes CANCELED |
ShipRev runs no timer of its own on a subscription. It does not mark a subscription unpaid because an expected renewal event has not arrived; until another event arrives, the subscription keeps the state of the last one received. The period end therefore moves only when the renewal's invoice.paid arrives.
Events that arrive late or twice
Stripe does not promise to deliver events in order, and resends an event until it is answered with success. ShipRev handles both:
- An event delivered twice changes nothing the second time.
- A failed payment that happened before the subscription's last successful payment does not make it past due; it is recorded and nothing else changes.
- A payment made before the subscription became past due does not end the past-due state; only a payment made since does.
- A cancelled subscription is never brought back by a later payment event; the payment is still recorded.
- For
customer.subscription.updated, ShipRev reads the subscription from Stripe instead of trusting the event's contents, so an old event cannot undo a newer change.
A payment for a checkout that no longer exists
Rarely, a checkout is paid after ShipRev has stopped waiting for it. When such a payment arrives and does not belong to any subscription in progress, ShipRev records the invoice, cancels the new Stripe subscription so that it does not renew, and keeps the existing subscription as it is. It does not refund the payment; the event is listed under recent webhooks on Payment Gateway as needing review, and you can refund it from your Stripe Dashboard.