Skip to content

Stripe Integration

Aerostack uses Stripe for all payment processing: platform plan subscriptions, wallet deposits, and marketplace creator payouts. This page explains how Stripe integrates with your Aerostack account and how to configure webhooks for self-hosted or custom setups.


FeatureStripe ProductDescription
Platform plansSubscriptionsMonthly/yearly recurring billing for plan tiers
Wallet depositsCheckout SessionsOne-time payments to fund the prepaid wallet
Creator payoutsConnectTransfer marketplace earnings to creator bank accounts
Customer portalCustomer PortalSelf-service billing management (invoices, payment methods)

When a user upgrades their plan, Aerostack creates a Stripe Checkout Session and redirects them to complete payment.

1. User clicks "Upgrade to Pro" in dashboard
2. Frontend calls POST /api/billing/checkout
Body: { tier: "pro", billing_interval: "yearly", success_url, cancel_url }
3. API creates Stripe Checkout Session with the correct Price ID
4. API returns { url: "https://checkout.stripe.com/..." }
5. Frontend redirects user to Stripe Checkout
6. User completes payment on Stripe
7. Stripe redirects to success_url with session_id
8. Frontend calls GET /api/billing/verify-session?session_id=...
9. API verifies payment and upgrades the plan immediately
10. Stripe also sends webhook for redundancy

Each paid plan has two Price IDs in Stripe — one for monthly and one for yearly:

Terminal window
# Monthly checkout
curl -X POST https://api.aerostack.dev/api/billing/checkout \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"tier": "pro",
"billing_interval": "monthly",
"success_url": "https://app.aerostack.dev/settings/billing?success=true",
"cancel_url": "https://app.aerostack.dev/settings/billing"
}'
# Yearly checkout (25% discount)
curl -X POST https://api.aerostack.dev/api/billing/checkout \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"tier": "pro",
"billing_interval": "yearly",
"success_url": "https://app.aerostack.dev/settings/billing?success=true",
"cancel_url": "https://app.aerostack.dev/settings/billing"
}'

Valid tiers: starter, pro, business. The free tier does not require Stripe checkout.


Stripe webhooks keep Aerostack in sync with subscription changes that happen outside the API (e.g. failed payments, subscription renewals, cancellations from the Stripe dashboard).

POST https://api.aerostack.dev/api/billing/webhook

This endpoint:

  • Requires no authentication (it is public)
  • Validates the stripe-signature header against your webhook signing secret
  • Processes the event and updates the account plan accordingly
  1. Go to Stripe Dashboard > Developers > Webhooks
  2. Click Add endpoint
  3. Enter the URL: https://api.aerostack.dev/api/billing/webhook
  4. Select these events:
    • checkout.session.completed
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_succeeded
    • invoice.payment_failed
  5. Click Add endpoint
  6. Copy the Signing secret (whsec_...) and configure it in your Aerostack deployment

The Stripe Customer Portal lets users manage their subscription without leaving the Aerostack app:

  • View and download invoices
  • Update payment methods
  • Switch billing intervals (monthly/yearly)
  • Cancel subscription
Terminal window
curl "https://api.aerostack.dev/api/billing/portal?return_url=https://app.aerostack.dev/settings/billing" \
-H "Authorization: Bearer YOUR_JWT"

Response:

{
"url": "https://billing.stripe.com/p/session/..."
}

Redirect the user to this URL. After they finish managing their billing, Stripe redirects them back to the return_url.


Wallet deposits use Stripe Checkout Sessions in “payment” mode (one-time payment, not subscription).

1. User clicks "Add Funds" in dashboard
2. Frontend calls POST /api/balance/deposit
Body: { amount_cents: 2500, success_url, cancel_url }
3. API creates Stripe Checkout Session (mode: "payment")
4. API returns { url: "https://checkout.stripe.com/..." }
5. User completes payment
6. Stripe redirects to success_url with session_id
7. Frontend calls GET /api/balance/verify?session_id=...
8. API verifies payment and credits the wallet
ConstraintValue
Minimum deposit$5.00 (500 cents)
Maximum deposit$500.00 (50,000 cents)

Marketplace creators earn revenue when consumers use their paid tools, functions, and agents. Payouts are processed via Stripe Connect.

  1. Creator publishes a paid tool to the marketplace
  2. Consumer calls the tool, and wallet is debited
  3. Marketplace fee is retained by Aerostack
  4. Remainder credited to the creator’s developer balance
  5. Payout transferred to the creator’s bank via Stripe Connect

Before receiving payouts, creators must complete Stripe Connect onboarding:

  1. Navigate to Settings > Payouts in the Aerostack Dashboard
  2. Click Connect with Stripe
  3. Complete Stripe’s identity verification and banking setup
  4. Once verified, payouts are enabled
SettingOptions
Payout frequencyManual, Weekly, Monthly
Minimum payout$10.00
CurrencyUSD

After any Stripe checkout redirect (plan upgrade or wallet deposit), verify the session to ensure the payment was processed:

Terminal window
curl "https://api.aerostack.dev/api/billing/verify-session?session_id=cs_live_..." \
-H "Authorization: Bearer YOUR_JWT"

Response:

{
"tier": "pro"
}
Terminal window
curl "https://api.aerostack.dev/api/balance/verify?session_id=cs_live_..." \
-H "Authorization: Bearer YOUR_JWT"

Response:

{
"deposited": true,
"amount_cents": 2500
}

All Stripe redirect URLs (success_url, cancel_url, return_url) are validated against an allowlist:

Allowed OriginPurpose
https://app.aerostack.devProduction dashboard
https://aerostack-admin.pages.devCloudflare Pages deploys
https://*.aerostack-admin.pages.devPreview deploys
http://localhost:5173Local development

Requests with redirect URLs on other origins are rejected with a 400 error. This prevents open redirect attacks.


During development, use Stripe test mode keys (sk_test_...) instead of live keys. Test mode:

  • Uses test credit card numbers (e.g. 4242 4242 4242 4242)
  • Does not charge real money
  • Sends webhooks to your test endpoint
  • Creates test subscriptions that behave like real ones

  1. Verify the webhook URL is correct: https://api.aerostack.dev/api/billing/webhook
  2. Check the webhook signing secret is set: aerostack secrets list
  3. In Stripe Dashboard > Webhooks, check the event delivery logs for errors
  4. Ensure payload type is “Snapshot” (not “Thin”)
  1. Call GET /api/billing/verify-session?session_id=... to force verification
  2. Check Stripe Dashboard for the checkout session status
  3. If the webhook failed, the verify endpoint handles plan updates as a fallback
  1. Call GET /api/balance/verify?session_id=... to force verification
  2. Ensure the checkout session completed successfully in Stripe
  3. Check for duplicate verification (the endpoint is idempotent)