One-time setup fee: test-mode dry run

2026-10-09 · Stripe TEST mode (Sandbox) · stage TEST company on propflow-stage · code at origin/main after #18153, #18158, #18197 and #18200

Result

PathResult
Card 4242: pay, webhook, row turns greenPASS
ACH: clearing, async success, row turns greenPASS
ACH: async failure, row says try again, retry opens a new pagePASS
One open page per company (repeat clicks reused one session)PASS

No bugs found. Two things to decide before going live:

The two decisions
  • Which payment methods the live page offers. The page doesn't name its methods, so it shows whatever the Stripe account has switched on. In test mode that was Card, US bank account, Cash App Pay, Klarna, plus Apple Pay, Link and Amazon Pay. For a $4,000 business setup fee you probably want only card and bank. That's a setting on the live account's payment method configuration, or a one-line code change to name the methods.
  • Where the customer lands after paying. The success URL is /settings?billing=success, not the onboarding Billing page they came from.
Screenshots for each path, how it was run, and the cleanup

Before: the step on the onboarding Billing page

The stage TEST company (Fairhaven Residential (TEST), propflow-stage) has a $4,000 one-time setup fee set through the staff route. The card names the fee and offers the Stripe page. There's no per-unit monthly price.

Onboarding › Billing, before paying
Onboarding › Billing, before paying

Path 1: card (4242). PASS

  • Clicking the button opened the Stripe-hosted page in TEST mode (cs_test_…, Sandbox): Setup and Customization (test), $4,000.00.
  • Paid with 4242 and got back to Propflow.
  • The webhook (checkout.session.completed) re-read the session and stored billingSetup.setupFeeStatus = paid.
  • The saved card became the customer's default payment method.
  • The checklist row turned green: Set up billing, Complete. Setup fee paid. Your plan starts when you go live.
  • Staff see Subscription pending: starts at go-live.
Stripe-hosted page, test card entered
Stripe-hosted page, test card entered
Billing card after paying
Billing card after paying
Overview: Set up billing is Complete
Overview: Set up billing is Complete

Path 2: US bank account (ACH), async success. PASS

  • Entered a test bank account (manual entry, microdeposits).
  • On return the row stayed open and said the payment was clearing (processing).
  • After the test microdeposits were verified, Stripe sent checkout.session.async_payment_succeeded. The record moved to paid, the bank account became the default, and the row turned green.
Bank account linked on the Stripe page
Bank account linked on the Stripe page
While the bank payment clears
While the bank payment clears
Overview after the async success
Overview after the async success

Path 3: ACH, async failure. PASS

  • Used a test account that fails after processing. Stripe sent checkout.session.async_payment_failed and the record moved to failed.
  • The row says the last payment did not go through, and the card offers the button again.
  • A retry opened a new page on the same customer: the failed one is treated as spent.
After a failed bank payment: try again
After a failed bank payment: try again

How it was run, and the cleanup

  • A local dev server with STRIPE_SECRET_KEY set to the test key, confirmed sk_test_ in the server's environment and by cs_test_ session ids. The live key was never loaded.
  • The test key was pulled from Vercel (Development) to a lane file and deleted afterwards. A test-mode product was created ("Setup and Customization (test)"). stripe listen forwarded the test webhooks with its own signing secret.
  • US bank account was switched on in the test-mode payment method configuration only, because it was off. Live settings were not touched.
  • Cleanup, read back from propflow-stage: billingPlan, billingSetup and billingSetupCheckout are all gone from the stage TEST company, and it carries no Stripe customer id (linked: false). The open test session was expired, and the server and the listener were stopped.
PropFlow Docs