Saved Cards & Auto Top-Up - cred.diy API documentation
Saved Cards & Auto Top-Up
Keep a buyer's card from a one-time checkout, then buy packs on it later without the buyer present — for example when their balance runs low. A card is saved only when the checkout request sends save_payment_method: true. One card per user; saving again replaces it.
https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/hosted-checkoutOne-time checkout that also saves the card for off-session charges. Not allowed with billing: recurring.
Body parameters
user_idstringrequiredYour unique identifier for the customerpricing_tier_idstringrequiredThe pack to buy nowsave_payment_methodbooleanrequiredSet to true to keep the carduser_emailstringCustomer email
Example request
curl -X POST "https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/hosted-checkout" \
-H "x-api-key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "user_id": "user_123", "pricing_tier_id": "tier_10k", "save_payment_method": true }'Response
{ "url": "https://checkout.stripe.com/...", "session_id": "cs_...", "purchase_id": "..." }/payment-methodThe user's saved card, or null. Stripe ids are never returned.
Query parameters
user_idstringrequiredExternal user ID
Example request
curl "https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/credits-api/payment-method?user_id=user_123" \
-H "x-api-key: sk_live_your_api_key"Response
{ "payment_method": { "brand": "visa", "last4": "4242", "exp_month": 12, "exp_year": 2030, "created_at": "...", "updated_at": "..." } }/payment-methodDetach the saved card in Stripe and forget it. Send user_id in the JSON body.
Body parameters
user_idstringrequiredExternal user ID
Example request
curl -X DELETE "https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/credits-api/payment-method" \
-H "x-api-key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "user_id": "user_123" }'Response
{ "deleted": true }
// no card saved:
{ "deleted": false, "code": "no_saved_payment_method" }/charge-savedBuy a one-time pack on the saved card, off-session. Requires an idempotency key: a retry with the same key returns the first attempt's outcome and never charges twice. Credits are issued before a 200 returns (a credits.issued webhook with billing: auto_topup also fires). requires_action (3-D Secure) cannot be completed without the buyer, so it is a 402 — send them through checkout instead.
Body parameters
user_idstringrequiredExternal user ID with a saved cardpricing_tier_idstringrequiredA one_time or both pricing tieridempotency_keystringrequiredOr the Idempotency-Key header; max 255 charscredit_type_idstringWhen the tier applies to several credit types
Example request
curl -X POST "https://eutdgemlrpvnxfkkpvlu.supabase.co/functions/v1/credits-api/charge-saved" \
-H "x-api-key: sk_live_your_api_key" \
-H "Idempotency-Key: autotopup-user_123-0001" \
-H "Content-Type: application/json" \
-d '{ "user_id": "user_123", "pricing_tier_id": "tier_10k" }'Response
// 200 — charged and credited
{ "status": "succeeded", "purchase_id": "...", "payment_intent_id": "pi_...", "credits": 10000, "new_balance": 12500 }
// 202 — settling; credits arrive by webhook
{ "status": "processing", "purchase_id": "...", "payment_intent_id": "pi_..." }
// 402 — declined or needs the buyer
{ "status": "failed", "purchase_id": "...", "code": "card_declined", "decline_code": "insufficient_funds", "message": "...", "requires_action": false }
// 404 — { "error": "...", "code": "no_saved_payment_method" }
// 409 — "IDEMPOTENCY_KEY_REUSED" (other user) or "saved_payment_method_unusable" (card on a Stripe account the project no longer uses)
// 502 — "charge_not_started": retry with the SAME keyYour first credit is one request away.
Create a project, copy an API key, and issue a credit from your server.
