reconcileCheckoutSession
Settle a completed Stripe Checkout Session immediately, instead of waiting for the webhook.
Between checkout completing and customer.subscription.* landing — measured at
5-30 seconds — the organization still resolves to the Free entitlement, so a
customer who has just paid is told to upgrade. Refreshing does not help, and a
reasonable person concludes the payment failed.
The console calls this on the Stripe return, with the session_id Stripe
substitutes into the success URL. The webhook remains authoritative for anyone
who closed the tab, and the two converge: settling the same session through
both paths, in either order, leaves exactly one subscription.
sessionID is CLIENT-SUPPLIED and Stripe session ids are not secrets — they
appear in URLs, browser history, referrer headers and support tickets. Ownership
is therefore proved from the session's own Stripe-side metadata, which the
server stamped at creation, never from the caller's word. Every refusal returns
one indistinguishable CHECKOUT_SESSION_NOT_FOUND so the mutation cannot become
an oracle over session ids.
Deliberately NOT @requiresStepUp. The manage-billing grant is
consumeOnFirstUse and was spent creating the session, and bouncing the
customer to re-authenticate on the Stripe return is precisely the friction this
mutation exists to remove — roughly half of production users cannot answer a
password challenge.
Returns the organization's subscription posture after settling, so the caller refreshes from the same response rather than racing a refetch.
reconcileCheckoutSession(
ownerID: String!
sessionID: String!
): SubscriptionInfo!
Arguments
reconcileCheckoutSession.ownerID ● String! non-null scalar
reconcileCheckoutSession.sessionID ● String! non-null scalar
Type
SubscriptionInfo object
Current subscription information for an organization, including plan details and feature access