@adocommercekit/stripe implements the Adocommerce Kit payment-provider contract with Stripe PaymentIntents. It creates and confirms intents, captures authorized funds, refunds or voids payments, verifies webhook signatures, and normalizes supported Stripe events.
The package and the generated storefront flow are beta. Read Strong Customer Authentication before using the default checkout controller in a market where additional customer action is common.
Install
Install the Stripe package at the same version as core:
pnpm add @adocommercekit/stripe
node ace configure @adocommercekit/stripeThe configure hook adds these variables to .env and start/env.ts:
STRIPE_SECRET_KEY=sk_test_replace_me
STRIPE_WEBHOOK_SECRET=whsec_replace_meUse a restricted or secret server key. Never expose it to storefront JavaScript. The webhook secret is specific to the registered endpoint and is not an API key.
Register the driver
Update config/commerce.ts:
import env from "#start/env";
import { defineConfig } from "@adocommercekit/core";
import { manualPayment } from "@adocommercekit/core/drivers";
import { stripe } from "@adocommercekit/stripe";
export default defineConfig({
// Other Adocommerce Kit settings...
payments: {
default: "stripe",
captureMode: "automatic",
methods: {
stripe: stripe({
apiKey: env.get("STRIPE_SECRET_KEY"),
webhookSecret: env.get("STRIPE_WEBHOOK_SECRET"),
}),
manual: manualPayment(),
},
},
});Keeping manual registered is optional. It is useful for local development, but do not accept it from an untrusted production storefront unless offline payment is an intentional business method.
The Stripe driver creates PaymentIntents with capture_method=manual. Adocommerce Kit’s payments.captureMode decides whether checkout captures an authorization immediately (automatic) or leaves it authorized (manual).
Configure the webhook
When @adocommercekit/storefront-api is installed, point Stripe to:
POST https://your-store.example/api/commerce/webhooks/payments/stripeSubscribe to the payment-intent, charge, and refund events your integration uses. Unknown event types are recorded as unhandled and acknowledged; duplicate provider event IDs are deduplicated.
The published route applies commerceRawBody before the controller. Signature verification must receive the exact bytes sent by Stripe:
- do not parse and re-stringify the request body;
- keep the webhook outside browser CSRF enforcement;
- do not place middleware before
commerceRawBodythat consumes or changes the body; - return a public HTTPS endpoint in production.
The storefront configurator adds /api/commerce/webhooks/payments/* to Shield’s exceptRoutes when it can update the standard Shield configuration. Verify that exclusion after configuration.
Test locally
Run the application, then forward Stripe CLI events:
stripe listen \
--forward-to localhost:3333/api/commerce/webhooks/payments/stripeCopy the whsec_... secret printed by the CLI into STRIPE_WEBHOOK_SECRET, then restart Adonis so the environment and driver are reloaded.
For a test checkout, use Stripe’s test PaymentMethod ID as the storefront payment.token:
curl -X POST -c .cart-cookie -b .cart-cookie \
-H 'content-type: application/json' \
-H 'Idempotency-Key: stripe-test-001' \
-d '{"payment":{"method":"stripe","token":"pm_card_visa"}}' \
http://localhost:3333/api/commerce/checkoutThe cart must already contain a line, email, address, and selected shipping method. Follow Build a store through the shipping step first.
Adocommerce Kit derives provider idempotency keys from the checkout key and forwards them in Stripe’s Idempotency-Key header. Repeating the same checkout request does not intentionally create a second PaymentIntent or order.
Strong Customer Authentication
The published checkout endpoint is a single server round trip. It accepts a Stripe PaymentMethod ID in payment.token, creates a PaymentIntent, and confirms it server-side. It completes when Stripe returns an authorized state.
If Stripe returns requires_action, core persists that state but the generated storefront controller does not expose the encrypted client secret or a resume endpoint. Therefore the generated controller is not a complete 3DS/SCA browser flow.
Before supporting cards that may require customer action, adapt the host-owned HTTP surface to:
- create the Adocommerce Kit payment intent for the cart;
- return an intentionally decrypted client secret to the authorized storefront session;
- confirm required action with Stripe.js;
- resume checkout with the same Adocommerce Kit intent and idempotency scope;
- verify final state through Stripe and webhooks before fulfillment.
Do not expose clientSecretEnc directly and do not treat a browser callback as proof of payment. This flow is application-owned until Adocommerce Kit publishes a dedicated SCA storefront contract.
Capture and refunds
With captureMode: 'automatic', checkout captures after authorization and before final completion. With manual, the payment remains authorized; host code is responsible for calling the payment service’s capture operation before the authorization expires.
Refund and void operations are available through PaymentService. The REST storefront does not publish customer-facing refund endpoints. Expose them only through an authenticated back-office or a trusted job.
Production checklist
- Replace all
sk_test_and CLI webhook secrets with live-mode values. - Register the exact production webhook URL and selected event types in Stripe.
- Keep the secret key and webhook secret in the deployment secret store.
- Confirm the application or proxy preserves the raw webhook request body.
- Use HTTPS and verify proxy forwarding rules for the webhook path.
- Send a real low-value payment through authorization, capture, webhook ingestion, and refund in the target environment.
- Decide whether the generated synchronous checkout meets the required SCA/payment-method contract.
- Monitor signature failures, provider declines, stuck checkouts, and unprocessed webhook events.