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
| Path | Result |
|---|---|
| Card 4242: pay, webhook, row turns green | PASS |
| ACH: clearing, async success, row turns green | PASS |
| ACH: async failure, row says try again, retry opens a new page | PASS |
| 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.
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 storedbillingSetup.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.
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 topaid, the bank account became the default, and the row turned green.
Path 3: ACH, async failure. PASS
- Used a test account that fails after processing. Stripe sent
checkout.session.async_payment_failedand the record moved tofailed. - 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.
How it was run, and the cleanup
- A local dev server with
STRIPE_SECRET_KEYset to the test key, confirmedsk_test_in the server's environment and bycs_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 listenforwarded 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.