← back to CelebritySignatures
wear: charge apparel through live-capable Stripe resolver, not test-only key (TK-10286)
8b5b7ca0e49a24b420044ef22d274a450a46fc55 · 2026-08-31 10:50:14 -0700 · Steve Abrams
The /wear POD checkout was hardwired to STRIPE_DOWNLOAD_KEY (test-only), so
even with WEAR_SALES_LIVE=1 + STRIPE_LIVE_ENABLED=1 + a live key it would
never charge a real card. Repoint the charge + session-read + order.mode to
STRIPE_MURAL_KEY/STRIPE_MODE (the same live-only-when-fully-switched resolver
murals use). No behavior change until Steve flips STRIPE_LIVE_ENABLED — today
it still resolves to the test key.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 8b5b7ca0e49a24b420044ef22d274a450a46fc55
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 31 10:50:14 2026 -0700
wear: charge apparel through live-capable Stripe resolver, not test-only key (TK-10286)
The /wear POD checkout was hardwired to STRIPE_DOWNLOAD_KEY (test-only), so
even with WEAR_SALES_LIVE=1 + STRIPE_LIVE_ENABLED=1 + a live key it would
never charge a real card. Repoint the charge + session-read + order.mode to
STRIPE_MURAL_KEY/STRIPE_MODE (the same live-only-when-fully-switched resolver
murals use). No behavior change until Steve flips STRIPE_LIVE_ENABLED — today
it still resolves to the test key.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
server.js | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/server.js b/server.js
index 4990668..d7e5fc9 100644
--- a/server.js
+++ b/server.js
@@ -791,7 +791,11 @@ ${paid ? `<div class="ok">✓</div><h1>Order confirmed</h1>
// flips WEAR_SALES_LIVE=1 (paired with live Stripe + a wired POD). Until then, no visitor
// is sent to a test-mode checkout — they get a friendly "opening soon".
if (envVal('WEAR_SALES_LIVE') !== '1') return sendJSON(res, 200, { ok: false, comingSoon: true, error: 'Apparel sales open soon — thanks for your interest!' });
- if (!STRIPE_DOWNLOAD_KEY) return sendJSON(res, 503, { ok: false, error: 'apparel not purchasable yet (awaiting Stripe test key)' });
+ // Apparel is a physical POD sale — charge through the live-capable resolver
+ // (STRIPE_MURAL_KEY: live only when STRIPE_LIVE_ENABLED=1 AND a sk_live_ key
+ // is present, else the test key). NOT STRIPE_DOWNLOAD_KEY, which is test-only,
+ // so wear would never have charged a real card. One consistent live switch.
+ if (!STRIPE_MURAL_KEY) return sendJSON(res, 503, { ok: false, error: 'apparel not purchasable yet (awaiting Stripe key)' });
const b = await readBody(req);
const email = String(b.email || '').trim();
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) return sendJSON(res, 400, { ok: false, error: 'valid email required' });
@@ -811,7 +815,7 @@ ${paid ? `<div class="ok">✓</div><h1>Order confirmed</h1>
const order = { id, at: new Date().toISOString(), account: u ? u.email : null, email,
qid: qidOf(sig), signature_name: sig.full_name, garment: garment.id, garment_label: garment.label,
color: color.id, size, placement: tpl.placement || 'left_chest', amountUsd: amountCents / 100,
- status: 'pending_payment', mode: 'test', pod_submitted: false };
+ status: 'pending_payment', mode: STRIPE_MODE, pod_submitted: false };
list.push(order); await store('wear-orders.json', list);
const params = new URLSearchParams();
params.set('mode', 'payment');
@@ -825,12 +829,12 @@ ${paid ? `<div class="ok">✓</div><h1>Order confirmed</h1>
params.set('line_items[0][price_data][currency]', 'usd');
params.set('line_items[0][price_data][unit_amount]', String(amountCents));
params.set('line_items[0][price_data][product_data][name]', `${sig.full_name} signature — left-chest ${garment.label} (${color.label}, ${size})`);
- params.set('line_items[0][price_data][product_data][description]', `Signature printed at the left chest; made to order. TEST checkout.`);
+ params.set('line_items[0][price_data][product_data][description]', `Signature printed at the left chest; made to order.${STRIPE_MODE === 'test' ? ' TEST checkout.' : ''}`);
params.set('metadata[order_id]', String(id));
try {
const sres = await fetch('https://api.stripe.com/v1/checkout/sessions', {
method: 'POST',
- headers: { Authorization: `Bearer ${STRIPE_DOWNLOAD_KEY}`, 'Content-Type': 'application/x-www-form-urlencoded' },
+ headers: { Authorization: `Bearer ${STRIPE_MURAL_KEY}`, 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});
const sj = await sres.json();
@@ -842,9 +846,9 @@ ${paid ? `<div class="ok">✓</div><h1>Order confirmed</h1>
if (path === '/wear-success' && M === 'GET') {
const sid = url.searchParams.get('sid') || '';
let paid = false, order = null;
- if (STRIPE_DOWNLOAD_KEY && /^cs_(test|live)_[A-Za-z0-9]+$/.test(sid)) {
+ if (STRIPE_MURAL_KEY && /^cs_(test|live)_[A-Za-z0-9]+$/.test(sid)) {
try {
- const s = await (await fetch(`https://api.stripe.com/v1/checkout/sessions/${sid}`, { headers: { Authorization: `Bearer ${STRIPE_DOWNLOAD_KEY}` } })).json();
+ const s = await (await fetch(`https://api.stripe.com/v1/checkout/sessions/${sid}`, { headers: { Authorization: `Bearer ${STRIPE_MURAL_KEY}` } })).json();
if (s.payment_status === 'paid') {
paid = true;
const list = await load('wear-orders.json', []);
← 19ad3e6 Add AI-readable site guide
·
back to CelebritySignatures
·
wear: +$4 2XL size upcharge (tee $38 / polo $48) — TK-10286 b152beb →