Saved cards
How a customer's card gets on file, how they replace it from the billing portal or the credits page, and how your server lists, chooses and removes cards.
Invoices are collected and auto-recharge buys credits with the customer's default card. Exactly one card is the default.
A card reaches Base316 in one of three ways, and all three store it the same
way (saveDefaultCard):
- Subscription checkout saves the card the subscription was bought with.
- A card update on Stripe's hosted page — a Checkout Session in setup mode, on your connected account. The customer starts it from the billing portal's Payment method section or the credits page's Card on file.
- The pay page, when the payer ticks Save this card for future payments.
Stripe collects the card and runs any verification it needs (3-D Secure, a bank's own app). Base316 never sees the number, and none of its own pages has a card field: there is no card form to build, and no SetupIntent to confirm.
Replacing a card
Send the customer to a hosted page with a single-use link from your server:
// The whole billing portal: plan, invoices, billing details and the card.
const billing = await base316.billingPortal.createSession(customerId, {
returnUrl: "https://app.example.com/billing",
});
// Or only the credits page: balances, packs, auto-recharge — and the card
// those charge. It cannot open the billing portal.
const credits = await base316.creditsPortal.createSession(customerId);Both pages show the card on file and an Update card button. It sends the customer to Stripe; when they finish, Base316 reads the result back from Stripe, checks it belongs to this customer and environment, makes it the default, and returns them to the page they came from. A cancelled update changes nothing.
The billing portal also has a Payment methods section
(billingPortal.createSession(customerId, { page: "payment-methods" }) lands
on it) listing every card on file, where the customer can Make default,
Remove, or Add a card through the same Stripe-hosted update, which
comes back to the section.
The credits page shows the button beside the two auto-recharge warnings that a card fixes — "no card on file" and "turned off after two declines" — so a customer you send there to fix auto-recharge never needs billing access.
In an application of your own, /v1/me/payment-method/update-session starts
the same card update for the signed-in user (see the
billing portal guide).
Cards on file
| SDK | REST |
|---|---|
paymentMethods.list(customerId) | GET /v1/customers/:id/payment-methods |
paymentMethods.setDefault(customerId, id) | POST /v1/customers/:id/payment-methods/:pmId/default |
paymentMethods.remove(customerId, id) | DELETE /v1/customers/:id/payment-methods/:pmId |
Secret key only. Removing a card detaches it at Stripe first; if Stripe refuses, the card stays on file so nothing claims it is gone when it is not. Removing the default promotes the newest remaining card, so a subscription does not fall into dunning because an old card was tidied away.
In the dashboard, each customer's page has a Payment methods section with the cards on file, Make default, Remove, and Copy billing portal link / Open as customer. The auto-recharge panel offers Copy credits page link when it needs a card. Operators never type a card in.
A managed tenant billed to its parent has no cards of its own: its parent's card pays, and neither page offers it a card update.
Saving the card on the pay page
The hosted pay page (/pay/...) has a Save this card for future payments
checkbox, off by default. Ticked, the payment is set up for off-session use on
the invoice's customer, so Stripe saves the card with the payment. Base316
records the card — as the default — when Stripe reports the payment succeeded,
not when the browser says so. It is not offered on an invoice billed to a
parent account.
Migrating from another provider
Bringing customers and subscriptions across without billing anybody twice.
Move subscribers to a new plan version
Publish a better version of a plan and give it to the customers already on it — in place, without restarting their billing period — or keep them where they are.

