Payments

Stripe integration

Ahena works with your Stripe account: it checks the account is ready to take payments, keeps test and live modes in the right environments, sets up webhooks and your product catalog, and generates checkout, billing portal, Connect and webhook code. Your app talks to Stripe directly. Ahena is never in the payment path.

Live verifiedLive verified: connection and permission checks, Doctor, planning, and creating webhooks, products and prices without duplicates (Stripe test mode)Full Stripe docs

What Ahena inspects

Read-only: inspecting and Doctor never change anything at Stripe.

  • The key's mode (test or live) and kind (secret or restricted), and whether a restricted key can write products, prices and webhook endpoints.
  • Whether charges and payouts are enabled, and any outstanding account requirements.
  • Webhook endpoints, products and prices, against payments in ahena.config.ts.
  • Whether the account is a Connect platform (with connect: true).

What Ahena configures

You declare what you want in ahena.config.ts; ahena plan shows each change with its classification before anything is applied.

ChangeClassificationNotes
Create the webhook endpointCONFIRMATION_REQUIREDThe signing secret is returned once and stored encrypted as STRIPE_WEBHOOK_SECRET.
Create a product (ahena_<key>)CONFIRMATION_REQUIREDIdempotent: a fixed product id plus idempotency keys.
Create a price (by lookupKey)CONFIRMATION_REQUIREDCreating a price charges no one.

Refused outright:

  • A changed amount for an existing lookupKey: Stripe prices are immutable, so Ahena asks for a new key rather than moving customers silently.
  • A test-mode key in production, before contacting Stripe.

Generated code: src/ahena/payments (Checkout and billing portal), Connect helpers with connect: true, and with Next.js a webhook route that verifies stripe-signature against the raw body.

How Ahena verifies

After every write, Ahena reads Stripe back. Each change ends in one of these states, and the plan's outcome says why:

  • VERIFIED: Ahena read the provider back and saw the desired state. The CLI shows ✓ only for VERIFIED.
  • APPLIED_UNVERIFIED: The provider accepted the change, but the re-read doesn't show it yet (after bounded polling), or the re-read failed.

Webhook endpoints are created with a stable idempotency key, so a retry after a lost response replays the original endpoint and its signing secret instead of making a duplicate. Products and prices use idempotency keys and deterministic ids, and every create is read back.

If a request may have reached Stripe but the answer was lost, Ahena re-reads before deciding: done, safe to retry, or “check before retrying”.

What Doctor diagnoses

Key checks from ahena doctor. Each finding says why it matters, where, the impact and whether Ahena can fix it. The full list is in the Stripe docs.

CheckWhat it means
stripe.modeA test key in production (FAIL) or a live key elsewhere (WARNING).
stripe.key_kindA full secret key in production; a restricted key would limit exposure.
stripe.account / .verificationCharges enabled and no outstanding requirements; otherwise the onboarding steps.
stripe.webhookEndpoint exists, enabled, with the needed events.
stripe.webhook.endpointYour route rejects an unsigned request.
stripe.prices / .mismatchConfigured prices exist and match.

More on findings, health and continuous checks: Doctor.

Approvals

Stripe changes here are classified CONFIRMATION_REQUIRED. Every change is planned and shown as a diff first. Ahena itself enforces who can approve it:

  • SAFE changes are applied without asking.
  • In production, every other change needs approval in the Ahena dashboard, signed in, by an admin.
  • In other environments, CONFIRMATION_REQUIRED changes are approved in the CLI; BILLABLE and DESTRUCTIVE changes always need the dashboard.
  • MANUAL steps are never applied by Ahena.

An environment holding a live Stripe key is treated as production, whatever its kind, so every change that isn't SAFE goes through the dashboard.

--yes and --allow-billable don't replace a dashboard approval. See approvals for how it works and why the browser.

Manual steps

These are MANUAL: Ahena never does them. It lists them with the exact steps when they apply.

  • Activate the account (business details and bank account) before live payments. Doctor lists outstanding requirements.
  • Marketplaces: enable Connect and complete the platform profile in the Stripe dashboard.
  • Put a live restricted key in production and a test key everywhere else.

Credentials and permissions

NameSecretNotes
STRIPE_SECRET_KEYYesA restricted key (rk_…, recommended) or a secret key (sk_…). A live key makes the environment count as production for approvals.
STRIPE_WEBHOOK_SECRETYesCreated by Ahena with the webhook endpoint and stored encrypted in that environment.

Least privilege

  • Use a restricted key with only Account: Read; Webhook Endpoints: Write; Products: Write and Prices: Write; and Connect: Read if you use Connect.
  • Ahena never needs Charges, Customers, Payment Intents or Payouts permissions, and never creates a charge.

Each credential Ahena stores gets its own key and is envelope-encrypted, bound to the environment. See security.

Workflow example

Connect, check, plan, then apply. Placeholders (…) stand for your own values.

  1. STRIPE_SECRET_KEY=rk_live_… ahena connect stripe -e production

    Connect a live restricted key to production.

  2. ahena doctor -e production

    Check key mode, account readiness, the webhook and prices.

  3. ahena plan -e production

    See the webhook, product and price creates.

  4. ahena apply -e production

    Approve in the dashboard, signed in; Ahena applies and reads each create back.

  5. ahena generate stripe -e production --framework nextjs

    Write checkout, portal and webhook code.

Verification status

Live verified

Live verified: connection and permission checks, Doctor, planning, and creating webhooks, products and prices without duplicates (Stripe test mode)

Verified against the real provider API for the capabilities listed. Its other capabilities are validated by Ahena's automated provider contract and conformance tests.

How Stripe is tested
  • Verified against real Stripe in test mode (2026-10-03, run again 2026-10-04 with a restricted key): connect, authentication, Doctor before and after, and a plan with three creates and then none.
  • Creates (one webhook, one product, one price), idempotent replays (same objects, no duplicates) and read-backs ran through Ahena's real-provider test harness, which records and cleans up every resource. They haven't yet run through ahena apply itself.
  • A restricted key's permissions were confirmed on the "allowed" side. The "missing permission" side and multi-page listings aren't verified against real Stripe yet, and live mode hasn't been exercised.
  • The generated payments code is typechecked against the Stripe SDK; tests check only that the client is constructed, and the webhook route isn't executed.

The providers overview explains Ahena's testing methodology and what has been verified for every provider.

Limitations

  • Customers, subscriptions, saved cards and payment history aren't moved or managed.
  • Test-mode and live-mode catalogs are separate, as in Stripe; configure each environment.
  • Tax, invoicing, branding and payout schedules aren't managed.

Disconnecting

ahena disconnect stripe removes the stored key (roll or delete it in the Stripe dashboard); products, prices, webhooks, customers and payments are untouched.