AstroBaaS

Checkout & payments

Payment gateway sandbox round-trip verification

Free — GPL coresize Mplanned, not built

Generated from docs/plan/core/payment-gateway-sandbox-round-trip-verification/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Payment integrations (Stripe, PayPal, Klarna) are theoretically correct but never verified against real gateways. This core work adds round-trip sandbox tests confirming session creation, webhook handling, and state transitions work end-to-end.

The problem

Payment integrations are implemented correctly by design, but we’ve never actually run a transaction against Stripe, PayPal, and Klarna in their sandboxes. A missed detail (wrong timestamp format, forgotten signature validation) might silently break in production.

What it does

  • Stripe sandbox round-trip: create order, POST /api/payments/start, get redirect URL, simulate Stripe webhook, confirm order becomes ‘paid’
  • PayPal sandbox round-trip: same flow, confirm PayPal session creation and webhook state changes work
  • Klarna sandbox round-trip: same flow, confirm Klarna authorization and capture sequence works
  • Idempotency: replay each webhook, confirm state does not change (no double-charge)
  • Error cases: webhook with wrong signature, wrong amount, out-of-order events — confirm all are handled safely
  • Test data retention: keep test orders in a ‘sandbox-test’ category so they don’t pollute reports

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Live production testing — that’s certification (production-payment-gateway-certification).
  • Automated CI/CD integration — tests run manually before each release (can be automated later).

Data model

No new schema. Test orders have a flag/category for identification: sandbox_test=true or similar.

API

  • POST /api/tests/payment-gateway/{provider} — run round-trip test against provider’s sandbox, return results

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Test panel under Payments; buttons for ‘Test Stripe’, ‘Test PayPal’, ‘Test Klarna’. Results show pass/fail for each step (session creation, webhook delivery, state transition). Log is accessible for debugging.

The seam — why this is core

Core owns the test harness and validation logic. Providers’ sandboxes are external (third-party). Tests are part of the smoke-test suite.

Payment correctness is non-negotiable. Unverified integrations are a trust issue.

Dependencies

  • adyen-payment-gateway, bnpl, apple-pay-google-pay-setup, paypal-suite-expansion — each provider can be tested

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Run ‘Test Stripe’: creates order, calls Stripe API, receives session URL, simulates charge.succeeded webhook, order becomes ‘paid’ ✓
  • Run ‘Test PayPal’: same flow ✓
  • Run ‘Test Klarna’: same flow ✓
  • Replay webhook: same event id sent twice; order state unchanged on second delivery ✓
  • Wrong signature: webhook rejected with 401 ✓
  • Wrong amount: webhook rejected as suspicious, audit-logged ✓
  • Test orders marked ‘sandbox_test’; don’t appear in production reports or inventory calculations

Risks

False sense of correctness: passing sandbox tests doesn’t mean production is safe. A detail unique to production (certificate expiry, webhook rate limiting, DNS issues) could still break. Sandbox mirrors production but is not identical. Test flakiness: if sandbox is slow or has outages, tests fail intermittently, crying wolf. Tests should have generous timeouts and clear failure messages. Credential rotation: test sandbox credentials must be rotated regularly; a leaked sandbox credential is less severe than production, but still a risk.

Commercial context

Suggested priceCore
Rival anchorMagento: PayPal and Braintree sandbox-verified in production for a decade.

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.