Payment Providers
Aerostack uses a dual payment gateway system that automatically selects the right provider for each user based on their country:
| Region | Provider | Why |
|---|---|---|
| India | Razorpay | UPI, net banking, INR pricing |
| All other countries | Stripe | Global card processing, USD pricing |
Your payment provider is auto-detected on signup and stored in your account. All billing flows (plan checkout, wallet deposits, creator payouts) route through your assigned provider.
How Provider Selection Works
1. User signs up → country detected (from IP or profile)
2. India → Razorpay assigned
3. Other → Stripe assigned
4. Provider stored in account_plans.payment_gateway
5. All future billing uses this providerYou can see your assigned provider in the billing API response:
curl https://api.aerostack.dev/api/billing \
-H "Authorization: Bearer YOUR_JWT"{
"plan_tier": "starter",
"payment_gateway": "razorpay",
"status": "active"
}Razorpay (India)
Razorpay handles all payment processing for Indian users: plan subscriptions, wallet deposits, and creator payouts.
Supported Payment Methods
- UPI (Google Pay, PhonePe, Paytm)
- Net Banking
- Debit/Credit Cards
- Wallets
Pricing in INR
All plans are displayed in INR for Indian users. The conversion rate is applied at billing time.
Webhook Configuration
Razorpay webhooks keep Aerostack in sync with subscription changes:
Endpoint:
POST https://api.aerostack.dev/api/billing/webhook/razorpayEvents handled:
payment.captured— payment successfulsubscription.activated— plan subscription startedsubscription.charged— recurring payment succeededsubscription.cancelled— subscription cancelledpayment.failed— payment failed
Stripe (Global)
Stripe handles payment processing for users outside India: plan subscriptions, wallet deposits, and creator payouts via Stripe Connect.
How Stripe is Used
| Feature | Stripe Product | Description |
|---|---|---|
| Platform plans | Subscriptions | Monthly/yearly recurring billing for plan tiers |
| Wallet deposits | Checkout Sessions | One-time payments to fund the prepaid wallet |
| Creator payouts | Connect | Transfer marketplace earnings to creator bank accounts |
| Customer portal | Customer Portal | Self-service billing management (invoices, payment methods) |
Webhook Configuration
Stripe webhooks keep Aerostack in sync with subscription changes:
Endpoint:
POST https://api.aerostack.dev/api/billing/webhookThis endpoint:
- Requires no authentication (it is public)
- Validates the
stripe-signatureheader against your webhook signing secret - Processes the event and updates the account plan accordingly
Events to configure:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
Use Snapshot payload, not Thin. When configuring the webhook in Stripe, ensure the payload type is set to “Snapshot” (default). Thin payloads require an additional API call to retrieve the full event, which is not supported.
Stripe Customer Portal
Stripe users can manage their subscription through the Stripe Customer Portal:
- View and download invoices
- Update payment methods
- Switch billing intervals (monthly/yearly)
- Cancel subscription
curl "https://api.aerostack.dev/api/billing/portal?return_url=https://app.aerostack.dev/settings/billing" \
-H "Authorization: Bearer YOUR_JWT"Plan Checkout Flow
The checkout flow is the same regardless of provider — only the redirect URL changes:
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 checkout session with the user's assigned provider
4. API returns { url: "..." } (Razorpay or Stripe checkout URL)
5. User completes payment on the provider's page
6. Provider redirects to success_url with session_id
7. Frontend calls GET /api/billing/verify-session?session_id=...
8. API verifies payment and upgrades the plan immediately
9. Provider also sends webhook for redundancyBilling Intervals
Each paid plan supports monthly and yearly billing:
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 checkout.
Wallet Deposits
Wallet deposits use one-time payment sessions (not subscriptions).
curl -X POST https://api.aerostack.dev/api/balance/deposit \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"amount_cents": 2500,
"success_url": "https://app.aerostack.dev/settings/billing?deposit=success",
"cancel_url": "https://app.aerostack.dev/settings/billing"
}'| Constraint | Value |
|---|---|
| Minimum deposit | $5.00 (500 cents) |
| Maximum deposit | $500.00 (50,000 cents) |
Creator Payouts
Marketplace creators earn revenue when consumers use their paid tools, functions, and agents.
How it Works
- Creator publishes a paid tool to the marketplace
- Consumer calls the tool, and their wallet is debited
- Marketplace fee is retained by Aerostack
- Remainder credited to the creator’s developer balance
- Payout transferred to the creator’s bank via the provider’s payout system
Payout Configuration
| Setting | Options |
|---|---|
| Payout frequency | Manual, Weekly, Monthly |
| Minimum payout | $10.00 |
| Currency | USD (Stripe) / INR (Razorpay) |
Redirect URL Security
All redirect URLs (success_url, cancel_url, return_url) are validated against an allowlist:
| Allowed Origin | Purpose |
|---|---|
https://app.aerostack.dev | Production dashboard |
https://aerostack-admin.pages.dev | Cloudflare Pages deploys |
https://*.aerostack-admin.pages.dev | Preview deploys |
http://localhost:5173 | Local development |
Requests with redirect URLs on other origins are rejected with a 400 error.
Verify Session After Redirect
After any checkout redirect (plan upgrade or wallet deposit), verify the session:
# Plan upgrade
curl "https://api.aerostack.dev/api/billing/verify-session?session_id=..." \
-H "Authorization: Bearer YOUR_JWT"
# Wallet deposit
curl "https://api.aerostack.dev/api/balance/verify?session_id=..." \
-H "Authorization: Bearer YOUR_JWT"Session verification is idempotent. Calling it multiple times with the same session_id will not duplicate the plan upgrade or wallet deposit.
Troubleshooting
Webhook Not Receiving Events
- Verify the webhook URL is correct for your provider
- Check the webhook signing secret is configured
- In your provider’s dashboard, check event delivery logs for errors
Plan Not Updating After Checkout
- Call
GET /api/billing/verify-session?session_id=...to force verification - Check your payment provider’s dashboard for the checkout session status
- If the webhook failed, the verify endpoint handles plan updates as a fallback
Wallet Balance Not Credited
- Call
GET /api/balance/verify?session_id=...to force verification - Ensure the checkout session completed successfully
- Check for duplicate verification (the endpoint is idempotent)