app/services/payment.ts) provides three server-side functions that cover the entire subscription flow: loading available plans, initiating a subscription, and querying a customer’s existing subscriptions. All functions use the Stripe Node SDK and must run server-side inside React Router loaders or actions.
The Stripe client is initialized with a hardcoded test key. Replace
sk_test_... with your actual secret key via an environment variable before deploying. See Environment configuration.Functions
getConfig
Fetches all active prices from Stripe with their associated product data expanded inline.
stripe.prices.list() with expand: ["data.product"]. The expand option tells Stripe to inline the full Stripe.Product object on each price instead of returning a bare product ID, so you can display the plan name and metadata without a second API call.
Parameters
This function takes no parameters.
Return value
A paginated Stripe list object containing all prices.
prices loader
subscribe
Creates a new Stripe subscription in an incomplete state and returns the client secret needed to confirm payment on the client side.
stripe.subscriptions.create() with payment_behavior: "default_incomplete". This means Stripe creates the subscription and generates a PaymentIntent, but does not charge the customer immediately. Your frontend must call stripe.confirmCardPayment(clientSecret) to complete the payment and activate the subscription.
The expand: ["latest_invoice.payment_intent"] option tells Stripe to inline the PaymentIntent on the response so the client secret is available without a second API call.
Parameters
The Stripe customer ID (e.g.
cus_Abc123). Read this from the session cookie — it is stored there by the registration action after calling createCustomer.The Stripe price ID to subscribe the customer to (e.g.
price_1Abc123). Obtained from the getConfig response or from the submitted form.The newly created subscription object. Its
status will be incomplete until payment is confirmed.The
client_secret from the subscription’s latest invoice’s PaymentIntent. Pass this to stripe.confirmCardPayment() in your React component to collect and confirm the card payment.customerId from the session and priceId from the submitted form:
subscribe action
payment confirmation
listSubscriptions
Returns all Stripe subscriptions for a given customer.
stripe.subscriptions.list({ customer: customerId }). Returns subscriptions in all statuses (active, incomplete, canceled, etc.) unless you add a status filter.
Parameters
The Stripe customer ID whose subscriptions you want to retrieve. Read from the session cookie.
Promise<Stripe.ApiList<Stripe.Subscription>>.
Array of subscription objects for the customer.
account loader