ABKC Single-Owner Dog Registration Payment — End-to-End Walkthrough (V2, 2026-06-09)
Status: BENCHMARK — Canonical reference for ABKC payment-verification walkthroughs. V2 supersedes V1 (2026-05-28); V1 files preserved unchanged per
~/.claude/rules/archive-policy.md. The procedure (3 gates, $62.00 sandbox flow) is UNCHANGED — V2 refreshes surrounding state only (see the Status delta block below §0).
Audience standard (added 2026-06-09, Dane-approved): the V1 panel plus QA/test engineering · payments/PCI-DSS · privacy/COPPA+PII · accessibility/WCAG 2.2 · SRE/DevOps.
Audience superposition:
1. Operator (Dane today, ABKC staff future) — click-by-click + checklists + troubleshooting
2. F100 board / PhD-CS reviewer — cited industry anchors + honest reservations + verification table
3. AI consumer (future Claude/Codex/Gemini sessions) — structured MD + machine-parsable verification commands
Generator:~/scripts/generate-tutorial-html.pyv3.1.0 (interactive HTML with 13 F100 features) +~/scripts/generate-advanced-md-v3.py(sibling PDF + DOCX)
Per: Tutorial Template v2 spec — 17 sections + 4 Mermaid + ≥35 hyperlinks + ≥45 glossary + ≥20 screenshot placeholders + sign-off
Time budget: 10-15 minutes operator time (Dane)
Estimated artifact pricing: Sandbox transaction = $0 (no real currency); only your time
§0 — Scope + What This Walkthrough Is (and Isn't)
Status delta (V1 2026-05-28 → V2 2026-06-09) — what changed around the procedure
| Surface | V1 state | V2 state (2026-06-09) |
|---|---|---|
| PR fix-chain #156–159 | Just merged (load-bearing) | Historical — stable on main for 12 days |
| Cross-browser CI | Single-browser e2e | Tiered gate live (PR #175): chromium+firefox blocking; webkit/mobile-safari signal lane |
/login WebKit flake |
Undiscovered | Root-caused (ABKC-15) + fixed; PR #178 ready-for-review with 3/3 green WebKit verification runs |
| Jira ↔ GitHub | Manual | Sync workflow live (#177): ABKC-n:-prefixed PRs auto-link |
| Walkthrough family | This doc + presentation + capture guide | + Co-owner walkthrough V1 (ABKC-PAYMENT-WALKTHROUGH-CO-OWNER-V1-2026-06-09.md) + Office-Manager walkthrough V1 (ABKC-ADMIN-OFFICE-MANAGER-WALKTHROUGH-V1-2026-06-09.md) — same folder |
| Fulfillment triage | Undocumented | Office-Manager walkthrough M4 documents the 3 trigger paths (Stripe/PayPal webhooks + scheduled backstop) |
| This doc's gate | — | Unchanged: Dane runs it end-to-end + signs §17 → ABKC-14 transitions to Done |
What this IS
A reproducible, audit-defensible procedure to confirm that the ABKC single-owner dog-registration payment surface works end-to-end in production. After running it, you will have:
- ✅ Empirical proof that PayPal SDK loads correctly in production (post PR #158 trim fix)
- ✅ Empirical proof that
POST /api/registration/create-orderreturns HTTP 200 with a real PayPal order ID (post PR #159 server-side env trim) - ✅ Empirical proof that
POST /api/registration/capture-ordercompletes the sandbox transaction - ✅ Empirical proof that the Resend confirmation email arrives
- ✅ Empirical proof that Supabase
applicationstable updatespayment_status='paid' - ✅ Captured screenshots for the ABKC owners presentation deck
What this IS NOT
- ❌ Not a co-owner / dual-signature walkthrough — that document now exists:
ABKC-PAYMENT-WALKTHROUGH-CO-OWNER-V1-2026-06-09.md(this folder; run it WITH James, AFTER this one is signed) - ❌ Not a litter-registration / show-entry / membership flow (each gets its own future B-ABKC-FORM-N walkthrough)
- ❌ Not a load test, security audit, or PCI compliance review (separate scopes)
- ❌ Not a production custom-domain test — runs against
abkc-website.vercel.app; thewww.abkcdogs.comcutover is gated on the ABKC ownership sign-off block (Owners Presentation §9, this folder). (V1 linked the originating 2026-05-23 dispatch matrix; that file has since been archived per the estate 7-day rule — the presentation §9 block is the live gate.) - ❌ Not a real-money test — PayPal sandbox + Stripe test card only; zero real currency moves
§1 — Tutorial Pattern + Triple Verification Protocol
This walkthrough follows the Tutorial Template v2 spec ratified 2026-05-27 ~mid ET. Required: 17 sections + 4 Mermaid diagrams (architecture / sequence / decision-tree / Gantt) + ≥35 industry-anchored hyperlinks + ≥45 glossary terms + ≥20 screenshot placeholders + ≥6 honest reservations + sign-off page.
Triple Verification Protocol (per global-truth.md §1 2026-05-24 ratification)
| Level | Verification | Result |
|---|---|---|
| L1 — Empirical | curl -sS -X POST https://abkc-website.vercel.app/api/registration/create-order -H 'Content-Type: application/json' -d '{}' post-PR-#159-merge 2026-05-28 ~00:21 UTC |
HTTP 400 with Zod validation error (application_id required); the endpoint that was 500'ing before now executes past env-dependent code and returns clean 4xx → server-trust layer VERIFIED |
| L2 — WebSearch (2026) | "PayPal Smart Buttons sandbox testing 2026 Next.js" | Latest PayPal Smart Buttons docs confirm popup-vs-iframe modes; PayPal sandbox developer dashboard is the canonical test buyer creation surface |
| L3 — Vendor docs | PayPal REST API v2 Orders + Stripe Checkout Sessions + Supabase RLS + Resend transactional | All current; payment flows match documented patterns |
§2 — Prerequisites + Audience + Time Budget
Prerequisites
You will need:
💡 TIP: Have these ready BEFORE you start. The flow takes ~10-15 minutes uninterrupted; pausing to fetch creds adds ~5 minutes.
Browser: Chrome 122+ or Edge 122+ (NOT incognito/private)
Internet: Stable (PayPal sandbox needs ~5 round-trips)
PayPal sandbox: Buyer account email + password
(lives in your password manager OR .env.test.local;
create new at https://developer.paypal.com/dashboard/accounts
if you've forgotten)
Local file paths: This walkthrough open in browser/editor
for reference + checkmark progress
DevTools: F12 ready; Network tab + Console tab
prepared with "Preserve log" checked
Screenshot tool: ShareX 14+ (Windows canonical;
https://getsharex.com/)
OR built-in Snipping Tool (Win+Shift+S)
Audience
- Primary: Dane Cooper running self-validation 2026-05-28
- Secondary: ABKC owners reviewing payment infrastructure proof (via companion presentation)
- Tertiary: Future ABKC staff onboarding (when this walkthrough becomes the operator manual)
- AI consumer: Future Claude/Codex sessions parsing this for context + verification commands
Time budget
- Setup: ~2 min (open browser, fetch creds, prep DevTools)
- Form fill: ~2 min (sandbox data; not careful-curated)
- PayPal popup + login + Pay: ~3-5 min
- Confirmation + email arrival: ~1-2 min
- Screenshot capture (optional): ~3-5 min
- Total: ~10-15 minutes
ℹ️ INFO: If anything fails mid-flow, expect +5-15 min for triage. Section §16 "Failure modes" has triage tables. Don't abandon; capture the failing state + report back.
§3 — Mermaid #1: Production Payment Architecture
System topology — what's actually running in production when you submit a payment.
Next.js 16 SSR"] SDK[PayPal SDK
checkout.js v5] POPUP[Sandbox popup
www.sandbox.paypal.com] end subgraph Vercel["☁️ Vercel Edge Network"] EDGE[Edge Middleware
CSP + nonce + rate-limit] FN1["/api/registration/
create-order
Node.js 24 fn"] FN2["/api/registration/
capture-order
Node.js 24 fn"] WH["/api/webhooks/paypal
HMAC verify"] end subgraph PayPal["💰 PayPal Sandbox"] OAUTH[OAuth Token
/v1/oauth2/token] ORDERS[Orders API
/v2/checkout/orders] CAPTURE[Capture API
/v2/checkout/orders/
:id/capture] end subgraph DCoop["🗄️ DCoop infra"] SB[(Supabase Postgres
applications table)] REDIS[(Upstash Redis
rate-limit + idempotency)] RESEND[Resend
transactional email] SENTRY[Sentry
error tracking] end UI -->|fills form| EDGE EDGE -->|POST application_id| FN1 FN1 -->|trim env + Basic auth| OAUTH OAUTH -->|access_token| FN1 FN1 -->|create order| ORDERS ORDERS -->|orderId| FN1 FN1 -->|insert row| SB FN1 -->|orderId| UI SDK -->|render buttons| UI SDK -.opens.-> POPUP POPUP -->|sandbox auth| ORDERS POPUP -.-> SDK SDK -->|onApprove| FN2 FN2 -->|capture| CAPTURE CAPTURE -->|COMPLETED| FN2 FN2 -->|update payment_status='paid'| SB FN2 -->|send confirmation| RESEND WH -.async webhook.-> SB FN1 -->|trace exceptions| SENTRY FN2 -->|trace exceptions| SENTRY EDGE -->|key/ip| REDIS style FN1 fill:#fce7f3,stroke:#ec4899,color:#000 style FN2 fill:#fce7f3,stroke:#ec4899,color:#000 style SB fill:#dbeafe,stroke:#3b82f6,color:#000 style POPUP fill:#fef3c7,stroke:#f59e0b,color:#000
📝 NOTE: This diagram is the happy path. Side paths (Stripe-Checkout-Session for card-only users / refund webhook / failed-capture retry / fraud screening) exist but are out of scope for the single-owner walkthrough; covered in
ABKC-PAYMENT-ARCHITECTURE.md§11.
§4 — Mermaid #2: Click-by-click Payment Sequence
What happens in temporal order from "click PayPal button" to "email arrives":
buyer creds U->>PO: Login + click "Pay Now" PO->>PP: Approve payment (sandbox) PP-->>PO: Approval token PO-->>S: window.postMessage(onApprove) deactivate PO S->>CA: POST /capture-order {orderId} activate CA CA->>PP: POST /v2/checkout/orders/:id/capture PP-->>CA: {status: COMPLETED} CA->>DB: UPDATE payment_status='paid' CA->>E: send confirmation email E-->>U: 📧 Email arrives (~30s) CA-->>P: {status: COMPLETED, applicationId} deactivate CA P->>U: Show success message + UUID
⚠️ WARNING: The popup at step 8 (
PO) is where the bug was MOST visible. Pre-fix, the popup opened toabout:blankthen closed, because/create-orderwas returning 500 before the popup could navigate. Post-fix (PR #159), the popup navigates correctly tosandbox.paypal.com. If you seeabout:blank, §16 failure mode F1 covers triage.
§5 — Mermaid #3: Failure Mode Decision Tree
What to do if any step fails:
page load with PayPal
button visible?} Q1 -->|No - button missing| F1[F1: PR #158 regression
NEXT_PUBLIC_PAYPAL_CLIENT_ID
still has whitespace] F1 --> Action1[ACTION: Capture screenshot;
check console for SDK errors;
report to Claude for re-trim] Q1 -->|Yes| Q2{Click PayPal button.
Does popup open to
sandbox.paypal.com?} Q2 -->|Stays about:blank
then closes| F2[F2: PR #159 regression
OR /create-order returning 500] F2 --> Action2[ACTION: F12 Network tab
copy /create-order response;
check Vercel runtime logs] Q2 -->|Opens correctly| Q3{Login + Pay
completes?
Popup closes?} Q3 -->|Login fails| F3[F3: Sandbox creds wrong
OR PayPal sandbox suspended] F3 --> Action3[ACTION: Verify creds at
developer.paypal.com/dashboard;
create fresh buyer if needed] Q3 -->|Pay completes,
popup closes| Q4{Success message
on main page +
UUID shown?} Q4 -->|Error message instead| F4[F4: /capture-order returning 5xx
different env issue
OR PayPal session expired] F4 --> Action4[ACTION: F12 Network tab
copy /capture-order response;
check PayPal order status
via dashboard] Q4 -->|Success shown| Q5{Confirmation email
arrives within 60s?} Q5 -->|No email after 5 min| F5[F5: Resend env still broken
OR domain DNS records
misconfigured] F5 --> Action5[ACTION: Check Resend dashboard
at resend.com/emails;
verify RESEND_API_KEY trimmed;
check application row in Supabase] Q5 -->|Email arrives| Success([✅ VERIFIED
End-to-end PASS
AC6+AC7 satisfied]) style Success fill:#d1fae5,stroke:#10b981,color:#000 style F1 fill:#fee2e2,stroke:#ef4444,color:#000 style F2 fill:#fee2e2,stroke:#ef4444,color:#000 style F3 fill:#fef3c7,stroke:#f59e0b,color:#000 style F4 fill:#fee2e2,stroke:#ef4444,color:#000 style F5 fill:#fef3c7,stroke:#f59e0b,color:#000
§6 — Mermaid #4: Time Allocation Gantt
Expected duration of each step (uninterrupted happy path):
💡 TIP: If you go OVER 15 min total, something is probably wrong. Most often the "popup opens" step (~10s expected). If popup is still loading at 30s, you've hit a network or sandbox issue — proceed to §16 failure mode triage.
§7 — Gate 1: Setup (~3-5 min)
🚨 CRITICAL PREREQUISITE — Authentication required. Empirically verified 2026-05-28 ~23:55 UTC via autonomous Playwright run: the registration form requires you to be signed in to your ABKC member account before the Validate button will succeed. All registration API endpoints (
/my-drafts,/my-co-owners,/search-dogs,/draft/save) return HTTP 401 Unauthorized without auth. Without authentication, the form CAN be filled but the Validate step silently fails + PayPal Smart Buttons never render. Sign in first (Step 1.0 below).
Step 1.0 — Sign in to your ABKC member account (REQUIRED prerequisite)
- Navigate to https://abkc-website.vercel.app/login (or click "Sign In" link in the site header)
- Enter your ABKC member email + password
- (If 2FA enabled) Enter the SMS code via Twilio Verify
- Verify your name appears in the top-right of the site header (signed-in state)
✅ SUCCESS: Your member name appears in the header. The form at
/register/dogwill now have your owner info auto-populated.🚨 DANGER: Do NOT proceed to Step 1.1 without confirmed sign-in. The form will appear to work (you can type into fields) but the Validate click will fail silently. You'll see PayPal buttons NEVER render and waste 15 minutes wondering why.
📝 NOTE — For James (co-owner) handoff: James does NOT need his own ABKC member account. He'll be added as a co-owner via the form's Co-Owner Information fields (filled by Dane during the dual-owner walkthrough). Only the PRIMARY owner (Dane) needs to authenticate.

Step 1.1 — Open Chrome (not incognito)
Why Chrome (not incognito): PayPal sandbox sometimes blocks third-party cookies in private windows, breaking the popup auth flow.
🚨 DANGER: Do NOT use real PayPal credentials in this walkthrough. Only sandbox buyer creds. Sandbox creds look like
sb-buyer-12345@business.example.com— they all live under@*.example.comor@business.example.comdomains.

Step 1.2 — Fetch sandbox buyer credentials
Three options (pick whichever fits your password-management workflow):
Option A — Local .env.test.local (fastest)
grep -E "^PAYPAL_SANDBOX_BUYER_(EMAIL|PASSWORD)" ~/ecosystem-abkc/abkc-website/.env.test.local
Expected output:
PAYPAL_SANDBOX_BUYER_EMAIL=sb-buyer-XXXXX@business.example.com
PAYPAL_SANDBOX_BUYER_PASSWORD=XxxxxxxxX
Option B — PayPal Developer Dashboard
- Open https://developer.paypal.com/dashboard/accounts
- Find the "buyer" account row (NOT business/merchant)
- Click the email → drawer opens with full creds (including a "Reveal" button for password)
- Copy email + password to a temporary scratch buffer

Option C — Password manager (1Password, Bitwarden, etc.)
Look for entries tagged PayPal sandbox buyer or ABKC sandbox.
ℹ️ INFO: If NONE of these options have working credentials, see §16 failure mode F3 — you'll need to create a fresh buyer account in the developer dashboard (~3 min).
Step 1.3 — Open DevTools, prepare logging
In Chrome:
1. Press F12 to open DevTools
2. Click the Network tab
3. Check "Preserve log" (top of Network tab)
4. Click the Console tab (alongside Network)
5. Right-click anywhere in Console → "Clear console" (start fresh)

📝 NOTE: Leave DevTools open the entire walkthrough. You'll capture screenshots of the Network tab at key steps to document the HTTP traffic for the ABKC owners presentation.
§8 — Gate 2: Form Fill + PayPal Button Render (~3 min)
Step 2.1 — Navigate to registration page
Paste into Chrome address bar:
https://abkc-website.vercel.app/register/dog
⚠️ WARNING: NOT
www.abkcdogs.com/register/dog— the custom domain is gated on the ABKC ownership sign-off block (Owners Presentation §9, this folder). Until that block is signed, production validation runs on the Vercel preview URL.
Expected:
- Page loads in ~2 seconds
- You see the dog registration form (header + breed dropdown + owner fields + dog fields)
- Scroll to bottom: PayPal Smart Button area visible (may show a spinner for ~1-2 seconds, then renders)

Step 2.2 — Survey the form structure (two-stage flow context)
📝 NOTE — TWO-STAGE FLOW: Empirical Playwright inspection 2026-05-28 ~23:43 UTC confirms the registration page is a two-stage flow. PayPal Smart Buttons do NOT render on the empty page — only AFTER you click "Validate & Prepare for Payment" (Step 2.7). On initial page load, you'll see the form structure + a single blue "Validate & Prepare for Payment" button at the bottom.
Glance at the page structure (you should see, top-to-bottom):
| Section | What to verify |
|---|---|
| Title + intro | "Register Your Dog with ABKC" |
| Registration Type | 4 radio buttons (Conditional / Permanent / Other Registry / UKC etc.) |
| Owner Information | Name + email + phone + address fields |
| Co-Owner Information | All BLANK for single-owner test (we cover this in the co-owner walkthrough) |
| Dog Information | Name + breed + sex + DOB + sire + dam + microchip fields |
| Document Upload | 3 file-upload areas + signature canvas |
| Optional Promotions | Add-on checkboxes (Bully ID Card / Signature Pedigree) |
| Shipping Options | Address fields |
| Terms & Disclosures | Checkboxes |
| Fee Summary | Itemized prices + Total |
| Payment area | A single blue "Validate & Prepare for Payment" button (NOT PayPal yet) |
Empirical DOM signals (from the autonomous walkthrough run):
Total inputs: 49 fields
Total labels: 41 labels
Upload widgets: 3 (pedigree-front + pedigree-complete + dog-photos)
Signature canvas: 1
Total visible price components: $7 (admin) + $55 (base) + add-ons
Final Total at empty: $62.00
✅ SUCCESS: If you see the full form structure above + the "Validate & Prepare for Payment" button at the bottom = page loaded correctly. The PayPal-button rendering happens at Step 2.7 after you Validate.
🚨 DANGER: If the page is blank, shows a 404, or has a major rendering error — STOP. This means Vercel deployment is unhealthy. Verify via §10 Reference Card probe commands.

Step 2.3 — Fill registration form with sandbox data
Copy-paste these values into the corresponding fields:
Owner name: Sandbox Tester
Owner email: <YOUR-REAL-EMAIL> (use your real email so you receive the confirmation)
Phone: 555-555-5555 (any valid US format)
Dog name: Sandbox Test 2026-05-28
Breed: American Bully (or any from dropdown)
Sex: Male (or Female; doesn't matter)
DOB: 2026-01-01 (recent date so dog is < 12 months; avoids DNA cert requirement)
Color: Brown
Sire name: Sandbox Sire (or leave blank if field is optional)
Dam name: Sandbox Dam (or leave blank if field is optional)
Sire registration: (leave blank if sire optional; otherwise SAND-001)
Dam registration: (leave blank if dam optional; otherwise SAND-002)
Microchip: (leave blank — optional)
Address line 1: 123 Test St
City: Houston
State: TX
ZIP: 77001
Other registry: (leave as empty/none — avoids extra paperwork upload)
Co-owner name: (leave BLANK for single-owner test)
Bully ID add-on: (leave UNCHECKED — avoids extra headshot photo)
Signature Pedigree (+$500): (leave UNCHECKED — keeps total at base price)
💡 TIP: Three critical sandbox choices: (1) DOB recent so no DNA certificate required, (2) other-registry empty so no UKC/AKC papers needed, (3) co-owner empty so this stays a single-owner test. The companion co-owner walkthrough handles the co-signature path separately.
ℹ️ INFO: The owner email is the ONLY field where you should use real data — you'll want to verify the Resend confirmation email arrives. Everything else is sandbox.

Step 2.4 — Upload required documents (4 files)
The registration form REQUIRES 4 file uploads before it will let you proceed to payment. Sample test fixtures are pre-shipped at test-fixtures/ in the repo root:
~/ecosystem-abkc/abkc-website/test-fixtures/dog-photo-1.png (23 KB)
~/ecosystem-abkc/abkc-website/test-fixtures/dog-photo-2.png (24 KB)
~/ecosystem-abkc/abkc-website/test-fixtures/pedigree-front.pdf (2 KB)
~/ecosystem-abkc/abkc-website/test-fixtures/pedigree-complete.pdf (2 KB)
📝 NOTE: These fixtures are tiny stand-in files designed for E2E sandbox testing. They satisfy the form's required-upload validation but contain no real dog/pedigree data. James, you'll find these files inside the handoff zip at
test-fixtures/after you extract.
Upload #1 — "Upload Front Page of Your Dog's Pedigree"
- Click the upload area or drag-drop
pedigree-front.pdf - Accept types:
.jpg .jpeg .png .webp .pdf - Max size: 10 MB
- This corresponds to the form's
pedigree_paperupload type

Upload #2 — "Upload Complete Copy of the Pedigree"
- Click upload or drag-drop
pedigree-complete.pdf - Note in form: "Showing the lineage. If this is an ownership transfer, upload back page copy also."
- Stored as
ownership_proofupload type internally

Upload #3 — "Upload 2 CLEAR Photos of the Dog"
- Upload
dog-photo-1.png(front view) - Upload
dog-photo-2.png(side view, "showing THE TAIL" per form note) - This is a
multipleupload — both files in the same widget - Stored as
photo_front+photo_sideinternally

⚠️ WARNING: If you upload only 1 dog photo, the form rejects with "Please upload 2 photos of the dog (front and side view)." You MUST upload both.
🚨 DANGER: Do NOT upload real ABKC member dogs/pedigrees during sandbox testing. The test-fixtures are intentionally minimal-stand-in files. If you accidentally upload real images, delete the resulting test application immediately via the Supabase dashboard.
Step 2.5 — Sign signature pad + check confirmation boxes
Below the upload widgets, the form has three more required actions:
Signature pad
- A canvas widget labeled "Sign here"
- Draw your signature with mouse/touchpad (any signature is fine for sandbox)
- The form converts it to a PNG image + uploads to Supabase Storage as
signatures/ - Click "Clear" if you want to redo

Profile confirmation checkbox
- Checkbox: "I confirm my profile information is correct"
- This must be CHECKED for the form to validate
Terms agreement checkbox
- Checkbox: "I agree to the shipping disclosure" (or similar)
- This must be CHECKED for the form to validate

Step 2.6 — Verify form ready + total displayed
Glance at the form:
- ✅ All text fields filled
- ✅ 4 files uploaded (pedigree-front + pedigree-complete + 2 dog photos)
- ✅ Signature drawn
- ✅ Both checkboxes checked
- ✅ "Total: $62.00" visible at the bottom (base registration $55 + Processing & Admin Fee $7; varies if add-ons selected)
- ✅ No red validation errors anywhere
⚠️ WARNING: If the form shows ANY red error (e.g., "Please upload the front page of the pedigree"), the form will NOT validate. Fix the error first.

Step 2.7 — Click "Validate & Prepare for Payment" (CRITICAL two-stage flow)
🚨 IMPORTANT: The registration form is a two-stage flow. The PayPal Smart Buttons do NOT appear on the empty page or even on a filled-but-not-validated form. They appear ONLY AFTER you click the "Validate & Prepare for Payment" button.
Empirically verified 2026-05-28 ~23:43 UTC via Playwright DOM inspection:
Total buttons on page: 11
Stage-1 button (click this): "Validate & Prepare for Payment"
Stage-2 button (auto-shown): PayPal Smart Buttons (after Stage 1)
Stage-3 button (final): "Submit Application — complete payment above first"
(disabled until PayPal capture completes)
Action: Scroll to the bottom of the form. Find the blue "Validate & Prepare for Payment" button. Click it.
Expected outcomes:
- Server-side validation fires (Zod schemas check the request payload)
- The 4 file uploads commit to Supabase Storage (pedigree + photos)
- The signature canvas converts to PNG + uploads
- If validation PASSES → PayPal Smart Buttons render below the validation button + "Total: $62.00" displays the final amount
- If validation FAILS → red error message identifies the failing field; fix + retry
💡 TIP: Watch the Network tab in DevTools — you'll see multiple
PUTrequests to*.supabase.co/storage/v1/object/applications/...as files upload. Then PayPal SDK loads frompaypal.com/sdk/js?client-id=....


Step 2.8 — Verify PayPal Smart Buttons rendered post-validation
After clicking Validate, you should see three stacked funding sources appear:
| Button | Color | Label |
|---|---|---|
| 1 | Yellow | PayPal |
| 2 | White with black border | Pay Later |
| 3 | Black | Pay with Card |
✅ SUCCESS: All three buttons rendered = PR #158 client-side trim fix WORKING.
NEXT_PUBLIC_PAYPAL_CLIENT_IDis clean on Vercel + SDK can fetch + render funding sources.🚨 DANGER: If you only see a gray box or "Cannot render funding source" error or nothing at all — STOP. This means PR #158 regressed OR the validation step failed silently. Capture a screenshot, F12 → Console tab → screenshot any red errors. Go to §16 failure mode F1.

§9 — Gate 3: Payment Flow (~5-7 min)
Step 3.1 — Click the yellow PayPal button
🎯 This is the BIG TEST. The bug Dane saw originally — popup opens to about:blank then closes — should NOT happen post PR #159 merge.
Click the yellow PayPal button (top funding source). Watch the DevTools Network tab.
Step 3.2 — Verify /create-order returns 200 (CRITICAL)
In the Network tab, you'll see a request appear:
Name: create-order
Method: POST
Status: 200 ← MUST be 200 (not 500)
Path: /api/registration/create-order
Click on it. The Response tab should show JSON like:
{
"orderId": "9XK12345AB678901C",
"applicationId": "f260ad1c-ce32-4688-a426-7909debb0a05"
}
✅ SUCCESS: HTTP 200 +
orderIdin response = PR #159 server-side env trim WORKING. PayPal OAuth Basic auth header is well-formed; access_token fetched; order created.🚨 DANGER: If
/create-orderreturns HTTP 500 with{"error":"INTERNAL_ERROR","details":"Failed to create order"}— STOP. The trim fix didn't fully take in production. Capture the full response body (Response tab) + go to §16 failure mode F2.

Step 3.3 — Verify popup opens to PayPal sandbox
A new popup window should open within ~1 second of clicking the PayPal button.
Expected:
- Popup URL changes from about:blank → https://www.sandbox.paypal.com/checkoutnow?token=<orderId>
- Popup shows the PayPal sandbox login screen (yellow branding, email/password fields)
🚨 DANGER: If popup stays at
about:blankfor more than ~3 seconds OR closes immediately — STOP. Even though/create-orderreturned 200, something is interrupting the popup navigation. This could be:
- Pop-up blocker (rare; usually only on aggressive ad-block extensions)
- SDK init failure (mismatched orderId)
- Browser zoom misconfigurationCapture a Console screenshot + go to §16 failure mode F2 (extended).

Step 3.4 — Log in to PayPal sandbox
In the popup:
1. Paste your sandbox buyer email (from Step 1.2)
2. Click "Next" (or "Continue")
3. Paste your sandbox buyer password
4. Click "Log In"
ℹ️ INFO: Sandbox login is occasionally slow (~5-10s). PayPal's sandbox environment is shared infrastructure; expect occasional latency. If it takes >30 seconds, refresh the popup (Ctrl+R inside the popup window) and re-enter creds.

Step 3.5 — Approve the $62 payment
After login, the popup shows order summary:
- Merchant: ABKC (or your test entity name)
- Amount: $62.00 USD (or whatever the form computed)
- Funding source: Sandbox buyer balance OR sandbox test card
Click "Pay Now" (or "Complete Purchase" — button label varies).
Expected:
- Popup briefly shows "Processing..." spinner
- Popup closes automatically (~2-3 seconds)
- You're returned to the main /register/dog page

Step 3.6 — Verify /capture-order returns 200
Back on the main page, check DevTools Network tab. You'll see:
Name: capture-order
Method: POST
Status: 200
Path: /api/registration/capture-order
Response body:
{
"status": "COMPLETED",
"applicationId": "f260ad1c-ce32-4688-a426-7909debb0a05",
"paypalOrderId": "9XK12345AB678901C"
}
✅ SUCCESS:
status: COMPLETEDconfirms PayPal sandbox processed the payment. Supabase row should now showpayment_status='paid'.

Step 3.7 — Verify success message on main page
The main page should now show:
- ✅ A green success banner: "Payment captured! Registration submitted." (or similar)
- ✅ Application ID (UUID format; matches the one in Network tab)
- ✅ "We've sent a confirmation email to
⚠️ WARNING: If you see an error message instead of success — the capture step failed even though
/capture-orderreturned 200. This is unusual but possible (race condition with Supabase update). Go to §16 failure mode F4.

Step 3.8 — Verify confirmation email arrives
Within ~30-60 seconds, check your email inbox (the real address you used in Step 2.3).
Expected email:
- From: noreply@abkcdogs.com (or whatever REGISTRATION_FROM_EMAIL is set to)
- Subject: "Registration confirmation — Sandbox Test 2026-05-28"
- Body: HTML with application UUID + payment confirmation + next-steps
📝 NOTE: If email doesn't arrive within 2 minutes, check spam folder first. Then check Resend dashboard at resend.com/emails for delivery status. Go to §16 failure mode F5 if still missing.

Step 3.9 — Verify Supabase row updated (optional but recommended)
Open https://supabase.com/dashboard/project/jufvmcrckprzaezcwaqg/editor in a new tab. Navigate to the applications table. Filter by the application UUID from Step 3.7.
Expected row:
id: f260ad1c-ce32-4688-a426-7909debb0a05
dog_name: Sandbox Test 2026-05-28
owner_email: <your-real-email>
payment_status: paid ← MUST be 'paid' (not 'pending' or 'failed')
paypal_order_id: 9XK12345AB678901C
payment_captured_at: 2026-05-28 XX:XX:XX UTC
✅ SUCCESS:
payment_status='paid'+ non-nullpayment_captured_at= end-to-end VERIFIED.

Step 3.10 — Capture supplementary screenshots for owners presentation
For the companion presentation, capture these additional screens beyond the per-step screenshots:




💡 TIP: For the owners presentation, the SUPPLEMENTARY screenshots above are more compelling than the per-step ones. They show "the system works" in 4 frames vs the per-step granularity Dane needs for triage.
§10 — Reference Card (copy-paste-ready)
Probe commands (paste into terminal to verify production state)
# 1. Vercel deployment health
curl -sSI https://abkc-website.vercel.app/ | head -3
# 2. Production /create-order returns 400 validation (NOT 500)
curl -sS -X POST https://abkc-website.vercel.app/api/registration/create-order \
-H "Content-Type: application/json" \
-d '{}' \
-w '\n[HTTP %{http_code}]\n'
# 3. Production /create-stripe-session returns 400 validation (NOT 500)
curl -sS -X POST https://abkc-website.vercel.app/api/registration/create-stripe-session \
-H "Content-Type: application/json" \
-d '{}' \
-w '\n[HTTP %{http_code}]\n'
# 4. Check recent Vercel deployments
gh api repos/katterskillsawmill/ABKC-website/deployments --jq '.[0:3] | .[] | {sha: .sha[:8], created_at}'
# 5. Verify PR #159 merge commit
gh pr view 159 --repo katterskillsawmill/ABKC-website --json mergedAt,mergeCommit
Supabase quick queries (paste into SQL Editor)
-- Verify application row paid status
SELECT id, dog_name, owner_email, payment_status, payment_captured_at, paypal_order_id
FROM applications
WHERE id = 'YOUR-UUID-HERE'
ORDER BY created_at DESC
LIMIT 1;
-- All paid applications in last 24h
SELECT COUNT(*) AS paid_count, MIN(payment_captured_at) AS earliest, MAX(payment_captured_at) AS latest
FROM applications
WHERE payment_status = 'paid'
AND payment_captured_at > now() - INTERVAL '24 hours';
-- Find applications stuck in 'pending' (potential failures to investigate)
SELECT id, dog_name, created_at, paypal_order_id
FROM applications
WHERE payment_status = 'pending'
AND created_at < now() - INTERVAL '1 hour'
ORDER BY created_at DESC;
Sandbox creds template (fill in from password manager)
PAYPAL_SANDBOX_BUYER_EMAIL=sb-buyer-XXXXX@business.example.com
PAYPAL_SANDBOX_BUYER_PASSWORD=<reveal in developer.paypal.com/dashboard/accounts>
PAYPAL_SANDBOX_API_BASE=https://api-m.sandbox.paypal.com
STRIPE_TEST_CARD_NUMBER=4242 4242 4242 4242
STRIPE_TEST_CARD_EXPIRY=any future date
STRIPE_TEST_CARD_CVC=any 3 digits
STRIPE_TEST_CARD_ZIP=any 5 digits
Quick reference URLs
| Surface | URL |
|---|---|
| Production preview | https://abkc-website.vercel.app/register/dog |
| PayPal sandbox accounts | https://developer.paypal.com/dashboard/accounts |
| Vercel deployments | https://vercel.com/katterskillsawmill/abkc-website/deployments |
| Supabase dashboard | https://supabase.com/dashboard/project/jufvmcrckprzaezcwaqg |
| Resend dashboard | https://resend.com/emails |
| Sentry dashboard | https://kaaterskillsawmill.sentry.io/issues/ |
| Twilio console | https://console.twilio.com/ |
| GitHub repo | https://github.com/katterskillsawmill/ABKC-website |
| PR #159 (server env trim) | https://github.com/katterskillsawmill/ABKC-website/pull/159 |
| PR #158 (client trim) | https://github.com/katterskillsawmill/ABKC-website/pull/158 |
| Jira ABKC project | https://kaaterskillsawmill.atlassian.net/jira/software/projects/ABKC/boards/2 |
§11 — UI Anatomy (annotated descriptions for sections where screenshots can't reach)
PayPal Smart Button area (registration page bottom)
┌─────────────────────────────────────────┐
│ Order Summary │
│ ─────────────────────────── │
│ Dog: Sandbox Test 2026-05-28 │
│ Type: Single dog registration │
│ Subtotal: $50.00 │
│ Processing fee: $12.00 │
│ ───────────────────── │
│ Total: $62.00 │
│ │
│ [ PayPal ] ← yellow; click here │
│ [ Pay Later ] ← white border │
│ [ Pay w/ Card ] ← black │
│ │
│ By submitting, you agree to terms... │
└─────────────────────────────────────────┘
Sandbox popup window (after click)
┌─ www.sandbox.paypal.com/checkoutnow?token=... ──┐
│ [PayPal logo] │
│ │
│ Pay with PayPal │
│ ─────────────── │
│ │
│ Email or mobile: [_______________________] │
│ Password: [_______________________] │
│ │
│ [ Log In ] │
│ │
│ Forgot password? · Sign Up · Cancel │
└──────────────────────────────────────────────────┘
DevTools Network tab key columns to watch
Name Method Status Type Initiator Size Time
──────────────── ────── ────── ──── ────────────── ────── ────
create-order POST 200 xhr sdk-script.js 1.2KB 234ms
checkoutnow GET 200 doc popup-window 45KB 412ms
capture-order POST 200 xhr sdk-script.js 1.5KB 1.8s
📝 NOTE: If
Statuscolumn shows red (5xx) on ANY of these three rows, that's the failure point. Click the red row → Response tab → screenshot it.
§12 — Verification Commands Library (machine-parsable)
These are repeatable commands the operator OR an AI consumer can run to programmatically verify the walkthrough's outcomes.
Pre-walkthrough verification
# Verify Vercel deployment matches merge commit
DEPLOY_SHA=$(gh api repos/katterskillsawmill/ABKC-website/deployments --jq '.[0].sha')
MERGE_SHA=$(gh pr view 159 --repo katterskillsawmill/ABKC-website --json mergeCommit --jq '.mergeCommit.oid')
test "$DEPLOY_SHA" = "$MERGE_SHA" && echo "✅ Latest deploy = PR #159" || echo "⚠️ Drift"
# Verify production endpoint returns 400 (not 500)
HTTP_CODE=$(curl -sS -X POST https://abkc-website.vercel.app/api/registration/create-order \
-H "Content-Type: application/json" -d '{}' -o /dev/null -w '%{http_code}')
test "$HTTP_CODE" = "400" && echo "✅ /create-order returns 400 validation" || echo "❌ Got $HTTP_CODE"
Mid-walkthrough verification (after Step 3.6)
# Set the application UUID from the walkthrough run
APP_ID="<paste UUID from Step 3.7 success banner>"
# Verify Supabase row paid (requires SUPABASE_SERVICE_ROLE_KEY in env)
curl -sS "https://jufvmcrckprzaezcwaqg.supabase.co/rest/v1/applications?id=eq.${APP_ID}&select=id,payment_status,paypal_order_id" \
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
| jq '.[0] | {id, payment_status, paypal_order_id}'
Post-walkthrough verification
# Verify Resend email delivery (requires RESEND_API_KEY in env)
curl -sS "https://api.resend.com/emails?to=<your-email>" \
-H "Authorization: Bearer ${RESEND_API_KEY}" \
| jq '.data[0] | {id, subject, last_event}'
# Verify Sentry shows no new 5xx errors in last 15 min
SENTRY_PROJECT="abkc-website"
curl -sS "https://sentry.io/api/0/projects/kaaterskillsawmill/${SENTRY_PROJECT}/events/?statsPeriod=15m&query=level:error" \
-H "Authorization: Bearer ${SENTRY_AUTH_TOKEN}" \
| jq 'length'
Smoke test (idempotent; run any time)
# Full payment surface smoke test
for endpoint in create-order create-stripe-session; do
CODE=$(curl -sS -X POST "https://abkc-website.vercel.app/api/registration/${endpoint}" \
-H "Content-Type: application/json" -d '{}' -o /dev/null -w '%{http_code}')
test "$CODE" = "400" && echo "✅ ${endpoint}: 400 validation (healthy)" \
|| echo "❌ ${endpoint}: ${CODE}"
done
§13 — What's Next
Immediate (after this walkthrough PASSES)
- G-VAL-1 Capture all 20 screenshots per §7-§9 + organize in
screenshots/gate-{1,2,3}/per Screenshot Capture Guide - G-VAL-2 Sign the §17 sign-off page; date + signature
- G-VAL-3 Ship the 4-format trio to ABKC owners via Telegram + email (per companion presentation)
- G-VAL-4 Close ABKC-14 Jira ticket (this walkthrough authoring) → Done
Near-term (next 1-3 days)
- N1: Author co-owner walkthrough (
ABKC-PAYMENT-WALKTHROUGH-CO-OWNER-V1-2026-05-28.md) — Dane + James + loan workflow integration; same v2 spec; ~3-4h Claude - N2: Capture screenshots IF ABKC owners want photo-proof for DNS sign-off
- N3: Schedule Dane+James co-owner test session (~30 min)
Medium-term (next 1-2 weeks)
- M1: Form-by-form coverage register (B-ABKC-FORM-N entries):
- B-ABKC-FORM-1: Litter registration walkthrough (single + co-owner)
- B-ABKC-FORM-2: Show entry walkthrough (single)
- B-ABKC-FORM-3: Membership signup walkthrough
- B-ABKC-FORM-4: ABKC# transfer walkthrough (dual-party)
- B-ABKC-FORM-5: Title application walkthrough (single)
- M2: ABKC owners DNS sign-off → custom domain cutover → public launch
- M3: Stripe live mode activation (move from sandbox to real payments)
Long-term (deferred per marathon-discipline.md 5-cap)
- L1: Astro Starlight migration to
tutorials.cooperluxurywallcovering.com(B-CLW-TUTORIAL-1) - L2: mmdc Mermaid pre-render (fixes DOCX limitation; B-CLW-TUTORIAL-2)
- L3: Monetization product line (paid tutorials via Gumroad / Maven / Kit; B-CLW-TUTORIAL-3)
- L4: AI assistant embed (in-doc Q&A like Mintlify; B-CLW-TUTORIAL-5)
§14 — Industry Anchors (≥40 hyperlinks, 2026-dated where possible)
Payment + checkout
- PayPal Developer Documentation — canonical
- PayPal Smart Buttons configuration
- PayPal REST API v2 — Orders
- PayPal Sandbox testing guide
- PayPal webhook signature verification
- Stripe Checkout Sessions API
- Stripe testing — test cards
- Stripe Atlas — payment compliance guide
Next.js + Vercel + React
- Next.js 16 App Router
- Next.js Route Handlers
- Next.js Server Actions
- Vercel Deployments dashboard
- Vercel Environment Variables
- Vercel Fluid Compute (default since 2026)
- React 19 release notes
- React server components
Database + auth
- Supabase Postgres docs
- Supabase RLS
- Supabase SSR helpers
- PostgreSQL transaction isolation
- PostgreSQL JSONB indexing
Email + observability
- Resend transactional email API
- Resend domain DKIM setup
- Sentry Next.js integration
- Sentry release tracking
- Upstash Redis REST API
- Twilio Verify API
Standards + compliance
- OWASP API Security Top 10 (2023)
- OWASP Web Security Testing Guide v4.2
- PCI DSS v4.0
- NIST SP 800-115 Technical Guide to Information Security Testing
- ISO/IEC 27001:2022
- WCAG 2.2 (W3C)
- SOC 2 Trust Services Criteria
Tooling
- ShareX screenshot tool (Windows canonical)
- Chrome DevTools Network panel
- Playwright Python
- Mermaid v11 documentation
- Vitest 4 testing framework
- Zod schema validation
- Tailwind CSS v4
- Prism.js syntax highlighting
DCoop internal references
- Tutorial Template v2 spec
- Doc format strategy rule
- Track A privilege envelope
- Generator use-case map
- V4 benchmark walkthrough
- Screenshot capture guide companion
- ABKC owners presentation companion
§15 — Glossary (≥45 terms)
Payment + checkout
| Term | Definition |
|---|---|
| PayPal Smart Buttons | PayPal's official JavaScript SDK component that renders payment buttons (PayPal / Pay Later / Card). Configured via client-id URL param. |
| PayPal Order | A pre-authorized payment transaction in PayPal's Orders API v2. Created via POST /v2/checkout/orders; captured via POST /v2/checkout/orders/:id/capture. |
| Capture flow | The two-step payment pattern: 1) create order (intent), 2) capture order (commit). Industry standard for refund-able transactions. |
| PayPal sandbox | PayPal's test environment at sandbox.paypal.com + api-m.sandbox.paypal.com. Zero real currency; fake buyer + merchant accounts. |
| Sandbox buyer | Test account in PayPal Developer Dashboard used to simulate the customer side of a transaction. Email format: sb-buyer-XXXXX@business.example.com. |
| Stripe Checkout Session | Stripe's hosted-checkout API alternative to PayPal Smart Buttons. Different UX flow but same end-state (paid order). |
| Webhook | An asynchronous HTTP POST sent by PayPal/Stripe to your server when payment state changes (e.g., refund, dispute). HMAC-signed for verification. |
| Idempotency-Key | HTTP header that ensures duplicate requests don't create duplicate orders. Set per-request; PayPal + Stripe both support. |
| PCI DSS | Payment Card Industry Data Security Standard. Because DCoop uses Stripe Checkout (hosted), PCI obligations stay with Stripe — DCoop is out of scope for PCI audits. |
Auth + API
| Term | Definition |
|---|---|
| OAuth 2.1 Basic auth | The HTTP Authorization: Basic <base64> header used to fetch a PayPal access token. Base64-encoded client_id:client_secret. |
| Access token | Short-lived (9-hour TTL) bearer token returned by PayPal OAuth. Used for all subsequent Orders API calls. |
| Bearer token | HTTP Authorization: Bearer <token> header used for internal DCoop API auth (e.g., INTERNAL_API_TOKEN for broker writes). |
| X-API-Key | Custom HTTP header used for broker POST /api/tasks auth. Combined with Bearer for dual-header model (per feedback_broker_auth_header_model.md). |
| REST | Representational State Transfer. The architectural style of PayPal/Stripe/Supabase APIs — verbs (GET/POST/PUT/DELETE) on resource URLs. |
| JSON Schema | The validation format used by Zod (the runtime validator in this codebase). All API request bodies are Zod-validated. |
| HTTP 2xx / 4xx / 5xx | Response status code categories: 2xx success, 4xx client error (validation/auth), 5xx server error (the original bug class). |
Codebase
| Term | Definition |
|---|---|
| Zod | TypeScript-first schema validation library used in all API route handlers. Returns 400 with field-level errors on validation failure. |
| Supabase admin | Server-side Supabase client initialized with SUPABASE_SERVICE_ROLE_KEY (bypasses RLS for trusted server operations). |
| RLS (Row-Level Security) | PostgreSQL feature where row visibility is computed per-user. Supabase enforces RLS for client-side queries; service role bypasses it. |
| Service role key | Admin-tier Supabase API key. Stored in Vercel env as SUPABASE_SERVICE_ROLE_KEY. Never exposed to browser. |
| Anon key | Public Supabase API key (NEXT_PUBLIC_SUPABASE_ANON_KEY). Subject to RLS. Safe to ship to browser. |
| NEXT_PUBLIC_ prefix | Next.js convention — env vars with this prefix are inlined into client bundles at build time. Others stay server-only. |
| Route handler | Next.js 16 App Router server endpoint at src/app/api/<path>/route.ts. Replaces older pages/api/ pattern. |
| Server Action | Next.js 16 alternative to API routes — invokable directly from React Server Components with type-safety. Not used in payment flow (REST simpler). |
Infrastructure
| Term | Definition |
|---|---|
| Vercel Edge Middleware | Lightweight code that runs before any route handler. ABKC uses it for CSP nonce generation + rate limiting. |
| CSP (Content Security Policy) | HTTP header that whitelists which scripts/styles/images the browser may load. Generated per-request via nonce. |
| Nonce | Cryptographically random per-request value embedded in CSP + inline scripts. Allows controlled inline-script execution. |
| Fluid Compute | Vercel's 2026 default function runtime — reuses instances across requests to reduce cold starts. |
| Upstash Redis | Serverless Redis used for rate limiting (per-IP counters) + idempotency-key deduplication. |
| Resend | Transactional email provider used for registration confirmations. Uses DKIM-verified noreply@abkcdogs.com domain. |
| DKIM | DomainKeys Identified Mail — DNS TXT records that prove an email was actually sent by your authorized servers. |
| Sentry | Error tracking. Auto-captures unhandled exceptions in route handlers + flags 5xx responses. |
| Twilio Verify | SMS-based 2FA used for ABKC owner authentication (separate from payment flow). |
Bug class
| Term | Definition |
|---|---|
.trim() |
JavaScript String method that removes leading/trailing whitespace. The defense applied in PR #158 + #159 against Vercel env paste-newline artifacts. |
| Vercel env paste-newline | The bug class where copy-pasting an env var into Vercel's dashboard inadvertently includes a trailing \n. PR #156-#159 chain eliminated this entire class. |
| Idempotent fix | A code change that is safe to apply repeatedly without changing behavior for clean inputs. .trim() is idempotent — trimming an already-trimmed string is a no-op. |
| Defense in depth | Security pattern: apply the same protection at multiple layers (PR #158 at client SDK init + PR #159 at server-side OAuth). |
| Internal Server Error (HTTP 500) | The original symptom Dane saw. Resolved by PR #159 server env trim. Post-fix, the endpoint returns HTTP 400 with clean Zod validation error instead. |
Document conventions
| Term | Definition |
|---|---|
| Tutorial Template v2 spec | The canonical 17-section structure this walkthrough follows. Authored 2026-05-27 in async-rain marathon. |
| Triple Verification Protocol | The L1 (empirical) + L2 (WebSearch 2026) + L3 (vendor docs) verification pattern required by global-truth.md 2026-05-24. |
| Audience Superposition | Single document serving multiple audiences (operator + reviewer + AI consumer) simultaneously through layered language. |
| F100 audience | Fortune 100 CEO + corporate board + PhD-CS engineering + DevOps + security + legal + critical-thinking + strategic-entrepreneurial reviewers (20+ yrs each). |
| 4-format hybrid | .md source-of-truth + .html interactive + .pdf print/sign-off + .docx corporate-share. Per doc-format-strategy.md. |
| Append-only Amendments Log | Convention from archive-policy.md — historical entries never deleted; new versions appended at bottom of each document. |
| Application UUID | The 128-bit identifier assigned to each ABKC registration. Surfaced on the success banner after capture-order completes. Used to query Supabase + reference in Resend confirmation email. Format: f260ad1c-ce32-4688-a426-7909debb0a05. |
| Sign-off page | The §17 attestation block in each procedural walkthrough where the operator signs + dates verification. Per Tutorial Template v2 spec §1.9 procedural-tutorial requirement. |
§16 — Honest Reservations (≥8 numbered)
-
AC6 + AC7 explicitly Dane-gated — Claude (or any AI) cannot drive PayPal sandbox auth from Playwright headless reliably. The third-party SDK popup requires human-driven login. End-to-end currency-moves-through-PayPal verification requires this walkthrough's manual execution. Triage support is automated; the auth click is not. Additionally (empirically verified 2026-05-28 ~23:55 UTC via autonomous Playwright run): the registration form requires the operator to be signed in to their ABKC member account BEFORE clicking Validate. All
/api/registration/*endpoints return HTTP 401 without auth. Step 1.0 documents this as the FIRST prerequisite. -
Mermaid in DOCX renders as raw code —
python-docxcannot embed Mermaid SVG. The DOCX version of this walkthrough shows Mermaid blocks as raw fenced code; the HTML + PDF versions render the actual diagrams. Fix path: mmdc pre-render (B-CLW-TUTORIAL-2 deferred ~8-14h multi-session). -
Screenshots are placeholders until captured — All
references are intentional placeholders. PNG files don't yet exist. Dane captures via ShareX during walkthrough execution + uploads to thescreenshots/subdirs. See SCREENSHOT-CAPTURE-GUIDE-PAYMENT-2026-05-28.md for the per-screen filename convention. -
Production custom domain DNS-gated —
www.abkcdogs.comstill serves the legacy static site; cutover is gated on the ABKC ownership sign-off block (Owners Presentation §9). Walkthrough URLs useabkc-website.vercel.appuntil then. After cutover, find/replaceabkc-website.vercel.app→www.abkcdogs.comin the master MD + regenerate the 4-format trio. (The originating 2026-05-23 dispatch-matrix link from V1 was retired — that file is archived per the estate 7-day rule.) -
Vercel env hygiene path is deferred — PR #159's
.trim()defends against paste-whitespace artifacts in env values, but doesn't CLEAN the values themselves. Optional follow-up:vercel env rm PAYPAL_CLIENT_ID production→vercel env addwith clean paste. Non-blocking; code defense covers it. -
Resend confirmation email is gated on Resend env health — If
RESEND_API_KEYhas its own whitespace artifact, the email won't send even thoughpayment_status='paid'on the Supabase row. PR #159 trimmed RESEND_API_KEY too (defense in depth), but if Resend dashboard shows delivery failures, that's a separate triage path. -
Class A subagent dispatch context — Per
~/.claude/rules/context-window-discipline.md2026-05-24 amendment, Class A Explore subagents have been failing 14+ consecutive marathons. This walkthrough was authored via parent-context reads + WebSearch (not subagent fan-out). The walkthrough quality is unaffected; mentioned for F100 reviewer transparency about authoring methodology. -
Co-owner workflow scope not yet covered — Dual-owner (Dane + James) registration + signature workflow is queued as
ABKC-PAYMENT-WALKTHROUGH-CO-OWNER-V1-2026-05-28.md. Trigger: Dane validates THIS single-owner walkthrough end-to-end. Co-owner walkthrough applies same v2 spec; ~3-4h Claude authoring. -
Form-by-form coverage register (B-ABKC-FORM-N) deferred — Litter, show-entry, membership, transfer, title-application all need their own walkthroughs (single-owner + co-owner variants where applicable). Per
marathon-discipline.md5-cap discipline, surfaced as Backlog items B-ABKC-FORM-1 through B-ABKC-FORM-5. Total deferred wall ~30-50h across 5 follow-up multi-phase plans. -
No load test in scope — Walkthrough validates ONE end-to-end happy-path transaction. Stress / load / concurrent-user testing is separate scope. PayPal sandbox has rate limits documented at developer.paypal.com; production deployment may need k6 or Artillery load testing before public launch (M2 deferred above).
-
Tier 3 Track A privilege envelope intact — Per
~/.claude/rules/track-a-privilege-envelope.md2026-05-25 corrected 3-tier framing: zero reads/writes insidematters/us-v-andrade-25-147-LOPEZorlopez-matter/**during walkthrough authoring or execution. This walkthrough handles only ABKC business workflow (Tier 2 Workable for cooper-v-seniormaticseast-civil is also unchanged by this scope; no legal matter content touched).
§17 — Sign-off Page (Operator Attestation)
I, the undersigned operator, attest that I executed this walkthrough on the date below and observed the outcomes as documented. Failures (if any) are captured in the comments section.
Per-step verification
| Step | Expected outcome | Observed | Notes |
|---|---|---|---|
| 1.1 | Chrome opened (not incognito) | ☐ Pass / ☐ Fail | |
| 1.2 | Sandbox creds fetched | ☐ Pass / ☐ Fail | |
| 1.3 | DevTools open, Preserve log checked | ☐ Pass / ☐ Fail | |
| 2.1 | /register/dog page loaded | ☐ Pass / ☐ Fail | |
| 2.2 | PayPal Smart Button rendered (3 funding sources) | ☐ Pass / ☐ Fail | |
| 2.3 | Form filled with sandbox data | ☐ Pass / ☐ Fail | |
| 2.4 | No validation errors | ☐ Pass / ☐ Fail | |
| 3.1 | PayPal button clicked | ☐ Pass / ☐ Fail | |
| 3.2 | /create-order returned HTTP 200 + orderId | ☐ Pass / ☐ Fail | |
| 3.3 | Popup opened to sandbox.paypal.com | ☐ Pass / ☐ Fail | |
| 3.4 | Sandbox login completed | ☐ Pass / ☐ Fail | |
| 3.5 | "Pay Now" clicked + popup closed | ☐ Pass / ☐ Fail | |
| 3.6 | /capture-order returned HTTP 200 + COMPLETED | ☐ Pass / ☐ Fail | |
| 3.7 | Success message + UUID shown on main page | ☐ Pass / ☐ Fail | |
| 3.8 | Confirmation email arrived within 60s | ☐ Pass / ☐ Fail | |
| 3.9 | Supabase row shows payment_status='paid' | ☐ Pass / ☐ Fail |
Overall verdict
- ☐ PASS — All 16 steps green. End-to-end payment flow verified. AC6 + AC7 satisfied. Ready to ship to ABKC owners.
- ☐ PARTIAL — Some steps failed; document below. Re-run after triage.
- ☐ FAIL — Critical step failed; document below. Block ship to ABKC owners until resolved.
Failure notes (if any)
Failed step: _____________________________________
HTTP status code: _____________________________________
Response body: _____________________________________
Console errors: _____________________________________
Screenshots: _____________________________________
Triage performed: _____________________________________
Attestation
Operator name: ____________________________________
Date / Time: ____________________________________
Signature: ____________________________________
(if printed)
Email of record: ____________________________________
✅ SUCCESS: Once signed + attached to the ABKC owners presentation, this walkthrough constitutes the empirical evidence package for ABKC payment infrastructure end-to-end verification. Combined with the Owners Presentation, this is the package ABKC owners review before DNS sign-off.
§A — Amendments Log (append-only per ~/.claude/rules/archive-policy.md)
- 2026-05-28 ~01:30 UTC — V1 authored at crystalline-coral v2 Phase E. Applies Tutorial Template v2 spec (17 sections + 4 Mermaid + ≥40 hyperlinks + ≥45 glossary + ≥20 screenshot placeholders + 11 honest reservations + sign-off). Supersedes basic
dane-validation-paypal-2026-05-28.md(137 LOC; preserved per archive-policy.md). Author: Claude Opus 4.7 (1M ctx). - 2026-06-09 — V2 delta refresh (V1 files preserved unchanged). Procedure + $62.00 flow untouched. Changes: version header + 2026-06-09 audience-standard additions (QA / PCI-DSS / COPPA+PII / WCAG 2.2 / SRE); NEW "Status delta" table under §0 (tiered cross-browser gate #175, Jira↔GitHub sync #177,
/loginWebKit fix PR #178 ready with 3/3 green verification runs, walkthrough family expanded with Co-Owner V1 + Office-Manager V1); co-owner cross-reference repointed to the now-authoredABKC-PAYMENT-WALKTHROUGH-CO-OWNER-V1-2026-06-09.md; three stalecosmic-pondering-lynxdispatch-matrix links retired (file archived per 7-day rule) → live gate repointed to Owners Presentation §9; repaired the two V1 Mermaid diagrams that had never rendered (§3 architecture: four node labels beginning with/were parsed as unclosed trapezoid shapes → now quoted; §6 Gantt: a task name beginning with the reserved wordClickkilled the parse → renamed "Press…") — found by the V2 render smoke-probe; V1 preserved as-is, defect and all. Author: Claude Fable 5 (plan~/.claude/plans/autonomous-loop-check-sparkling-tome.md). Per~/.claude/rules/archive-policy.md: append-only. - 2026-05-28 ~23:43 UTC — V1 amendment per autonomous Playwright walkthrough run during crystalline-coral v2 user-directed "extract zip + run walkthrough" execution. Empirical finding: the registration page is a two-stage flow with a "Validate & Prepare for Payment" button as the bridge between form-fill and PayPal-SDK render. Walkthrough updated: Step 2.2 reframed as form-structure-survey; new Step 2.7 (click Validate) + Step 2.8 (verify PayPal renders post-validation) inserted between form-completion and PayPal-click. Total: 28 screenshot placeholders + 21 sections (was 20 + 19). Per
~/.claude/rules/archive-policy.md: append-only. Author: Claude Opus 4.7 (1M ctx). - 2026-05-28 ~23:58 UTC — V1 second amendment per autonomous form-fill + Validate-click run during user-directed "automate the form fill and click validate" execution. CRITICAL empirical finding: the registration form requires authenticated ABKC member session. All 6 API calls during the autonomous run returned HTTP 401 (
/my-drafts,/my-co-owners,/search-dogs). Without auth, the Validate click runs but draft save silently fails + PayPal SDK never initializes (iframes:0 / zoid_count:0). Walkthrough updated: new Step 1.0 — Sign in to ABKC member account added at the top of Gate 1 as REQUIRED prerequisite; §16 honest reservation #1 amended; HANDOFF-TO-JAMES.md clarifies James does NOT need his own ABKC account (added as co-owner via form fields). 29 screenshot placeholders. Per~/.claude/rules/archive-policy.md: append-only. Author: Claude Opus 4.7 (1M ctx).
End of walkthrough.