Skip to content

Stripe Setup

AvailEngine uses Stripe for three things: developer subscriptions, business deposit payments, and Connect payouts. This guide walks through everything you need to configure.

1. Create a Stripe Account

Go to dashboard.stripe.com and sign up. Stripe is available in 46+ countries.

Use test mode (the toggle in the top-right of the dashboard) during development — all API calls, webhooks, and payments will be simulated. Switch to live mode when you're ready to go to production.

2. Get Your API Keys

  1. Go to Developers > API keys
  2. Copy your Secret key (sk_live_... or sk_test_... in test mode)

Add it to your backend .env file:

bash
STRIPE_SECRET_KEY=sk_test_51...

The publishable key (pk_...) is only needed if you're building a custom frontend that uses Stripe.js directly. AvailEngine uses server-side Stripe APIs and does not require the publishable key.

3. Create Products & Prices

AvailEngine uses a 4-tier subscription model (3 paid tiers). Create these products in Stripe:

Product NamePriceBillingENV Variable
AvailEngine Starter€9.99Monthly recurringSTRIPE_PRICE_STARTER
AvailEngine Growth€29.99Monthly recurringSTRIPE_PRICE_GROWTH
AvailEngine Scale€129.00Monthly recurringSTRIPE_PRICE_SCALE

For each product:

  1. Go to Products
  2. Click + Add product
  3. Name: As listed above
  4. Pricing model: Standard pricing (recurring)
  5. Price: As listed above, billing period: Monthly
  6. Save and copy the Price ID (looks like price_1A2B3C4D...)

Add to your .env:

bash
STRIPE_PRICE_STARTER=price_XXXXX
STRIPE_PRICE_GROWTH=price_XXXXX
STRIPE_PRICE_SCALE=price_XXXXX

4. Set Up Webhooks

Stripe sends events to your server to keep subscription and payment state in sync.

  1. Go to Developers > Webhooks
  2. Click Add endpoint
  3. Endpoint URL: https://your-api-domain.com/webhooks/stripe
  4. Listen to these events:
EventWhy
payment_intent.succeededBooking deposit charged — confirms booking
payment_intent.payment_failedDeposit failed — cancels booking
payment_intent.amount_capturable_updatedAuthorization hold placed — confirms booking
checkout.session.completedCheckout paid — activates subscription or confirms staff deposit
checkout.session.expiredCheckout expired — cancels unpaid booking
account.updatedConnect account status changed — syncs onboarding state
customer.subscription.createdNew subscription — syncs developer profile
customer.subscription.updatedSubscription changed — syncs status/price
customer.subscription.deletedSubscription cancelled — marks developer as cancelled
invoice.payment_succeededInvoice paid — keeps developer active
invoice.payment_failedInvoice failed — marks developer as past_due (blocks API)
  1. Click Add endpoint
  2. Copy the Signing secret (whsec_...)

Add to your .env:

bash
STRIPE_WEBHOOK_SECRET=whsec_abc123...

Local Testing with Stripe CLI

Install the Stripe CLI and forward events to your local server:

bash
stripe listen \
  --events payment_intent.succeeded,payment_intent.payment_failed,\
payment_intent.amount_capturable_updated,checkout.session.completed,\
checkout.session.expired,account.updated,customer.subscription.created,\
customer.subscription.updated,customer.subscription.deleted,\
invoice.payment_succeeded,invoice.payment_failed \
  --forward-to localhost:8000/webhooks/stripe

The CLI prints a signing secret — use it as STRIPE_WEBHOOK_SECRET in your local .env.

5. Enable Stripe Connect (Optional)

Stripe Connect lets your businesses accept deposit payments. If your businesses don't need deposits, skip this section.

  1. Go to Connect > Settings

  2. Configure your brand settings (business name, logo)

  3. In your AvailEngine app, businesses onboard through the API:

    bash
    curl -X POST https://api.availengine.com/v1/billing/connect/onboard \
      -H "Authorization: Bearer YOUR_JWT_TOKEN"

    This returns an onboarding URL — redirect the business owner there.

  4. Webhook account.updated fires when onboarding completes. AvailEngine syncs the status to businesses.stripe_connect_status.

Connect account types

AvailEngine creates Express accounts by default. Express accounts handle onboarding, identity verification, and payouts — you don't need to manage that yourself.

6. Brand Your Checkout

  1. Go to Settings > Branding
  2. Upload your business logo and icon
  3. Set your brand color
  4. Set your accent color

These appear on the Stripe-hosted Checkout page when developers subscribe.

7. Test Your Setup

Test Card Numbers

CardNumberEffect
Visa4242 4242 4242 4242Success
Visa (debit)4000 0566 5566 5556Success
3D Secure4000 0000 0000 3220Requires 3DS (use any value)
Declined4000 0000 0000 0002Generic decline
Insufficient funds4000 0000 0000 9995Insufficient funds

Use any future expiry date, any CVC, and any postal code.

Verification Checklist

  1. Developer subscription: Subscribe through the dashboard → verify developer_profiles.subscription_status = active
  2. Metered billing: Create 3 non-sandbox businesses → check Stripe Dashboard > Billing for metered usage
  3. Deposit payment: Make a public booking → verify payment_intent.succeeded webhook processes it
  4. Authorization hold: Make a booking with hold → verify amount_capturable_updated fires
  5. Connect onboarding: Go through the Connect flow → verify businesses.stripe_connect_status = active
  6. Past-due blocking: Simulate a failed invoice → verify API returns 402

Send Test Webhooks

In the Stripe Dashboard, go to Webhooks > your endpoint > Send test webhook. Select an event type and send it — verify your server returns 200 {"status":"success"}.

8. Go Live

Before switching to production:

  • [ ] Replace sk_test_ with sk_live_ in .env
  • [ ] Create live Price IDs and update STRIPE_PRICE_STARTER, STRIPE_PRICE_GROWTH, STRIPE_PRICE_SCALE
  • [ ] Update STRIPE_WEBHOOK_SECRET to the live endpoint's signing secret
  • [ ] Update APP_BASE_URL and API_BASE_URL to production URLs
  • [ ] Verify webhook endpoint points to production domain
  • [ ] Configure CORS origins in .env for production
  • [ ] Set ENVIRONMENT=production
  • [ ] Test the full flow end-to-end in live mode with a real card

Troubleshooting

Webhook returns 400

The STRIPE_WEBHOOK_SECRET doesn't match the endpoint's signing secret. Verify you're using the correct secret from the Stripe Dashboard (test mode and live mode have different secrets).

Webhook returns 500

Check server logs. Common causes: database connection issues, missing tables, or RLS policy blocks.

PaymentIntent fails with "No such customer"

The Stripe Customer wasn't created before the payment. AvailEngine creates customers automatically during subscription checkout — make sure the stripe_customer_id column is populated in developer_profiles.

Subscription not syncing

If subscription webhooks aren't updating developer_profiles, verify:

  1. The webhook endpoint URL is correct in Stripe Dashboard
  2. customer.subscription.* events are selected
  3. Your server is reachable from the internet (use Stripe CLI for local testing)

Connect onboarding won't complete

Express accounts require identity verification. The business owner must complete the full Stripe onboarding flow. Check businesses.stripe_connect_status via the API:

bash
curl https://api.availengine.com/v1/billing/connect/status \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Released under the MIT License.