HOW TO TEST

How to Test a Checkout Flow.

E-Commerce A complete testing guide for e-commerce checkout: cart validation, discounts, address handling, shipping methods, tax, payment success and failure, order confirmation, inventory updates, refunds, guest vs authenticated checkout, and API-layer validation.

13
scenarios
9
test cases
16 min
read
intermediate5–8 hours (full suite); 1–2 hours (smoke pass covering happy path + payment failure + inventory check) testingQA engineersSDETsAutomation engineers

Checkout is the highest-revenue-risk surface in any e-commerce application. A bug that prevents payment, double-charges a customer, or fails to decrement inventory can cost thousands of dollars per hour. This guide covers the complete checkout surface: cart state and quantity validation, coupon and discount application, shipping address and method selection, tax calculation, payment processing (success, decline, network failure, cancellation), order confirmation emails, inventory decrements, guest and authenticated checkout, refunds, and API-level idempotency. All test cases are written for a Cypress/Playwright engineer with access to a sandbox payment gateway.

Risks

Double-charge on payment retry

If the payment POST is not idempotent and the user retries after a network timeout, two charges can be created for the same order. Without server-side deduplication, the customer is charged twice and inventory decremented twice.

Inventory not decremented — overselling

If inventory is decremented only after payment confirmation (not atomically), a race condition between two concurrent checkouts for the last item in stock can sell the item to both customers.

Price tampering via API

If the client sends the item price in the checkout POST body and the server uses it without re-verifying against the product catalogue, an attacker can set the price to $0.00 or $0.01.

Coupon codes stackable or reusable beyond their limit

Discount codes that can be applied multiple times in the same checkout (stacking beyond intent) or reused after their single-use limit is exhausted result in unintended revenue loss.

Tax calculation incorrect for cross-border or exempted customers

Tax is jurisdiction-specific. Incorrect tax for international orders or for tax-exempt customers (B2B, non-profit) can create legal liability and customer disputes.

Order created without payment confirmation

An asynchronous webhook from the payment provider may arrive before the synchronous response in some failure modes, or a race condition can mark an order 'paid' before the payment is actually confirmed, shipping goods for free.

Guest checkout data persisted insecurely

Guest checkout collects sensitive PII (name, address, card details passed through the UI). If this data is logged, stored in plaintext, or linked to a weak session, it can be accessed by subsequent users on shared devices.

Test Scenarios

Successful authenticated checkout with credit card creates an order

CriticalfunctionalFully automated

Complete end-to-end checkout as a logged-in user with a test card. Assert order is created, confirmation email sent, inventory decremented, and order appears in the user's order history.

Guest checkout completes without an account

CriticalfunctionalFully automated

Complete checkout without logging in. Assert order is created, confirmation email sent to the provided email, and no user account is created unless explicitly offered.

Declined card shows a clear error and preserves cart state

CriticalnegativeFully automated

Use a test card that triggers a decline. Assert an error message is shown (not a 500), the cart is preserved, and no order or charge is created.

Network error during payment does not double-charge

CriticalnegativeFully automated

Simulate a network timeout after the payment POST is sent (drop the response). Re-submit the same checkout. Assert only one charge is created (idempotency key enforced).

Valid coupon code applies correct discount

HighfunctionalFully automated

Apply a valid coupon at checkout. Assert the discount is reflected in the order total before payment, the correct amount is charged, and the coupon is marked used (if single-use).

Invalid or expired coupon code is rejected

HighnegativeFully automated

Apply an expired coupon, a non-existent code, and a used single-use code. Assert each is rejected with a clear error and the order total is unchanged.

Inventory is decremented after successful payment

CriticalfunctionalFully automated

Before checkout, record stock quantity for the item. After successful payment, assert the stock is reduced by the purchased quantity. Verify via the admin API or database.

Server ignores client-submitted price and uses catalogue price

CriticalsecurityFully automated

Intercept the checkout POST request and modify the item price to $0.01. Assert the server charges the correct catalogue price and returns an error or corrects the amount.

Order confirmation email contains correct order details

HighfunctionalFully automated

After successful checkout, assert a confirmation email arrives with correct: item names, quantities, prices, shipping address, and order reference number.

Cart quantity updates reflect in checkout total

HighfunctionalFully automated

Update item quantity in the cart (increase, decrease, remove). Assert the checkout summary and the payment amount update correctly before and after proceeding to payment.

Missing required address fields block checkout

HighnegativeFully automated

Attempt checkout with each required address field omitted. Assert the form blocks progress and shows a field-level error message.

Refund reverses payment and restores inventory

HighfunctionalFully automated

Trigger a full refund via the admin panel or refund API. Assert the payment is reversed in the payment gateway, the order status changes to 'refunded', and inventory is restored.

Checkout form is keyboard-operable and screen-reader accessible

HighaccessibilityManual only

Tab through the entire checkout flow. Assert all form fields have visible labels, error messages are associated via aria-describedby, and the payment button is reachable and operable via keyboard.

Detailed Test Cases

Preconditions

  • At least one in-stock product in the catalogue
  • Authenticated test user with a saved address
  • Stripe test card: 4242 4242 4242 4242 (or equivalent sandbox card)
  • Test inbox accessible via API

Steps

  1. 1.Add one unit of an in-stock product to the cart via API (POST /api/cart)
  2. 2.Navigate to /checkout
  3. 3.Assert order summary shows correct item name, quantity, and price
  4. 4.Select or confirm shipping address
  5. 5.Select a shipping method — assert total updates with shipping cost
  6. 6.Assert tax line is displayed (if applicable to the jurisdiction)
  7. 7.Enter test card details: 4242 4242 4242 4242, exp 12/26, CVV 123
  8. 8.Click 'Place order'
  9. 9.Assert redirect to /order-confirmation/{orderId}
  10. 10.Assert confirmation page shows order reference, items, and total
  11. 11.Poll test inbox — assert confirmation email arrives within 60 s
  12. 12.Assert email contains: order reference, item list, shipping address, total charged
  13. 13.Assert inventory for the purchased item decremented by 1 via GET /api/products/{id}

Expected result

Order created, charge processed, confirmation email received, inventory decremented.

Test data

  • Card: 4242 4242 4242 4242 / 12/26 / 123
  • Product: first in-stock item from API
  • Quantity: 1

Edge Cases

Item goes out of stock between cart add and checkout

A user adds an item to their cart, but it sells out while they are filling in payment details. The checkout POST should return a clear 'item no longer available' error, not a silent failure or a generic 500.

Price changes between cart add and checkout

If the price of an item increases after a user adds it to their cart, the checkout should use the current price (not the cart-cached price), and the user should be notified if the price changed.

Cart contains a mix of in-stock and out-of-stock items

The checkout flow should clearly communicate which items cannot be fulfilled and offer options: remove out-of-stock items and continue, or wait for restocking.

Applying a coupon that brings the total below zero

A coupon for $20 off applied to a $15 order. The final amount must be $0 (not a negative charge or a credit).

Back button during 3DS authentication cancels the payment

If a user presses Back during a 3D Secure authentication popup, the payment is cancelled. The application should detect the cancellation and return the user to the payment form cleanly.

Browser tab closed mid-payment after the charge was captured

If the browser is closed after the payment gateway confirms the charge but before the success redirect completes, the order exists in the payment system but not in the application. The webhook must create the order record.

Checkout with maximum cart quantity

Adding 999 of an item that has a max-quantity restriction of 5 per order. The server should enforce the limit, not the UI alone.

Checkout with a PO box address rejected by some shipping carriers

Some shipping methods (e.g. UPS, FedEx) cannot deliver to PO boxes. The address validation should reject these combinations with a clear carrier-specific message.

Payment for exactly $0.00 (free order via 100% coupon)

A 100% discount coupon makes the order free. The payment step should be skipped or handled as a $0 charge. Attempting to process a $0 payment with some gateways returns an error.

Two separate sessions with the same last-in-stock item in cart

Two users have the same last-in-stock item in their cart. The item display in the cart may show 'in stock' for both, but only one checkout should succeed.

Automation Ideas

Payment sandbox E2E matrix

Drive a table of Stripe test cards (success, decline, insufficient-funds, 3DS required) through the checkout flow, asserting the correct outcome for each. Run in CI against a staging environment with a real Stripe test-mode account.

Tools: playwright, cypress

Idempotency key assertion via network interception

Intercept the checkout POST, extract the idempotency key, send a duplicate POST with the same key, and assert only one charge appears in the gateway. Uses Playwright's route interception.

Tools: playwright

Price integrity sweep via request tampering

Use Playwright to intercept checkout requests and replace price values with $0.01. Assert the server rejects or corrects the price. Run as a security regression suite on every release.

Tools: playwright, burp-suite

Concurrent checkout race condition test

Fire two simultaneous checkout API calls for the last-in-stock item using parallel Promise.all() in Playwright. Assert inventory never goes below 0 and exactly one order succeeds.

Tools: playwright, k6

Inventory snapshot before/after checkout

Before each checkout test, snapshot inventory levels via GET /api/products. After checkout, assert each purchased item's stock decreased by exactly the purchased quantity.

Tools: playwright, cypress

Checkout accessibility audit

Run axe-core against each checkout step (cart, address, payment, confirmation). Assert zero WCAG 2.1 AA violations. Combine with a tab-order assertion.

Tools: axe-core, playwright, pa11y

Coupon expiry and reuse edge case matrix

Create a test matrix of {couponType, couponState, expectedOutcome}: valid/single-use/multi-use/expired/non-existent. Drive it through the apply-coupon endpoint and assert correct responses.

Tools: postman, playwright

Common Bugs

Order created before payment confirmed — free order exploit

When an order record is written synchronously with the checkout POST but payment confirmation arrives asynchronously (webhook), a delayed or missing webhook can leave an order in 'payment_pending' that the fulfilment system treats as paid.

Impact: Goods shipped or digital products delivered without actual payment.

Coupon discount not reflected in the charged amount

The UI shows the discounted total, but the payment request is sent with the original pre-discount amount. The gateway charges full price; the coupon is cosmetic only.

Tax recalculated after payment — total mismatch

Tax is recalculated server-side at order confirmation using a different rate than was shown at checkout (e.g. rate updated between the two steps), causing the charged amount to differ from what the customer approved.

Inventory decremented on payment failure

A failed payment still triggers inventory decrement, gradually reducing stock for orders that never completed. Hard to detect without monitoring inventory vs. order totals.

Back button after payment re-submits the form

The checkout confirmation page is not a redirect (POST response, not POST-redirect-GET), so the browser's back-then-forward navigation re-submits the payment form, triggering a duplicate charge attempt.

Guest email used to create a user account silently

Guest checkout silently creates a user account with a random password, sending the customer an unexpected account-creation email. They cannot log in but their data is now in a user record.

Shipping cost not included in payment charge

The order total displayed includes shipping, but the payment API call uses only the subtotal. The merchant absorbs shipping cost without knowing it.

Order confirmation email sent for declined payments

An async email job fires on order creation (before payment confirmation), so customers receive a 'your order is confirmed' email even for declined cards.

Currency rounding errors cause $0.01 discrepancy

Float arithmetic on subtotal + tax + shipping produces a total that is $0.01 off the expected value. Some payment gateways reject amounts that don't match their records to the cent.

Useful Tools

Playwright

End-to-end checkout flows, network interception for price tampering and idempotency tests.

Cypress

Checkout E2E with cy.intercept for network stubbing and cy.request for API payment assertions.

k6

Concurrent checkout load tests — race conditions, inventory limits under simultaneous purchases.

Postman

API-layer checkout tests: price tamper, coupon abuse, refund flows, and webhook simulation.

Burp Suite

Intercept and modify checkout requests for price tampering, coupon stacking, and parameter injection.

axe-core

WCAG 2.1 AA audit on each checkout step — labels, focus management, error announcement.

Faker.js

Generate realistic shipping addresses, names, and emails for checkout test data.

WireMock

Stub payment gateway responses to simulate declines, timeouts, and 3DS flows in isolation.

Practice this → Try it hands-on in the E-commerce Practice App.