zudo-text

検索したい単語を入力

いつでも検索バーを開ける

Stripe billing catalog

This runbook defines the server-owned Stripe catalog used by POST /api/v1/subscription/checkout-session. The client sends only the lookup keys below; it never sends a Stripe Product or Price id.

Catalog to create

Create both entries in the same Stripe account and deploy their Price ids to every sync-server environment.

Lookup keyProductPrice shapeWorker bindingQuantity
prozudo-text ProRecurring subscription Price, one unit per subscriptionSTRIPE_PRICE_PROExactly 1
storage-10gbzudo-text storageRecurring subscription Price, per-unit billingSTRIPE_PRICE_STORAGE_10GB1100 at Checkout; desired total 0100 afterward

One storage-10gb unit grants exactly 10,737,418,240 bytes (10 GiB). Configure the two Prices with the same currency and recurring interval. The storage Price must use standard per-unit pricing so Stripe multiplies its unit amount by the subscription-item quantity.

Set each Price's Stripe lookup_key to the exact key in the table. The Worker also keeps the corresponding Price id in its bindings, so a caller cannot swap in another Price id. Before an existing subscription is mutated, its Customer must match the persisted Customer and it must contain exactly one configured Pro Price. The storage item remains identifiable by either its configured id or its locked lookup key.

Worker configuration

The Price ids and fallback scheme are non-secret Worker variables. Keep the Stripe API key secret.

[vars]
STRIPE_PRICE_PRO = "price_..."
STRIPE_PRICE_STORAGE_10GB = "price_..."
APP_DEEP_LINK_SCHEME = "zudotext"
pnpm --filter @takazudo/sync-server exec wrangler secret put STRIPE_SECRET_KEY

Repeat configuration for each named Wrangler environment. A deployed Worker without the API key or either Price id returns 503 from Checkout instead of falling back to a client-supplied value.

APP_DEEP_LINK_SCHEME is only a defensive fallback for an older or non-Tauri caller that omits scheme. Current ROOT and LEAF clients send their own runtime scheme on every attempt. Never configure the fallback as a way to force all LEAF callbacks to ROOT.

Checkout and quantity operations

  • A first Checkout creates one subscription-mode hosted Checkout Session with exactly one pro item and one storage-10gb item.

  • If users.stripe_subscription_id is already present, the Worker retrieves that subscription and updates its sole storage item. It does not create a second subscription.

  • A positive desired quantity updates the item or adds it when absent. The Worker leaves Stripe's normal proration behavior unchanged.

  • Desired quantity zero deletes the storage subscription item; Stripe does not accept zero as a subscription-item quantity.

  • Every caller supplies one Idempotency-Key for a logical attempt. The Worker derives separate deterministic Stripe keys for Customer creation, Checkout, and each storage mutation, and never logs the Stripe secret.

Entitlement projection from signed Stripe webhooks is a separate deployment step. Do not treat a successful Checkout/update response as the source of truth for subscription_plan or storage bytes.