---
name: ghl-order-form-quirks
description: GHL native order form (One Step Order) limitations and wiring — products, custom fields, trials, scroll anchors, publish gotchas. Verified building the Premium Line bail funnel.
---

# GHL Order Form Quirks

Verified 2026-08-10 building the "Premium Line for Bail Bonds" funnel (go.realresultsready.com/bail-bonds-page).

## Hard limitations (native One Step Order form)
- **No custom fields.** Only built-ins: Full Name, Email, Phone, Company Name, Shipping. A Town dropdown or any custom field is IMPOSSIBLE on the order form. GHL's own AI panel cannot patch this — it's a platform limit, not a settings issue.
  - Workaround (launch): relabel built-in **Company Name** — the label + placeholder text boxes sit as rows under "Toggle Company Name"; each row's editable text box is to the RIGHT of the row label (easy to miss).
  - Workaround (proper): two-step flow — GHL native Form page (supports custom fields) → order form page.
- **Trial = X days only.** No calendar billing anchor in GHL products — cannot truthfully promise "bills on the 1st." Footer copy must read "bills after your N-day trial" (Rob approved this phrasing after pushing back on 22-days wording; he preferred 1st-of-month but accepted platform reality).

## Product wiring
- Products attach at the **funnel STEP level**: funnel step view → **Products** tab → + Add Product. There is NO Products tab in the page-builder toolbar, and "Main Product Options" in the element settings has no product picker.
- Editor canvas shows a stale placeholder ("Dynamic Item $99") even after correct wiring — verify on the LIVE page only.
- Preview link 404s until the step is **Published** (Publishing tab).

## Button scroll-to-section
- Sections don't expose a CSS ID; "Element name" is the handle. Use button → "link to → **Scroll to Element**" → pick the named section.
- Requires **republish** (Publishing tab) + hard refresh (Ctrl+Shift+R) to work live — editor saves don't push automatically.

## Rob's checkout standards
- Hide Shipping + Coupon for digital products.
- Button text first person: "Lock In My Town" (not "Your") — page copy says "your," button says "my."
- Delete false-promise defaults the AI builder inserts ("Upgrade Your Order & Save!" sub-headline, $99 Dynamic Item placeholder).
- Footer must state exact billing timing; every claim verified against what the product actually does.
- AI builder: fine for scaffolding, but audit every element after — it over-promises and can't reach product/field settings.
- Custom-field workarounds are optional at launch: if page context already implies the value (e.g. a town-specific page), Rob defers capture to onboarding rather than add checkout friction. Don't push the two-step flow when the buyer obviously knows what they're buying.

## AI builder failure modes (seen 2026-08-10)
- **It wipes sections.** A large/multi-part prompt ground the builder to a halt and deleted half the page. Use it for ONE small atomic section at a time (a footer prompt worked fine); hit Save before EVERY AI prompt so a wipe is recoverable; for edits to an existing element (restyle, rewire, settings), close the AI panel (X / Esc) and edit manually.
- **Schema validation failures on the order form.** The builder can only patch a few order-form settings directly (button text, shipping/coupon toggles, microcopy style); attempts to update non-editable fields fail with a schema error. Product selection and anything structural: always manual.
- After ANY builder run, scroll the whole page top-to-bottom and audit which sections survived before continuing — don't trust its "done" report.

## Verify from outside (no GHL login needed)
Editor canvas and preview lie (stale placeholders, 404-until-publish). Verify the LIVE page with curl:
- `curl -sL -o /dev/null -w "%{http_code}\n" <page-url>` → expect 200 for the page AND each redirect target (claimed/expiry page).
- `curl -sL <page-url> | grep -oiE "(product name|price|button text|key headline)" | sort | uniq -c` → confirms real content shipped, not the "Dynamic Item $99" placeholder.
- `curl -sL <page-url> | grep -oE 'expir[^,}]{0,200}'` → countdown expire action wired (`expireAction` present in page JSON).
- Check redirect pages' H1s: `curl -sL <redirect-url> | grep -oiE '<h[1-3][^>]*>[^<]*'`.

## Mobile Stripe embed bug (verified 2026-08-10 — cost real debugging time on walk-in day)

**Symptom:** Order form renders fine on desktop but on mobile (Chrome/Android) the Stripe card fields (card number, expiry, CVC) never render — gray placeholder boxes forever. Apple Pay / Google Pay buttons may also flash or fail.

**Root cause:** Google Pay being enabled in the Stripe payment-method config for Subscriptions breaks the entire Stripe Payment Element embed on mobile. Not a GHL page-builder issue — a Stripe wallet conflict.

**Fix (2 minutes, sub-account level):**
1. GHL sub-account → **Payments → Integrations → Stripe → Manage Options** (this opens a Stripe-style config page INSIDE GHL — it is the sub-account's Stripe settings, not agency level)
2. Switch the **product-area dropdown to "Subscriptions"** (the default view is "Invoices" — wrong place, toggling there does nothing for subscription products)
3. **Toggle Google Pay OFF.** Apple Pay can stay on (it only surfaces on Safari/iOS anyway and didn't cause the bug).
4. Save, then test on the phone in a FRESH browser (restart the phone or use a new incognito tab — the broken state caches hard; incognito on desktop may show the fix before the phone does).

**Diagnostics:**
- Desktop works + mobile gray boxes = suspect wallet conflict first, before touching form type or GHL support.
- GHL's own AI help gives generic "check Stripe connection / use Chrome" troubleshooting — it does not know about this bug. Don't waste time with it.
- Toggling Google Pay off in the Invoices product area does NOT fix subscriptions — must be the Subscriptions dropdown.

## Test purchase
- Stripe TEST mode: card `4242 4242 4242 4242`, any future exp, any CVC/ZIP. Expect: lands on the success-redirect page + trial subscription appears in GHL → Payments → Subscriptions.
- Stripe LIVE mode: 4242 is declined — use a real card, verify the sub appears, then cancel the subscription immediately.
- **Test BOTH desktop and mobile before field use.** QR-code-driven mobile checkouts are the whole point of print collateral; a desktop-only checkout discovered on walk-in day is a near-miss.
