Agent docs

Stripe commerce has a sandbox checkout path; live billing is not enabled.

Bumpgrade has a Stripe architecture, secret mapping, D1 commerce schema, billing-safe agent contract, self-serve live subscription checkout for Bumpgrade plans, sandbox publisher-offer Checkout Session path, constrained order-bump checkout start, sandbox webhook-backed entitlement grants, optional referral-click attribution evidence, review-only commission ledger evidence, owner review/reversal actions, non-billing post-purchase upsell/downsell decision evidence, owner-confirmed non-destructive product revocation intent records, and protected content readiness. Publisher-offer live billing and payout rollout remain deliberately separated.

Commerce source data

Status

Sandbox path liveIssue #11 defines the contract. Issue #34 owns the first sandbox checkout path.

Expected shape

What this contract enables next

Stripe node 22.1.1 is installed and pinned to API version 2026-04-22.dahlia.

Checkout Sessions are the first payment surface for on-session purchases and subscriptions.

Subscriptions use Stripe Billing patterns; future self-service changes should use Customer Portal before custom billing state.

Future publisher payout work uses Connect Accounts v2, not legacy account-type shortcuts.

Raw Stripe customer, checkout, payment, subscription, connected-account, webhook, and secret values stay server-private.

Decisions

Payment architecture choices

Source data
Acceptedcommerce-decision-checkout-sessions-first

Use Checkout Sessions first

Bumpgrade will create Checkout Sessions server-side for on-session purchases, subscriptions, order bumps, and future upsell paths before considering lower-level PaymentIntent flows.

Acceptedcommerce-decision-billing-for-subscriptions

Use Stripe Billing for recurring plans

Subscriptions, trials, upgrades, downgrades, cancellations, and payment-method updates should use Stripe Billing plus Checkout and Customer Portal patterns rather than hand-rolled renewal loops.

Acceptedcommerce-decision-connect-v2-later

Use Connect Accounts v2 for future publisher payouts

Publisher payout or marketplace flows will use Accounts v2 with explicit configuration, capabilities, dashboard access, and responsibility choices. No connected-account onboarding is live in this slice.

Acceptedcommerce-decision-idempotent-webhooks

Webhook events are idempotent and auditable

Every Stripe event must be keyed by its event id, store a payload hash, record processing status, and write redacted billing audit entries for state changes.

Acceptedcommerce-decision-no-public-provider-ids

Public routes redact provider identifiers

Public and agent-readable commerce routes expose stable Bumpgrade IDs, statuses, and source evidence. Raw Stripe customer, session, payment, subscription, and account IDs stay server-private.

Sandbox checkout

First Checkout Session path is API-first and redacted.

Checkout contract
Sandboxprice-bumpgrade-sandbox-launch-pass-usd

Bumpgrade launch pass

A one-time checkout offer used to prove Checkout Session creation, intent persistence, webhook idempotency, and redacted payment audit trails before live billing is enabled.

Confirmed writeIssue #34

Checkout creation requires exact confirmation

POST /api/commerce/checkout with confirmation text Create checkout for Bumpgrade launch pass at 9.00 USD. Without a valid sandbox secret, the endpoint returns a safe preview instead of calling Stripe.

Webhook/api/stripe/webhook

Webhook events are stored idempotently

The webhook route verifies raw Stripe signatures when configured, stores redacted event evidence, and updates matching checkout intents before fulfillment is trusted.

D1 contract

Commerce tables are ready before checkout code ships.

Schemalive

commerce_products

Canonical Bumpgrade product records for products, memberships, services, downloads, and future offers.

Public-safeid, slug, name, kind, status, description, fulfillment_kind
Server-privateowner_user_id, metadata_json
Schemalive

commerce_prices

Stable price records mapped to Stripe Prices for one-time and subscription checkout.

Public-safeid, product_id, nickname, currency, unit_amount_cents, billing_interval, active
Server-privatestripe_price_id, metadata_json
Schemalive

checkout_intents

Idempotent checkout-start record created before Stripe is called.

Public-safeid, checkout_kind, status, product_id, price_id, amount_cents, currency, stripe_mode
Server-privateidempotency_key, owner_user_id, buyer_user_id, buyer_email, stripe_checkout_session_id, stripe_payment_intent_id, stripe_subscription_id, success_url, cancel_url, audit_correlation_id, agent_client_id, metadata_json
Schemalive

checkout_referral_attributions

Public-safe evidence that a validated seeded referral click was attached to a sandbox checkout intent.

Public-safeid, checkout_intent_id, referral_click_id, referral_link_id, referral_code, partner_id, destination_route, attribution_status
Server-privatecheckout_product_id, checkout_price_id, audit_correlation_id, metadata_json, raw click rows, buyer identifiers, raw Stripe identifiers, payout or tax data
Schemalive

checkout_post_purchase_decisions

Non-billing post-purchase upsell/downsell decision evidence for trusted sandbox checkout intents before one-click charging exists.

Public-safeid, checkout_intent_id, offer_stack_id, presented_offer_id, decision_kind, checkout_status, checkout_updated_at, actor_kind, created_at
Server-privateidempotency_key, audit_correlation_id, metadata_json, buyer identifiers, raw Stripe identifiers, payment method data, private checkout metadata
Schemalive

affiliate_commission_ledger_entries

Review-only, non-payable commission ledger evidence created from trusted checkout referral attribution before payout workflows exist.

Public-safeid, checkout_intent_id, referral_attribution_id, referral_click_id, referral_link_id, partner_id, source_checkout_amount_cents, commission_cents, ledger_status, review_status, payout_status
Server-privateidempotency_key, audit_correlation_id, metadata_json, buyer identifiers, raw Stripe identifiers, partner payout accounts, tax forms, private review notes
Schemalive

affiliate_commission_ledger_actions

Owner-gated review, hold, and reversal actions for review-only commission ledger evidence before payout mutation exists.

Public-safeid, commission_ledger_id, checkout_intent_id, action_kind, previous_ledger_status, next_ledger_status, previous_review_status, next_review_status, next_payout_status, created_at
Server-privateidempotency_key, actor_user_id, actor_email, private reason, metadata_json, buyer identifiers, raw Stripe identifiers, partner payout accounts, tax forms
Schemalive

stripe_webhook_events

Webhook idempotency and redacted event evidence keyed by Stripe event id.

Public-safeevent_type, api_version, livemode, status, processed_at
Server-privateid, payload_redacted_json, error
Schemalive

billing_subscriptions

Subscription access state derived from Stripe Billing events.

Public-safeid, product_id, price_id, status, current_period_start, current_period_end, cancel_at_period_end
Server-privateowner_user_id, buyer_user_id, buyer_email, stripe_customer_id, stripe_subscription_id, stripe_price_id, metadata_json
Schemalive

payment_audit_events

Redacted audit trail for billing-impacting checkout, webhook, and agent actions.

Public-safeid, checkout_intent_id, event_kind, actor_kind, summary, created_at
Server-privatestripe_event_id, actor_id, metadata_json
Schemalive

product_entitlements

Idempotent product access grants derived from trusted paid checkout webhook evidence.

Public-safeid, checkout_intent_id, product_id, entitlement_template_id, access_rule_id, status, grant_kind, source_price_id, granted_at
Server-privatesource_stripe_event_id, source_commerce_product_id, buyer_user_id, buyer_email_hash, metadata_json
Schemalive

product_fulfillment_tasks

Public-safe fulfillment queue evidence created with entitlement rows before private delivery exists.

Public-safeid, entitlement_id, checkout_intent_id, product_id, status, fulfillment_kind, summary
Server-privatemetadata_json
Schemalive

product_asset_uploads

Owner-confirmed private product asset upload records backed by PRODUCT_ASSETS without exposing object keys, signed URLs, upload bodies, or private metadata.

Public-safeid, product_id, asset_id, file_name, content_type, byte_count, body_sha256, status
Server-privateidempotency_key, actor_user_id, actor_email_hash, r2_object_key, confirmation_text_sha256, metadata_json
Schemalive

product_entitlement_revocation_intents

Owner-visible revocation intent records that document confirmation, stale-state, audit, and non-destructive boundaries before live entitlement removal exists.

Public-safeid, product_id, entitlement_template_id, access_rule_id, status, intent_kind, reason_code, destructive_action_enabled, entitlement_mutation_enabled
Server-privatetarget_entitlement_id, idempotency_key, actor_user_id, actor_email_hash, confirmation_text_sha256, private_reason_sha256, metadata_json, future buyer identifiers, future private reason notes
Schemalive

product_protected_content_sections

Protected content readiness metadata for future course and member-area delivery without exposing protected bodies or enabling customer delivery.

Public-safeid, product_id, asset_id, entitlement_template_id, status, content_kind, title, public_summary, delivery_enabled, protected_body_included
Server-privatemetadata_json, lesson bodies, member post bodies, progress rows, private R2 object keys, signed URLs

Billing safety

Agents can read contracts; writes need confirmation.

Confirmed writes

Agents must not create, expire, refund, cancel, upgrade, downgrade, or publish a billing object without explicit confirmation text.

Redacted output

Model-visible output must not include raw Stripe secret keys, webhook secrets, customer IDs, Checkout Session IDs, PaymentIntent IDs, Subscription IDs, connected-account IDs, or private customer data.

Auditable events

Billing-impacting writes require actor identity, client attribution, idempotency key, audit correlation id, stale-state check, and redacted output.