Menu

Payment System Documentation Index

The NEXTY.DEV payment system supports Stripe, Creem and PayPal at the same time, covering subscriptions, one-time purchases, the credit ledger, team shared pools, refunds and reconciliation.

This chapter goes from the whole to the parts: understand the shape first, then dive into each module.

Chapter structure

  1. Payment System Overview

    • The whole path in one picture
    • Five design rules
    • Database tables and the code map
    • Personal and team billing subjects
    • What each provider can do
  2. Pricing Configuration

    • Why pricing lives in code
    • Writing subscription / credit pack / team plans
    • Field reference and provider-side references
    • Localized copy, promotion codes, the iron rule about retiring a plan
  3. Payment Flow

    • The complete path from click to credits
    • The order of the checkout guards, and why
    • The success page and the webhook as belt and braces
    • Guard code reference
  4. Webhook Handling

    • Three layers and signature verification
    • The event map of all three providers
    • Idempotency, status normalization, error handling
    • Duplicate subscription settlement and lost-webhook recovery
  5. Credit System

    • The two-bucket model and the append-only ledger
    • The monthly drip for annual subscriptions
    • Wiring a feature into credits
    • Team shared pools, the signup bonus, admin operations
  6. Orders and Subscriptions

    • Order data and queries
    • Refunds: why only the API is called and local state is left to the webhook
    • The self-service portal and the coupon console
    • Every user-side and admin page
  7. Coupon Console

    • The Stripe Coupon + Promotion Code data model
    • Codes are immutable, and the UI that follows from it
    • The create form and how scope is translated
    • Auto-apply and the listing scan cap
  8. Subscription Changes

    • Configuring the Stripe plan-change entry point
    • The credit difference algorithm for a mid-cycle change
    • Anti-farming design and cross-interval re-anchoring

Getting started

First integration

  1. Read the Payment System Overview to build a mental model
  2. Create the products on the provider side per Stripe Integration (or PayPal Integration)
  3. Edit config/pricing.ts per Pricing Configuration, or just run pnpm stripe:bootstrap --write
  4. Configure the webhook endpoints and CRON_SECRET (see Scheduled Tasks)
  5. Run one payment with a test card and verify it against the checklist at the end of Payment Flow

Find by need

I want to…Read this
Change prices, add a plan, run a promotionPricing Configuration
Make a feature spend creditsCredit System
Debug a payment that never landedWebhook Handling
Refund a customerOrders and Subscriptions
Run coupons and promotion codesCoupon Console
Let customers upgrade or downgradeSubscription Changes
Understand the architecturePayment System Overview

Environment variables

The full list lives in Environment Variables. The payment-related ones:

Stripe

STRIPE_SECRET_KEY=sk_...
STRIPE_PUBLISHABLE_KEY=pk_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Optional: refund,email | refund | email | empty
STRIPE_RADAR_EARLY_FRAUD_WARNING_TYPE=refund,email

Creem

CREEM_API_KEY=your_api_key
CREEM_WEBHOOK_SECRET=your_webhook_secret
CREEM_API_BASE_URL=https://api.creem.io/v1  # Optional

PayPal

NEXT_PUBLIC_ENABLE_PAYPAL=true
NEXT_PUBLIC_PAYPAL_CLIENT_ID=your_client_id
NEXT_PUBLIC_PAYPAL_ENVIRONMENT=sandbox  # sandbox | live
PAYPAL_CLIENT_SECRET=your_client_secret
PAYPAL_WEBHOOK_ID=your_webhook_id

Scheduled tasks

# Auth secret for /api/cron/credits. Required once subscriptions or credits are enabled
CRON_SECRET=your_cron_secret

Other

NEXT_PUBLIC_DEFAULT_CURRENCY=USD
NEXT_PUBLIC_SITE_URL=https://yourdomain.com
[email protected]

FAQ

Q: Which payment providers are supported?

Stripe, Creem and PayPal. The provider field of each plan in config/pricing.ts decides which one handles it, and all three can be enabled at once.

Q: How do I change prices? Where is the admin page?

Since v4.0.0 there is no admin pricing page. Pricing lives in config/pricing.ts — edit and deploy. See Pricing Configuration.

Q: Is the cron job mandatory?

Yes, as soon as you sell subscriptions or use credits. The monthly drip for annual plans, lost-webhook reconciliation and advancing PayPal pending captures all depend on it. See Scheduled Tasks.

Q: How does the credit system work?

Two buckets: subscription credits (reset on every grant, cleared when the subscription ends) and purchased credits (never expire); spending drains the subscription bucket first. Every change goes through the ledger, append-only. See Credit System.

Q: Can customers manage their own subscription?

Yes. The "manage subscription" button on /dashboard/billing redirects to the matching self-service portal for the subscription's provider. PayPal has no hosted portal, so it redirects to the PayPal autopay page.

Q: How do I test?

Use test/sandbox mode for all three and forward webhooks locally. See the testing section of Payment Flow.