Test your Managed Checkout integration
Verify payments, order state, recovery, and the shopper experience in your app before launch.
Test the Managed Checkout quickstart. Copy these tables into your test report and record evidence against each result. All cases start Not run.
What this plan verifies
| Coverage | Tests | Implementation being tested |
|---|---|---|
| Quickstart outcome | Q1–Q5 | Follow the five guide checkpoints in order. Real sandbox execution required. |
| Supplied handlers | F8; F10 unhandled events; E3 script/status failure; E4 pending mount cleanup | Signature and transaction checks, non-purchase filtering, generic browser errors, and teardown. Controlled tests can verify these without making a payment. |
| Required app integration | Q2/Q5; F6–F10 storage, access, replay, and restart | Your orders adapter, session/CSRF middleware, persistence, and error handler. The guide defines their contract; it does not implement your database or concurrency controls. |
| Additional launch behavior | F1–F5; F7 concurrent ordering; E1–E8 beyond the supplied UI; L1–L4 | Safe retries, payment locking, cart changes, full confirmation/recovery UI, focus behavior, fulfillment, receipts, and enabled features. Implement these in your app before expecting those tests to pass. |
The quickstart verifies a card purchase and a persisted payment. It does not build a fulfillment system, send receipts, or implement refunds. Count those effects only when your launch includes them; record the omission otherwise. Additional launch checks remain required when applicable, but are not evidence that the minimal quickstart already supplies those features.
Setup and inputs
| Input | Value / preparation |
|---|---|
| Run details | Record build, date, tester, sandbox division, browser/device versions, and enabled features. |
| Configuration | Same division in API settings, Payments, Trusted Domains, and Webhooks. Keep the HTTPS development URL running. |
| Cart | Shopper A: one physical product, $10.00 USD, quantity one, free shipping, zero tax, no discounts. Create shopper B for access tests. |
| Evidence | App order/payment records, backend logs, sandbox Transactions, and screenshots. If enabled, send fulfillment/emails to test destinations so you can count them. |
| Harness | Ability to delay/fail your endpoints, replay signed notifications, and substitute transaction responses. Use actual sandbox payments for Q1–Q5. |
| Reset | Fresh order per independent case. Preserve order/transaction IDs during retries and recovery. Never repay just to resolve an unknown result. |
| Payment input | Card | Expiration / CVV |
|---|---|---|
| Approved | 4111 1111 1111 1111 | 03/30 / 737 |
| Processor decline | 4111 1111 1111 1012 | Future date / any three digits |
| Pre-auth rejection | 4100 2003 0003 0001 | Future date / any three digits |
| Review / later rejection | Use the Bolt Payments test-card set for your onboarding date. | As listed in the reference |
1. Quickstart checkpoints
Run Q1–Q5 in order in the real sandbox. Keep the same order through Q2–Q5.
| Test | Input | Steps | Expected output | Result |
|---|---|---|---|---|
| Q1 · Set up | Sandbox credentials; USD; Immediate Capture | 1. Reopen Payments/API settings. 2. Inspect browser content. | Same division throughout; capture setting and development Trusted Domain saved; no private keys or signing secret in the browser. | Not run |
| Q2 · Connect orders | Shopper A’s $10 cart; shopper B | 1. Request a token twice as A. 2. Retrieve A’s order as A, then B. | Token returned; one unpaid order at 1000 USD; B cannot read it. | Not run |
| Q3 · Add checkout | A’s saved cart | 1. Open the cart. 2. Inspect scripts and status without opening checkout. | One button; both sandbox scripts loaded; correct order ID shown; no blocking browser error. | Not run |
| Q4 · Connect Bolt | Unsigned requests; US shipping address | 1. POST unsigned bodies to both receivers. 2. Open checkout; verify product/quantity/$10 total. 3. Enter a US address. | Unsigned requests: 401. Signed shipping/tax callbacks: 200. Checkout: free shipping, zero tax. | Not run |
| Q5 · Verify payment | Approved card; original order ID | 1. Pay. 2. Match app and dashboard records. 3. Restart and retrieve order. | Successful order callback; verified transaction; persisted completed payment; matching order/reference and $10 amount. | Not run |
2. Payment failures and retries
Use a fresh order per case. Within each retry scenario, retain the original order and check for duplicate charges.
| Test | Input | Steps | Expected output | Result |
|---|---|---|---|---|
| F1 · Decline | Decline card, then approved card | 1. Submit decline. 2. Retry through the app. | Decline: unpaid, cart preserved. Retry: one completed purchase, one fulfillment/notification if those features are enabled. | Not run |
| F2 · Rejection | Pre-auth rejection card | 1. Submit payment. 2. Check app and order. | Unpaid; no fulfillment or success message; no internal fraud-rule details exposed. | Not run |
| F3 · Close checkout | Unpaid checkout; submitted payment awaiting confirmation | 1. Close before payment and reopen. 2. Repeat after payment submission. | Cart survives. After submission, app checks original payment state before allowing another attempt. | Not run |
| F4 · Repeated actions | One checkout snapshot; two tabs | 1. Double-click checkout. 2. Reload/open a second tab. 3. Retry after a timeout. | No overlapping payment attempts; at most one successful charge, paid order, and fulfillment for the purchase. | Not run |
| F5 · Cart changes | Checkout open in one tab | 1. Change quantity, item, or price in another tab. 2. Resume checkout. | App locks or refreshes the cart visibly. No silent stale charge; new snapshot/token for a changed cart. | Not run |
3. Payment delivery and order integrity
Use your development harness for fault injection. Label manual replays and mocked responses in the evidence.
| Test | Input | Steps | Expected output | Result |
|---|---|---|---|---|
| F6 · Delayed confirmation | Receiver returns 503; separate transaction-lookup failure | 1. Complete payment. 2. Restore receiver and replay. 3. Repeat with lookup failure. | Before verification: pending, no second payment. Failure: non-2xx. Recovery: original order completes once. | Not run |
| F7 · Duplicate / old events | Captured signed notifications | 1. Replay twice. 2. Replay concurrently. 3. Deliver an older event last. | Authoritative state retained; no regression, duplicate order, fulfillment, or success notification. | Not run |
| F8 · Invalid confirmation | Bad signature; unknown order; wrong amount/currency/reference; cc_credit; browser success only | 1. Submit each invalid fixture. 2. Inspect stored payment and logs. 3. Send a valid shipping callback with only the pending rotation signature, then with valid primary and invalid pending signatures. | Either matching signature accepts the callback; two invalid signatures return 401. Invalid confirmation cannot mark paid. cc_credit is acknowledged without replacing the sale. Failed processing is observable; browser success alone cannot confirm payment. | Not run |
| F9 · Access / price | A/B sessions; missing authentication/CSRF; modified browser prices | 1. Request another shopper’s order. 2. Submit unauthorized or altered requests. | No leaked order details or unauthorized order creation. Server owns cart prices and shopper identity. | Not run |
| F10 · Persistence / other events | Completed order; unrelated signed event | 1. Restart backend. 2. Replay payment. 3. Send an unhandled object type. | Payment persists; no duplicate effects. Deliberately unhandled event gets 2xx without changing payment state. | Not run |
4. Merchant-controlled experience
Run on supported desktop browsers and a real mobile device. Include keyboard/screen-reader use and supported in-app browsers. Test merchant-owned screens and transitions; report Bolt-hosted UI defects to Bolt.
| Test | Input | Steps | Expected output | Result |
|---|---|---|---|---|
| E1 · Clear purchase | Cart, checkout, confirmation | 1. Compare item, quantity, currency, and total. 2. Inspect checkout action. | Values agree; shipping/tax assumptions visible; clearly labeled action, unobscured by merchant overlays. | Not run |
| E2 · Loading | Slow network; own endpoints delayed 10 seconds | 1. Delay token creation. 2. Delay payment status. | Visible progress; no duplicate submission; cart preserved. Pending confirmation has a safe next step, not endless spinning. | Not run |
| E3 · Errors | Blocked Bolt script; token failure; offline status request | 1. Trigger each failure. 2. Follow recovery action. | Readable message; no stack traces/secrets. Safe retry, or check existing order when payment is uncertain. | Not run |
| E4 · Navigation | Open checkout; mobile browser | 1. Navigate away during delayed token/script loading. 2. Remount the cart. 3. Close/reopen and resume on mobile. | No late checkout mount after unmount; no duplicate scripts after remount. Merchant navigation restores cart, controls, and focus without another payment. | Not run |
| E5 · Accessibility | Keyboard and screen reader | 1. Reach/open/close checkout. 2. Observe app status and errors. | Named controls; visible focus; useful return focus; status announced without repeated interruptions; color is not the only cue. | Not run |
| E6 · Mobile layout | Narrow screen; 200% zoom; on-screen keyboard | 1. Rotate, zoom, and open keyboard. 2. Complete merchant-owned screens. | Totals, actions, and errors remain readable/reachable; no obstructing overlays or horizontal scrolling hiding actions. | Not run |
| E7 · Confirmation | Completed order; receipt enabled if offered | 1. Refresh confirmation. 2. Open order/help links. 3. Count receipts. | Persisted, correct order result; clear next step and support route; one receipt matching the order; pending is not complete. | Not run |
| E8 · Session expiry | Shopper session expires | 1. Expire before checkout. 2. Repeat during confirmation. 3. Sign in again. | Clear sign-in; original order recoverable; no cross-shopper disclosure or second payment. | Not run |
5. Launch features
Run after replacing quickstart fixtures with real behavior. Use Not applicable only for features outside your launch, with a reason.
| Test | Input | Steps | Expected output | Result |
|---|---|---|---|---|
| L1 · Real totals | Offered shipping, tax, quantities, discounts, currencies; unavailable item | 1. Test each supported combination. 2. Attempt unavailable combinations. | App/Bolt totals agree; unsupported purchases blocked with a useful recovery action. | Not run |
| L2 · Review / rejection | Account-appropriate review/rejection cards | 1. Pay. 2. Observe initial and later states. | Order/fulfillment follow payment and risk policy. Review is not final success; rejection does not trigger fulfillment. | Not run |
| L3 · Post-purchase | Supported refund, void/cancellation, later payment changes | 1. Perform each supported operation. 2. Reconcile records and messages. | Amounts/references, inventory, order state, and messages agree. Refund tracked separately; never mistaken for a new sale. | Not run |
| L4 · Entry points | Each supported cart/product/app entry | 1. Run purchase and recovery cases from each entry point. | Same verified order outcome and merchant-experience checks pass; exclusions recorded. | Not run |
Results and completion
For each result, attach the actual outcome, order/transaction IDs, and redacted evidence. Record an issue, owner, and retest for failures. Duplicate rows for required browser/device runs.
| Result | Meaning |
|---|---|
| Pass | Expected output observed; evidence attached. Label sandbox, mocked, and replayed evidence. |
| Fail | Output differs; issue and owner recorded. Merchant-experience failures count even if payment succeeds. |
| Blocked | Missing access, configuration, or fixtures. Prevents sign-off when required. |
| Not run | Outstanding. Prevents sign-off when required. |
| Not applicable | Feature outside launch scope; reason recorded. |
| Gate | Required output |
|---|---|
| Quickstart verified | Q1–Q5 pass in the real sandbox, including the required app adapter. Fixed shipping/tax fixtures remain unsuitable for production. |
| Test plan complete | All Q, F, E, and applicable L cases pass. No required Blocked/Not run cases. Technical and merchant-experience owners review evidence and retest fixes. |
| Production review | Test plan complete plus production readiness. Sandbox tests do not establish live processing or settlement. |
Test notes
| Topic | Rule |
|---|---|
| Callback failure | Generic custom-cart callback errors may not stop payment. Use the documented deliberate-decline envelope and verify the actual payment outcome. |
| Replay | Use the helper below for F6/F7/F10. Inspect stored state and downstream counts, not just HTTP responses. Record manual replay separately from actual Bolt retry; no retry schedule is assumed. |
| Timing | E2's 10-second delay is a test input, not a Bolt response-time promise. |
| Test cards | If the intended payment state is not triggered, record Blocked or Fail and investigate; do not mark Pass. |
| Evidence | Never include credentials or shopper personal data. This page is an unexecuted plan, not a passed-test report. |
| Retest | Rerun affected cases after cart, checkout, payment-handler, or shopper-journey changes. |
Replay a sandbox notification
For F6, F7, and F10, capture a notification received for your own sandbox transaction as sandbox-notification.json. Keep its original transaction reference. Load your sandbox signing secret into the server environment and run this helper against your development receiver:
import { readFileSync } from 'node:fs';
import { createHmac } from 'node:crypto';
const [endpoint, file] = process.argv.slice(2);
if (!endpoint || !file || !process.env.BOLT_SIGNING_SECRET) {
throw new Error('Provide a development endpoint, payload file, and sandbox signing secret');
}
const body = readFileSync(file);
const signature = createHmac('sha256', process.env.BOLT_SIGNING_SECRET)
.update(body).digest('base64');
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Bolt-Hmac-Sha256': signature },
body,
});
console.log(`Receiver returned HTTP ${response.status}`);
if (!response.ok) process.exitCode = 1;node replay-webhook.mjs https://your-development-host.example/bolt/webhooks sandbox-notification.jsonFor the concurrent case, start two instances against the same endpoint and payload. For the older-event case, retain an earlier payload and replay it after a newer state is confirmed. A 200 response alone is not a pass: inspect the stored order, transaction reference, fulfillment count, and notification count.