Coneflower Creamery - Stripe/Gravity Forms Investigation Summary
Date: December 5, 2025 Client: Coneflower Creamery Site: https://coneflowercreamery.com Local Dev: https://conefower-creamery.local
THE PROBLEM
Client reported orders showing as "Processing" instead of "Paid" in Gravity Forms during a big sale. Some orders appeared to be failing silently.
ROOT CAUSE IDENTIFIED
1. Disabled Webhook
The main Stripe webhook endpoint (https://coneflowercreamery.com/?callback=gravityformsstripe) was DISABLED in Stripe. Form-specific webhooks existed for Forms 3, 4, and 5, but NOT for Form 6 (Pie Pre-Orders).
2. Gravity Forms Stripe 6.0 Changes
GF Stripe 6.0 (November 2025) changed the payment flow: - Old: Form submits → Payment processes → Done immediately → Webhook updates in background - New: Form submits → Payment processes → Waits for webhook (20 sec timeout) → Then completes
Without the webhook, Form 6 hung waiting for confirmation that never came.
3. Legacy Code Removal
Client had recently removed "legacy code" (switched from old Credit Card field to Stripe Card Element), which activated the new 6.0 flow and exposed the webhook issue.
IMPACT
Ghost Payments (Type B)
- 33 payments where customers entered their card but form never completed
- $3,249.86 in potentially lost revenue
- No GF entry created, no email captured in metadata
- Customers gave up when form hung
Abandoned Checkouts (Type A)
- Customers who started form but never entered card
- These have GF entries with email addresses
- Normal customer behavior, not a bug
FIXES IMPLEMENTED
1. Enabled Main Webhook (Production - Stripe Dashboard)
- Enabled
https://coneflowercreamery.com/?callback=gravityformsstripe - Updated signing secret in GF settings
- Status: DONE - Dec 5, 2025 ~5:00 PM
2. Increased Webhook Timeout (Local - needs deployment)
File: functions/gravity-forms-stripe-customizations.php
add_filter('gform_stripe_submission_timeout_seconds', 'coneflower_stripe_webhook_timeout', 10, 2);
function coneflower_stripe_webhook_timeout($timeout, $form) {
return 45; // Increased from 20 seconds
}
3. Added Metadata Capture Filter (Local - needs deployment)
Ensures Email, Customer Name, and Phone are always captured in Stripe metadata, even if form fails.
add_filter('gform_stripe_payment_intent_pre_create', 'coneflower_ensure_email_in_metadata', 10, 5);
4. Processing Orders Alert (Local - needs deployment)
File: functions/admin-custom-orders.php
- Added yellow warning banner showing "Processing" orders
- Displays on Cake/Pie Orders admin pages
- Direct links to view entries in GF
FILES CHANGED (Local Theme)
| File | Change |
|---|---|
functions/gravity-forms-stripe-customizations.php |
NEW - Timeout filter + metadata capture |
functions/admin-custom-orders.php |
Added Processing orders alert |
functions.php |
Added require for new customizations file |
docs/custom-orders-system.md |
Updated documentation |
Git Branch: feature/stripe-webhook-timeout-fix
STRIPE API ACCESS
Restricted API Key: rk_live_51GSoYLDXyxZMtNxq...
- Read-only access to Payment Intents, Charges, Events, Webhook Endpoints
- Cannot read Payment Methods (customer billing details)
Webhook Endpoints:
| URL | Status |
|-----|--------|
| ?callback=gravityformsstripe (main) | ENABLED (was disabled) |
| ?callback=gravityformsstripe&fid=5 | Active |
| ?callback=gravityformsstripe&fid=4 | Active |
| ?callback=gravityformsstripe&fid=3 | Active |
DATABASE ACCESS
MySQL Socket: /Users/edowns/Library/Application Support/Local/run/F-ZotZuZS/mysql/mysqld.sock
Table Prefix: wp_51lvh6p4st_
GF Entry Tables: wp_51lvh6p4st_gf_entry, wp_51lvh6p4st_gf_entry_meta
CUSTOMER RECOVERY
Ghost Payments - Matched to Emails
Cross-referenced ghost payment names with 5,251 GF customers:
| Customer | Amount | |
|---|---|---|
| Maureen Kaufman | $93.79 | maureen.kaufman@gmail.com |
| Ashley Stinebaugh | $204.42 | anstinebaugh@gmail.com |
| Mia Lincoln | $46.89 | 98nielsenmia@gmail.com |
| Laura Mullen | $187.58 | lauraamullen@gmail.com |
| Charles Krolikowski | $98.79 | chkrolikowski@gmail.com |
| Catie Miltenberger | $232.18 | catiemiltenberger@gmail.com |
| Peter Haug | $82.57 | phaug6512@gmail.com |
| David McCon | $54.89 | davidmccon4@gmail.com |
| Teresa Stowe | $95.78 | teresastowe@hotmail.com |
| Melissa Allison | $238.94 | mheinert684@gmail.com |
| Mary Garcia | $47.89 | marycmerle@aol.com |
| Claire Finken | $187.58 | Finkenclaire@gmail.com |
| Ryan Overfield | $140.68 | overfield23@hotmail.com |
| Lena Munger | $129.47 | lenajmunger@gmail.com |
Processing Orders - Already Have Emails
12+ customers in GF with "Processing" status who can be contacted directly.
Full recovery list: ghost-payment-recovery-list.md
UNDERSTANDING PAYMENT STATUSES
In Gravity Forms
| Status | Meaning |
|---|---|
| Paid | Payment succeeded, webhook confirmed |
| Processing | Entry created, payment not confirmed (abandoned or webhook issue) |
| Failed | Card declined or payment explicitly failed |
In Stripe
| Status | Meaning |
|---|---|
| succeeded | Payment completed |
| requires_payment_method | Customer never entered card (abandoned) |
| requires_confirmation | Card entered but payment never confirmed (ghost) |
Two Types of Incomplete Payments
- Type A (Has Entry ID): Customer abandoned before entering card. Has GF entry with email.
- Type B (Ghost - No Entry ID): Customer entered card but form hung. No GF entry, no email captured.
KEY LEARNINGS
-
GF Stripe 6.0 is a breaking change - The new webhook-dependent flow exposes any webhook configuration issues that were previously invisible.
-
One webhook can handle all forms - Don't need form-specific webhooks (
&fid=X). The main endpoint handles routing. -
Metadata capture is critical - Without email in Stripe metadata, ghost payments are unrecoverable. Added filter to always capture contact info.
-
"Processing" doesn't mean processing - In GF 6.0, it means "waiting for confirmation that may never come" - essentially abandoned.
ACTION ITEMS
Completed
- [x] Identified root cause (disabled webhook)
- [x] Enabled main webhook in Stripe
- [x] Updated signing secret in GF
- [x] Verified webhook is working (entries 12085+ showing Paid)
- [x] Created timeout filter (local)
- [x] Created metadata capture filter (local)
- [x] Created Processing orders alert (local)
- [x] Built customer recovery list
To Deploy
- [ ] Push theme changes to production
- [ ] Test payment flow after deployment
Client Follow-up
- [ ] Send recovery emails to ghost payment customers
- [ ] Monitor for new Processing/ghost payments
- [ ] Update client email with findings (saved to Desktop)
FILES IN THIS INVESTIGATION FOLDER
| File | Purpose |
|---|---|
investigation-notes.md |
Detailed technical notes |
customer-recovery-report.md |
Initial recovery list |
ghost-payment-recovery-list.md |
Comprehensive matched customer list |
CONVERSATION-SUMMARY.md |
This file - full conversation takeaways |
analyze_stripe.py |
Python script for Stripe analysis |
cross_reference.py |
Python script for customer matching |
USEFUL COMMANDS
Check Stripe Webhooks
curl -s https://api.stripe.com/v1/webhook_endpoints -u "API_KEY:"
Look Up Payment Intent
curl -s https://api.stripe.com/v1/payment_intents/pi_XXXXX -u "API_KEY:"
Query GF Entries
"/Applications/Local.app/Contents/Resources/extraResources/lightning-services/mysql-8.0.35+4/bin/darwin-arm64/bin/mysql" -u root -proot --socket="/Users/edowns/Library/Application Support/Local/run/F-ZotZuZS/mysql/mysqld.sock" local -e "SELECT * FROM wp_51lvh6p4st_gf_entry WHERE form_id = 6 ORDER BY id DESC LIMIT 25;"
REFERENCES
Summary generated December 5, 2025 by Claude Code