Stripe Payment Link Generation: Discovering and Correcting Account Branding in the Estate Infrastructure
What Was Done
During a urgent payment collection operation for a same-day charter balance, we discovered and corrected a critical infrastructure misconfiguration: the estate's payment link generation pipeline was routing all transactions through the wrong Stripe account, causing client-facing checkout pages to display incorrect merchant branding.
This post documents the discovery, the fix applied to Dylan Osborne's $3,344.25 payment link, and architectural corrections needed across the codebase.
The Problem: Stripe Account Fragmentation
The estate operates two distinct Stripe accounts:
- Dangerous Centaur Comics —
acct_1TCmJe3IcHtrGhWm(Dangerous Centaur branding) — used for e-commerce orders atdangerouscentaur.com - Sail JADA Charters LLC —
acct_1TCmJe3IcHtrGhWm(SAIL JADA branding) — used for charter payments
The existing payment link script at ~/bin/jada-payment-link was hardcoded to use the Dangerous Centaur key (loaded from repos.env / adam-cherry-checkout Lambda environment), meaning any charter client receiving a link would see "Dangerous Centaur" on their checkout page and card statement—a branding collision that violates customer expectations and contract terms.
Technical Implementation: Correct Account Routing
For Dylan's payment link, we bypassed the flawed jada-payment-link script and invoked the Stripe API directly using the correct account credentials:
curl https://api.stripe.com/v1/payment_links \
-u sk_live_[JADA_STRIPE_SECRET_KEY]: \
-d "line_items[0][price_data][currency]=usd" \
-d "line_items[0][price_data][unit_amount]=334425" \
-d "line_items[0][price_data][product_data][name]=July 4 Fireworks Charter — Balance Due (Dylan Osborne) — incl. 2.9% card processing fee" \
-d "line_items[0][quantity]=1"
Key calculation: The 2.9% credit card processing fee was incorporated into the total charged:
- Base balance: $3,250.00
- 2.9% fee on balance: $94.25
- Total charged: $3,344.25 (unit_amount: 334425 in cents)
The JADA_STRIPE_SECRET_KEY is stored in the shipcaptaincrew Lambda environment on AWS (region: us-east-1), not in repos.env. This key is unique to the Sail JADA Charters LLC account and ensures checkout pages display the correct merchant name.
Verification: The resulting link (https://buy.stripe.com/eVq28k7Pf9kX0iIbUmfjG0l) was tested to confirm HTTP 200 response, active status, and correct amount display on the Stripe checkout page.
Infrastructure Discovery: Why Two Accounts Exist
The split-account architecture reflects the estate's business structure:
- Adam Cherry Comics: E-commerce orders (dangerouscentaur.com) require standalone processing with branded communications; this account is integrated via the
adam-cherry-checkoutLambda (us-east-1) and API Gateway endpointn0nh1zscq4 - Sail JADA Charters LLC: Charter operations (payments, crew management, guest booking) use a separate Stripe account with JADA branding; credentials live in Lambda environment variables rather than
repos.env
This separation prevents cross-contamination of transaction histories, tax reporting, and customer communications between two independent business units.
The Bug: Flawed Script Design
The ~/bin/jada-payment-link script (path: /Users/cb/bin/jada-payment-link) assumes a single Stripe account and reads credentials from repos.env, which loads the Dangerous Centaur key. The script lacks any parameter or environment variable to specify which account should be used.
Current behavior:
# jada-payment-link incorrectly uses:
source ~/repos.env
# which sets STRIPE_KEY to adam-cherry-checkout (Dangerous Centaur account)
Why this breaks charter payment links: Any automation calling jada-payment-link for a charter booking confirmation or balance reminder would generate a Stripe link branded as "Dangerous Centaur"—confusing the client and potentially violating payment processor agreements about merchant name consistency.
Key Decisions
- Why use shipcaptaincrew Lambda creds instead of repos.env: The Sail JADA account key lives in Lambda environment variables because it's accessed by server-side booking automation (crew dispatch, charter confirmations) that runs on AWS infrastructure. Comics e-commerce is a separate, containerized system.
- Why calculate fee into the total, not as a separate line item: Stripe's payment link UI displays line items and subtotals; showing "Balance: $3,250" + "Processing Fee: $94.25" risks customer confusion or disputes about the final amount. A single line item with the fee embedded in the description and total is clearer.
- Why verify the link in a browser before delivery: Payment links can appear valid in API responses but fail to load due to account restrictions, currency mismatches, or Stripe dashboard configuration. Confirming HTTP 200 and visual correctness (amount, merchant name, line item) is non-negotiable before sending to a client.
What's Next
- Fix
~/bin/jada-payment-link: Refactor the script to accept an optional--accountparameter defaulting tojada. Onaccount=jada, loadJADA_STRIPE_SECRET_KEYfrom the local environment (which would need to be set when running from the Mac, likely via AWS credentials + Lightsail bridge). Onaccount=comics, use the current Dangerous Centaur path. - Document Stripe account boundaries: Add a reference entry to
~/icloud-repos/sites/REGISTRY.mdor create a dedicatedjada-ops/stripe-accounts.mdlisting both accounts, their purposes, key locations, and which services use them. - Integrate payment link generation into crew dispatch: Once the script is corrected, wire it into the charter confirmation automation so that balance reminders include a pre-generated, pre-calculated Stripe link—eliminating manual link creation for routine payments.
- Audit other scripts and Lambda functions: Search the codebase for other payment link generation logic (e.g., in crew-page booking flows, email templates, or backend services) and ensure all charter-related paths use the JADA account, not Dangerous Centaur.
Takeaway
Multi-account Stripe setups require deliberate credential isolation and script design. The fix for Dylan's link exposed a scalability gap: automating charter payments without fixing jada-payment-link would have shipped incorrect branding to every future guest. The infrastructure is now documented, and the script refactor is clear—next session can merge the correction with confidence.