← back to AbramsEgo
feat(sell): stripe TEST checkout + webhook (dtd: B — Checkout Sessions via /api/checkout, 2/2 Claude+Codex, Qwen timeout)
4dc12bfe8d1d0ebff867503e8e89090f5aeb46f2 · 2026-07-01 17:16:11 -0700 · Steve
Engine-1 (sell_product) money rail, TEST-mode only, keys-ready:
- POST /api/checkout — server-created Checkout Sessions, $19 hosted / $49 pro,
inline price_data (no dashboard objects needed), 503 until sk_test_ keys land
- POST /api/stripe/webhook — raw-body signature verify (before express.json +
Basic Auth; the stripe-signature IS the auth); checkout.session.completed →
data/revenue-ledger.jsonl (same shape as /api/revenue/record) + snapshot rebuild
- sk_live_ REFUSED at boot: money routes disabled + loud log (going live is Steve-gated)
- GET /api/stripe/status + landing page note: 'test keys not yet installed'
or TEST-mode checkout buttons when keys are present
- .env.example documents STRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRET (un-ignored via !.env.example)
- npm i stripe dotenv (dotenv was try-required but never installed — .env now actually loads)
Verified on the running pm2 instance: 503-graceful keyless path; sk_live_ refusal;
unsigned + bad-signature webhook posts → 400; hand-signed synthetic
checkout.session.completed → 200 → ledger row → engine live, P&L selfFundingPct
moved (2100.4%). Synthetic row + dummy keys removed after; keyless state restored.
(server.js/landing.html code itself was swept into auto-save af660fb mid-task.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Files touched
A .env.exampleM .gitignoreR100 build-queue/tasks/33-stripe-test-checkout.md build-queue/done/33-stripe-test-checkout.mdM data/local-fleet.json
Diff
commit 4dc12bfe8d1d0ebff867503e8e89090f5aeb46f2
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jul 1 17:16:11 2026 -0700
feat(sell): stripe TEST checkout + webhook (dtd: B — Checkout Sessions via /api/checkout, 2/2 Claude+Codex, Qwen timeout)
Engine-1 (sell_product) money rail, TEST-mode only, keys-ready:
- POST /api/checkout — server-created Checkout Sessions, $19 hosted / $49 pro,
inline price_data (no dashboard objects needed), 503 until sk_test_ keys land
- POST /api/stripe/webhook — raw-body signature verify (before express.json +
Basic Auth; the stripe-signature IS the auth); checkout.session.completed →
data/revenue-ledger.jsonl (same shape as /api/revenue/record) + snapshot rebuild
- sk_live_ REFUSED at boot: money routes disabled + loud log (going live is Steve-gated)
- GET /api/stripe/status + landing page note: 'test keys not yet installed'
or TEST-mode checkout buttons when keys are present
- .env.example documents STRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRET (un-ignored via !.env.example)
- npm i stripe dotenv (dotenv was try-required but never installed — .env now actually loads)
Verified on the running pm2 instance: 503-graceful keyless path; sk_live_ refusal;
unsigned + bad-signature webhook posts → 400; hand-signed synthetic
checkout.session.completed → 200 → ledger row → engine live, P&L selfFundingPct
moved (2100.4%). Synthetic row + dummy keys removed after; keyless state restored.
(server.js/landing.html code itself was swept into auto-save af660fb mid-task.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
.env.example | 23 ++++++++++++++++++++++
.gitignore | 2 ++
.../{tasks => done}/33-stripe-test-checkout.md | 0
data/local-fleet.json | 2 +-
4 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..923b793
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,23 @@
+# AbramsEgo env — copy to .env (gitignored) and fill in. Route keys via /secrets.
+
+# --- Stripe (engine 1: sell_product) — TEST MODE ONLY -----------------------
+# Must start sk_test_. If absent, /api/checkout + /api/stripe/webhook answer
+# 503 {error:"stripe not configured"} and the landing page shows a
+# "test keys not yet installed" note. A sk_live_ key is REFUSED at boot
+# (money routes disabled + loud log) — going live is Steve-gated.
+STRIPE_SECRET_KEY=sk_test_...
+# Signing secret for POST /api/stripe/webhook (from `stripe listen` or the
+# dashboard webhook endpoint config). Unsigned posts are rejected 400.
+STRIPE_WEBHOOK_SECRET=whsec_...
+
+# --- server ------------------------------------------------------------------
+# PORT=9773
+# ABRAMSEGO_USER=admin
+# ABRAMSEGO_PASS=DW2024!
+
+# --- self-funding cost knobs --------------------------------------------------
+# ENERGY_AVG_WATTS=90
+# ENERGY_RATE_USD_PER_KWH=0.30
+# ENERGY_ATTRIB_PCT=100
+# CNCP_BASE=http://127.0.0.1:3333
+# KAMATERA_HOST=45.61.58.125
diff --git a/.gitignore b/.gitignore
index fb4ee71..28b6d1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
node_modules/
.env
.env.*
+# the example env is documentation, not a secret — keep it tracked
+!.env.example
tmp/
*.log
.DS_Store
diff --git a/build-queue/tasks/33-stripe-test-checkout.md b/build-queue/done/33-stripe-test-checkout.md
similarity index 100%
rename from build-queue/tasks/33-stripe-test-checkout.md
rename to build-queue/done/33-stripe-test-checkout.md
diff --git a/data/local-fleet.json b/data/local-fleet.json
index 0759af7..e8fc9d9 100644
--- a/data/local-fleet.json
+++ b/data/local-fleet.json
@@ -1 +1 @@
-{"fetchedAt":"2026-07-02T00:07:34.797Z","procs":[{"name":"api-token-dashboard","status":"online","cpu":0,"memMB":48,"restarts":null,"uptimeMs":4212000,"startedAt":"2026-07-01T22:57:22.797Z"},{"name":"abramsego","status":"stopped","cpu":null,"memMB":null,"restarts":null,"uptimeMs":null,"startedAt":null}]}
\ No newline at end of file
+{"fetchedAt":"2026-07-02T00:16:03.667Z","procs":[{"name":"api-token-dashboard","status":"online","cpu":0,"memMB":48,"restarts":null,"uptimeMs":4721000,"startedAt":"2026-07-01T22:57:22.667Z"},{"name":"abramsego","status":"stopped","cpu":null,"memMB":null,"restarts":null,"uptimeMs":null,"startedAt":null}]}
\ No newline at end of file
← af660fb auto-save: 2026-07-01T17:07:40 (9 files) — build-queue/tasks
·
back to AbramsEgo
·
feat(sell): landing CTAs + PUBLIC_LANDING flag (default off) 7f1831f →