Skip to the article
Aniq-UI

E-CommercePayments

Payments

How the checkout takes payment, how to connect Stripe, and what happens to an order at each step.

For the Full Stack package

How the checkout takes payment

The storefront offers two ways to pay: a card through Stripe, and cash on delivery. There is no PayPal option in the checkout. Both create the order on the API first, priced by the API from its own catalogue, never from the prices the browser sends.

MethodWhat happens to the order
Card (Stripe)Saved as pending and unpaid. The API asks Stripe for a payment and the storefront confirms the card on the same page. When Stripe reports the payment through the webhook, the order becomes paid and confirmed; a declined card marks it failed.
Cash on deliverySaved as confirmed and unpaid straight away. You collect the money on delivery and move the order on in the dashboard.

Cash on delivery is selected by default. Guests can check out with their email; signed-in customers see the order in their account.

Shipping is free from $75 and costs $9.99 below it, and there is no tax. The cart, the checkout summary and the API apply the same rule, so the total a shopper sees is the total charged. The storefront keeps the rule in storefront/src/config/shipping.ts and the API in back-end/src/modules/orders/orders.service.ts: change both together. Stripe charges in US dollars.

Connect Stripe

  1. Add your API keys

    From the Stripe dashboard's API keys page, put the secret key in back-end/.env. Use the test keys (sk_test_…) until you are ready to take real money.

    back-end/.env
    STRIPE_SECRET_KEY=sk_test_…
  2. Subscribe the webhook

    In Stripe, add a webhook endpoint at your API's address followed by /api/payments/webhook, subscribed to payment_intent.succeeded and payment_intent.payment_failed. Copy its signing secret into back-end/.env.

    back-end/.env
    STRIPE_WEBHOOK_SECRET=whsec_…
  3. Give the storefront its publishable key

    Set the publishable key in the storefront's .env, then rebuild it: the key is compiled in. With Docker Compose, put it in the .env next to docker-compose.yml and run docker compose up --build.

    storefront/.env
    NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_…
  4. Restart the API

    Expected result: The API's log says "Stripe initialized", and the checkout shows the card form.

The webhook marks the order paid

An order is marked paid when Stripe calls the webhook, not when the shopper returns from the payment. Without the subscription and its signing secret, card orders stay pending and unpaid.

To test the webhook on your own machine, the Stripe CLI can forward events to http://localhost:8000/api/payments/webhook and prints the signing secret to use while it runs.

Without Stripe

  • Without NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, or with anything that is not a real pk_test_… or pk_live_… key, the card option at checkout says "Card payments are unavailable right now. Please choose cash on delivery." and hides the card field.
  • Without STRIPE_SECRET_KEY, or with the .env.example placeholder, the API takes no card payment: an order placed with the card method is saved as pending and unpaid.
  • Cash on delivery works either way.
  • On the storefront's sample store, with no API at all, checkout completes without calling Stripe and nothing is charged.

Taking real payments

  • Swap in the live keys (sk_live_… and pk_live_…) and a webhook created in live mode, which has its own signing secret.
  • Set NEXT_PUBLIC_DEMO_CHECKOUT=false, so the checkout is not prefilled with a generated buyer.
  • Prices are charged in US dollars. To sell in another currency, change the currency the API sends to Stripe in back-end/src/modules/payments/payments.service.ts, and set NEXT_PUBLIC_ANALYTICS_CURRENCY to match.

Stuck on a step?

Find a fix before you start over.

Troubleshooting

Cookie Preferences

We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising.