[object Object]

← back to Dw Signup Fulfillment

retail-webhook: only set sample_verify_sent flag when the letter actually sent

43065de9b55ec28fe0ff5d60b58b5923b21756ad · 2026-08-14 10:16:26 -0700 · Steve Abrams

A failed send (missing VERIFY_SECRET / George down) was stamping the idempotency
flag anyway, permanently skipping the customer so they'd never get the welcome
email even after the fault is fixed. Now the flag is set only on started.ok.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 43065de9b55ec28fe0ff5d60b58b5923b21756ad
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Aug 14 10:16:26 2026 -0700

    retail-webhook: only set sample_verify_sent flag when the letter actually sent
    
    A failed send (missing VERIFY_SECRET / George down) was stamping the idempotency
    flag anyway, permanently skipping the customer so they'd never get the welcome
    email even after the fault is fixed. Now the flag is set only on started.ok.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 lib/retail-webhook.js | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/retail-webhook.js b/lib/retail-webhook.js
index f7f775f..9e2f40e 100644
--- a/lib/retail-webhook.js
+++ b/lib/retail-webhook.js
@@ -50,8 +50,15 @@ async function handleCustomerCreate(payload) {
   //    the real customer id baked into the token so the tag lands on the right account.
   const started = await verify.startVerification({ email: real.email, customerId: real.id, firstName: real.first_name });
 
-  // 5) FLAG in Shopify so it never double-sends (survives restarts).
-  await shopify.setCustomerMetafield(id, { ...SENT_FLAG, value: 'true', type: 'boolean' });
+  // 5) FLAG in Shopify so it never double-sends (survives restarts) — but ONLY when the
+  //    letter actually went out. A failed send (missing VERIFY_SECRET, George down, etc.)
+  //    must NOT poison the idempotency flag, or the customer is marked "handled" while
+  //    having received nothing — permanently skipped, never gets their welcome email.
+  if (started.ok) {
+    await shopify.setCustomerMetafield(id, { ...SENT_FLAG, value: 'true', type: 'boolean' });
+  } else {
+    console.warn(`[retail-webhook] verify letter NOT sent for id=${id} (${started.reason || 'unknown'}) — flag left unset so a retry/backfill can re-send.`);
+  }
 
   return { ok: started.ok, id, email: real.email, started };
 }

← f2bce23 selftest: cover Option C (verify letter, token security, tag  ·  back to Dw Signup Fulfillment  ·  honor-reissue: void+re-mint 53 orphaned free-sample cards (p bf4aa2c →