One-time sales
Create payment-mode Checkout Sessions for credits, downloads, upgrades, and other single purchases.
A billing control layer for a product portfolio
Connect multiple products to a shared Stripe billing contract without letting the browser choose prices, users, merchants, or return destinations.
Catalog before checkout
Every billable feature begins as an app and SKU in the Yito Pay catalog. The record identifies an immutable Stripe Price, currency, amount in minor units, payment mode, and entitlement key. Product browsers never send a trusted dollar amount or Stripe Price ID.
When a backend requests checkout, its app API key selects the app. The SKU selects the catalog entry. The authenticated product user becomes the external user ID, and the product’s own order becomes the external order ID. Yito Pay rejects an idempotency key if a retry changes any of those values.
This design gives finance and engineering one answer to a basic question: which approved product and price produced this charge? Stripe metadata aids investigation, while the Yito Pay order remains the application ledger for fulfillment.
Create payment-mode Checkout Sessions for credits, downloads, upgrades, and other single purchases.
Track Stripe subscription status and invoice outcomes without reducing the lifecycle to a fragile paid boolean.
Create short-lived Stripe portal sessions so customers can manage payment methods, invoices, and cancellation safely.
Explicit state
A one-time order can be created, open, processing, paid, fulfilled, failed, expired, partially refunded, refunded, or disputed. A subscription can be trialing, active, past due, paused, canceled, or unpaid. Preserving these states prevents a temporary payment delay from looking like permanent success or failure.
Delayed payment methods may complete Checkout before money is available. Yito Pay keeps the order processing until the asynchronous success event arrives. Subscription access follows paid invoices and current subscription state. Refund and dispute events can revoke or restore an entitlement without editing an append-only payment fact.
| Signal | Order action | Product effect |
|---|---|---|
| checkout.session.completed + paid | Mark paid | Grant mapped entitlement |
| async_payment_succeeded | Mark paid | Grant after delayed settlement |
| invoice.payment_failed | Keep order history | Mark subscription access past due |
| refund succeeds | Partial or full refund | Revoke on full refund |
| dispute created | Mark disputed | Pause access pending outcome |
Product isolation
Each app has its own server key, allowed payment origins, return paths, callback URL, customer namespace, and catalog. A key for one product cannot read another product’s orders or request a refund for them. App authentication happens before order lookup, and public recovery links use a separate short-lived token.
Customers are currently scoped by app, which is the safer default for distinct products. A person who buys from two products can therefore have two Stripe Customer records even if the products share a merchant account. This avoids accidentally exposing one brand’s invoices or subscriptions in another brand’s portal.
Product callbacks use a per-app signing secret derived from a Worker master key. The receiving backend verifies the timestamp, raw body, and event ID, then stores the event ID before granting access. Retries deliver the same semantic event rather than issuing access twice.
Merchant responsibility
Products can share a Stripe account only when the legal seller, statement identity, invoice issuer, refund owner, dispute owner, and tax responsibility are aligned. Separate legal entities require separate accounts. Third-party sellers require a Stripe Connect design.
Yito Pay’s shared API does not hide those responsibilities. It makes the routing change an infrastructure concern instead of a rewrite in every product.
Start with the smallest correct boundary
The first production boundary uses one Stripe account, one Worker, one Neon schema, one webhook path, and multiple approved apps. That is enough to make checkout and fulfillment consistent while keeping operations understandable.
Additional Stripe accounts are introduced only for a verified business reason. Stripe Connect is introduced only when external sellers receive funds. The architecture leaves room for those paths, but the first implementation does not pretend to be a marketplace or payment orchestrator before that need exists.
Questions, answered
No. Products can share an account when the same legal seller, billing identity, support team, refund owner, dispute owner, and tax responsibility apply. Separate business responsibility should use a separate Stripe account or Stripe Connect.
Prices come from the Yito Pay server-side catalog. Each app and SKU maps to an approved Stripe Price ID, amount, currency, mode, and entitlement. The browser cannot override those values.
Yito Pay records Checkout, invoice, and subscription events, synchronizes subscription state, and exposes Stripe Customer Portal sessions for supported customer self-service actions.
Build on a reliable payment boundary
Start with the integration guide, then register the app, domain, and server credentials before enabling checkout.