Table of contents
- Products and plans
- Plan labels
- Meters
- Customer references
- Paywall protection flow
- Purchase lifecycle
- Authentication flow
- Usage tracking
- Next steps
Products and plans
Products
A product represents the API, app, or MCP server you monetize.- Product reference (
prd_...) - Name and description
Plans
A plan defines pricing and access for a product.- Plan reference (
pln_...) - Type:
recurring,usage-based,one-time, orhybrid - Price and currency
- Features
- Status:
active,inactive, orarchived
Product-plan relationship
- One product can have multiple plans
- Plans are embedded in products
- One default plan per product
- Paywall checks verify plan access for a product
Plan labels
A plan is anoptions[] list. These names are derived labels, not a type you send:
See Plans to compose those options.
Meters
Meters define what usage to measure.- Seeded default:
requests(name/displayName/unit) - MCP tool meters:
tool:{toolName} - Custom meters for business-specific usage
unit noun — see Plans and billing glossary.
Customer references
A customer reference (customerRef) maps your user identity to SolvaPay.
Create-or-link semantics
When you callPOST /v1/sdk/customers (or ensureCustomer / syncCustomer) with an email that already exists under this provider and the caller supplies an externalRef, the API links the externalRef onto the existing customer instead of returning 409 Conflict. This lets you idempotently adopt pre-existing SolvaPay customers when wiring up your own auth layer for the first time. Callers without externalRef still get 409 on duplicate email so the behavior is explicit.
Update a customer
UsePATCH /v1/sdk/customers/:reference to backfill or change externalRef, name, or email. Only the fields you supply are modified.
Data helpers
Three read-only endpoints power customer-facing UI without bloatingcheckPurchase:
GET /v1/sdk/platform-config— browser-safe platform values (today: the SolvaPay Stripe publishable key used to initialize the Stripe.js client). Resolves against the sandbox or live environment matching your secret key. Call it once on page load before mounting<PaymentForm>; additions will land here rather than in/sdk/merchant.GET /v1/sdk/merchant— provider identity safe to render in checkout and mandate copy:name,legalName,supportContact,termsUrl,privacyUrl,iconUrl(square app icon), andlogoUrl(absolute URL resolved againstASSETS_BASE_URL). Used by SDK components likeMandateTextandCheckoutSummary.GET /v1/sdk/payment-method?customerRef=…— returns{ kind: 'card', brand, last4, expMonth, expYear, reusable }or{ kind: 'none' }. The card brand and last4 are mirrored onto the Customer by thepayment_intent.succeededwebhook, so this endpoint reads from SolvaPay’s database with no Stripe round-trip.reusabledistinguishes a chargeable saved card from a card that is only on file. Safe to poll alongsidecheckPurchase.
@solvapay/next (getMerchant, getProduct, getPaymentMethod) and as fetch handlers in @solvapay/server/fetch. In an MCP server they are not separate tools — createSolvaPayMcpServer delivers the same data on the account viewer’s bootstrap payload, which seeds the client caches at mount.
Paywall protection flow
When your handler is wrapped withpayable(), the SDK:
- Resolves customer reference
- Checks purchase status
- Checks usage limits
- Executes business logic when allowed
- Tracks usage
- Returns a paywall response when blocked
Example blocked response
Purchase lifecycle
Purchase states:- Active — customer has access
- Pending cancellation — active with
cancelledAtset; access continues until period end, can be reactivated - Cancelled — cancel confirmed at period end
- Expired — purchase ended (period elapsed or plan switch)
- Past due — payment failed; may be suspended
Cancel and reactivate renewal
Activate a plan directly
Activate a product for a customer on a specific plan without checkout. Handles free plans, credit-based activation, usage-based (PAYG) plans, and plan switching.- Free — always
activated. - Usage-based (metered, no billing cycle) —
activatedimmediately. A zero balance is not an activation gate. Empty-wallet access is enforced later astopup_requiredat usage time. - Paid recurring, hybrid, or one-time —
payment_required. Complete checkout before the plan activates.
activatePlan automatically expires the old purchase and creates a new one.
See Purchase lifecycle management for the full guide.
Authentication flow
You keep your existing auth and map identities to SolvaPay customers. Common pattern:- Extract user ID from your auth layer
- Use ID as
customerRef - Sync email/name as needed
- Run purchase checks
Usage tracking
Usepayable() for automatic usage tracking, or record usage directly.
Next steps
-
Customer linkage (bring your own client and IdP) —
ensureCustomer(externalRef)from any backend - Quick start
- CLI setup
- Installation
- Plans overview
- Plans and billing glossary