E-commerce QA
Checkout flows, inventory sync, payment gateways, and promotion logic for online retail.
// OVERVIEW
E-commerce platforms fail at the intersection of money, real-time inventory, and promotion logic. The most damaging bugs are invisible until a customer is charged twice, sold an item that is no longer in stock, or left stranded mid-checkout by a gateway timeout.
// What makes E-commerce QA different
- Checkout is a multi-step pipeline — cart state can diverge from checkout state mid-flow due to price changes or session expiry
- Inventory is shared across concurrent sessions: the last unit of a product can be sold to two buyers simultaneously if writes are not serialised
- Promotions interact multiplicatively — applying coupon A and coupon B together can reduce an order total below zero
- Payment gateways are external and asynchronous: authorisation, capture, and webhook confirmation are three separate events, each of which can fail independently
- Guest checkout paths diverge from authenticated paths and carry their own separate bug sets
// Core user journeys
| Journey | What to cover |
|---|---|
| Guest checkout | Product search → add to cart → checkout → payment → order confirmation and email |
| Coupon/promo application | Code entry, discount calculation, cart total update, invalid/expired code handling |
| Last-unit concurrent purchase | Two sessions add the same low-stock item to cart and proceed to checkout simultaneously |
| Refund / return | Full and partial refund from admin panel, return label generation, order status update |
| Authenticated checkout | Saved addresses, stored payment methods, order history, loyalty points application |
// RISKS & TEST AREAS
// Main risk areas
| Risk | Why it matters |
|---|---|
| Inventory oversell | Concurrent add-to-cart sessions on a low-stock item can both succeed, creating confirmed orders for stock that does not exist |
| Coupon stacking to zero | Applying multiple valid promotion codes simultaneously can reduce an order total below cost or to $0.00, accepted without error |
| Cart-to-checkout price drift | A price change applied after add-to-cart but before checkout confirm creates a mismatch between the price the customer saw and the amount they are charged |
| Gateway partial failure | The payment provider confirms authorisation but the webhook is dropped — the order is neither confirmed nor failed, leaving the customer and inventory in an unknown state |
| Refund / order-status desync | A refund is issued at the provider level but the webhook is not processed, so the order status stays 'shipped' and no customer refund email is sent |
// Functional areas to test
- Cart and session management: add, update, remove, session expiry, cart merge on login
- Checkout funnel: address entry, shipping selection, payment, review, confirm
- Coupon and promotion engine: single-code, multi-code, percentage, fixed-amount, free-shipping
- Payment and gateway integration: authorisation, capture, decline, timeout, 3DS challenge
- Order management and fulfilment: status transitions, split fulfilment, tracking updates
- Returns and refunds: full refund, partial refund, return label generation, restocking
// API & integration areas
- Payment gateway webhooks: success, failure, and chargeback — assert each triggers the correct order status transition
- Inventory sync API: assert stock level updates propagate before the next available-to-purchase check
- Shipping carrier rate API: assert fallback behaviour when the carrier is unavailable and that rates match the checkout display
- Coupon validation endpoint: assert expired, invalid, and already-used codes each return a distinct error code
- Order status callbacks: assert fulfilment partner status updates are reflected in customer-facing order history
// Data testing
- Seed products with a stock count of 1 for race-condition tests — never run concurrent tests against live inventory
- Use sandbox payment methods only; never run checkout tests against a live payment gateway
- Seed a matrix of coupon codes: expired, single-use already redeemed, valid percentage, valid fixed-amount, and multi-code combinations
- Seed multi-currency test data if the platform supports international checkout
// CROSS-CUTTING CONCERNS
// Security & privacy
- PCI scope: card numbers and CVVs must never appear in application logs, error messages, or analytics payloads
- Coupon code brute-force rate limit: assert the validation endpoint rejects rapid sequential guesses with 429
- Guest order token entropy: order lookup tokens must have sufficient entropy to prevent enumeration attacks
- Price manipulation via request tampering: assert the server recalculates the order total server-side and ignores any client-submitted price field
// Accessibility
- WCAG AA contrast and keyboard navigation through all checkout funnel steps
- Error-state focus management: validation errors on address and payment forms must move focus to the first error field
- Screen reader on dynamic cart total updates: assert the updated total is announced to assistive technology, not silently replaced
// Performance
- Concurrent add-to-cart on a 1-unit product: assert the inventory lock holds correctly under parallel requests
- Checkout page load and payment submission under peak load — simulate flash sale or seasonal traffic patterns
- Payment gateway timeout handling: assert the UI shows a clear pending state and does not strand the user on a blank page
// Mobile & responsive
- Mobile checkout at 375 px: tap targets meet WCAG minimum size, payment form fields are usable, address autocomplete works
- Mobile wallet payment flows (Apple Pay, Google Pay): assert the payment sheet renders and the flow completes end-to-end
// BUGS & SCENARIOS
// Common bugs
| Bug | Scenario / repro |
|---|---|
| Inventory oversell | Two browser sessions add the last unit to cart and both reach payment; both orders are confirmed and both receive fulfilment emails — stock goes negative |
| Coupon stack to zero | User applies a 10%-off code followed by a free-shipping code to a $5.00 order; the combined discount reduces the total to $0.00 and the order is accepted without payment |
| Cart-checkout price drift | Item added to cart at $50.00; admin changes price to $40.00; customer proceeds without refreshing and is charged the stale $50.00 price at checkout |
| Ghost order on gateway timeout | Payment submit request times out at the network layer; an order row is created in the database but the payment is neither confirmed nor failed — the customer sees an error but the order exists |
| Refund-status desync | Refund issued via the admin panel; the provider processes it but the inbound webhook is not delivered; order status stays 'shipped' and no refund confirmation email is sent |
// Example test scenarios
- 01Open two browser sessions simultaneously; add the last unit of a product in both; complete checkout in both — assert exactly one order is confirmed and the other receives an out-of-stock error
- 02Apply coupon A (10% off) then coupon B (free shipping) to a $5.00 order — assert the cart total is $4.50, not $0.00, and that no further discount can be applied below a defined floor
- 03Add an item to cart at its current price; update the price via the admin panel; proceed to checkout without refreshing — assert the checkout page reflects the updated price before payment is taken
- 04Submit payment and simulate a gateway timeout by blocking the webhook endpoint — assert no order is created in the confirmed state, inventory is not decremented, and the user sees a clear retry message
- 05Issue a full refund via the admin panel — assert the order status changes to 'refunded', the inventory count increments, and the customer receives a refund confirmation email within the defined window
// Edge cases
- Split fulfilment: order contains items from two warehouses; only one tracking number is added — assert both shipments are reflected correctly in the customer's order history
- Stale cart reopened: a cart saved 7 days ago contains an item now out of stock — assert the customer sees a clear out-of-stock message when they return to checkout, not a silent removal
- Orphaned coupon: coupon applied, then the discounted item is removed from the cart — assert the coupon is cleared and not silently applied to the remaining items
- Zero-price item: a free promotional item (price $0.00) alongside paid items — assert it does not trigger a gateway error or create a $0.00 charge request
- Guest-to-account conversion: guest completes an order, then registers with the same email address — assert the order is associated with the new account and appears in order history
// AUTOMATION & TOOLS
// What to automate
- Concurrent last-unit test: fire two simultaneous requests to add and purchase the same 1-stock product; assert exactly one succeeds and one returns a stock-unavailable error
- Coupon matrix: data-driven parametrised tests across all active coupon combinations, asserting correct cart totals and no below-zero outcomes
- Playwright E2E checkout: guest path and authenticated path, both completing with a real sandbox payment method, run on every deployment
- Gateway failure simulation: use WireMock or a mocked gateway stub returning timeout and 500, asserting no confirmed order is created and the correct error is surfaced to the user
// Useful tools
PlaywrightE2E checkout flows for guest and authenticated pathsCypressComponent and integration tests for cart and coupon UIPostmanPayment webhook simulation and order API collectionsBoundary value generatorGenerate min/max order totals and coupon discount boundary valuesPairwise test case generatorCoupon combination coverage without exhaustive enumerationHow to test: checkoutStructured checkout test guide with scenario coverage
// SHIP & LEARN
// Release readiness checklist
- Inventory race-condition suite is green — concurrent last-unit test passes consistently across runs
- Coupon stacking matrix tested — no below-zero or free-item exploit confirmed across all active code combinations
- Guest and authenticated checkout E2E both passing in CI with sandbox payment method
- Gateway timeout scenario handled — no ghost orders, correct error message surfaced to user
- Refund flow verified — order status, inventory count, and customer email all update correctly
- Mobile checkout validated at 375 px viewport with real device or accurate emulation
- Price-drift scenario covered — checkout reflects server-recalculated price, not stale cart price