Skip to content

Stripe payments

@adocommercekit/stripe implements the Adocommerce Kit payment-provider contract with Stripe PaymentIntents.

@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/stripe

The configure hook adds these variables to .env and start/env.ts:

STRIPE_SECRET_KEY=sk_test_replace_me
STRIPE_WEBHOOK_SECRET=whsec_replace_me

Use 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/stripe

Subscribe 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 commerceRawBody that 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/stripe

Copy 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/checkout

The 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:

  1. create the Adocommerce Kit payment intent for the cart;
  2. return an intentionally decrypted client secret to the authorized storefront session;
  3. confirm required action with Stripe.js;
  4. resume checkout with the same Adocommerce Kit intent and idempotency scope;
  5. 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.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close