Skip to main content

Stripe Post-Cloud Validation Runbook

Status: Requires Cloud Deploy + Live Credentials Audience: Operators Priority: P0

Objective​

Revalidate the Stripe package against the production cloud endpoint with live Stripe credentials. This is the final validation step before Stripe's live_e2e_status can move from cloud_gated to live_validated.

Prerequisites​

  • ✅ Public cloud endpoint deployed (control plane reachable)
  • ✅ Stripe test/live account with webhook event generation capability
  • ✅ Stripe webhook signing secret (whsec_...)
  • ✅ Stripe API key (test mode: sk_test_...)
  • ✅ Cloud endpoint registered as Stripe webhook endpoint
  • ✅ stripe CLI installed (for event triggering, optional — manual HTTP also works)
  • ❌ No live credentials in docs or generated evidence artifacts

Validation Sequence​

1. Positive Test — Send Real Webhook Event via Stripe API​

Trigger a Stripe event and verify it reaches the cloud endpoint:

# Trigger a test event (requires stripe CLI)
stripe trigger payment_intent.succeeded

Expected: Stripe delivers the webhook to the cloud endpoint.

2. Positive Test — Verify Delivery via Platform API​

Verify the webhook appears in platform delivery logs:

curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries?provider=stripe&limit=1 | jq .

Checks:

  • ✅ Delivery recorded with status: delivered
  • ✅ Event type matches the triggered event
  • ✅ Timestamp is recent (within 60s of trigger)

3. Signature Validation — Verify Stripe-Signature Header​

Confirm the platform validated the Stripe HMAC signature:

# Retrieve the raw webhook headers from delivery evidence
curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries/${DELIVERY_ID}/evidence | jq '.headers["Stripe-Signature"]'

Manually verify the signature using the signing secret:

# Using the platform's evidence output
zen package verify-signature stripe \
--payload payload.json \
--signature-header "$STRIPE_SIGNATURE" \
--secret "$STRIPE_WHSEC"

Checks:

  • ✅ Stripe-Signature header is present
  • ✅ Signature verification returns valid: true
  • ✅ t= timestamp is within acceptable skew (≤ 5 minutes)

4. Negative Test — Invalid HMAC Signature​

Send a modified payload to confirm rejection:

# Send a request with tampered payload
curl -X POST https://api.zen-mesh.io/v1/webhooks/stripe \
-H "Stripe-Signature: t=1719184800,v1=invalidsignature" \
-H "Content-Type: application/json" \
-d '{"id": "evt_bad", "object": "event", "type": "payment_intent.succeeded"}'

Checks:

  • ✅ Response status is 401 or 403
  • ✅ Error body indicates signature_verification_failed
  • ❌ No delivery recorded for the rejected event

5. Negative Test — Unknown Event Type​

Send a well-signed event with an unsupported type:

# Generate valid signature for custom event
TIMESTAMP=$(date +%s)
PAYLOAD='{"id":"evt_custom","object":"event","type":"charge.captured"}'
SIGNED=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$STRIPE_WHSEC" | awk '{print $2}')
curl -X POST https://api.zen-mesh.io/v1/webhooks/stripe \
-H "Stripe-Signature: t=$TIMESTAMP,v1=$SIGNED" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"

Checks:

  • ❌ Delivery may be accepted or rejected depending on platform routing policy
  • ✅ If accepted, event type recorded as unmapped
  • ✅ No delivery to unsupported target

6. Negative Test — Missing Stripe-Signature Header​

Send a well-formed payload without the signature header:

curl -X POST https://api.zen-mesh.io/v1/webhooks/stripe \
-H "Content-Type: application/json" \
-d '{"id": "evt_nosig", "object": "event", "type": "payment_intent.succeeded"}'

Checks:

  • ✅ Response status is 401
  • ✅ Error body indicates missing_signature_header

7. Evidence Capture​

Capture all validation evidence:

# Create evidence directory
mkdir -p docs/80-EVIDENCE/public-docs/stripe-post-cloud-$(date +%Y%m%d)

# Capture delivery logs
curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries?provider=stripe > \
docs/80-EVIDENCE/public-docs/stripe-post-cloud-$(date +%Y%m%d)/delivery-log.json

# Capture validation results
zen package evidence stripe --output=json > \
docs/80-EVIDENCE/public-docs/stripe-post-cloud-$(date +%Y%m%d)/validation-evidence.json

# Generate summary
cat > docs/80-EVIDENCE/public-docs/stripe-post-cloud-$(date +%Y%m%d)/README.md << 'SUMMARY'
# Stripe Post-Cloud Validation

Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
Validator: $(whoami)
Cloud Endpoint: <endpoint-url>
Stripe Account: <test/live indicator>
Results: <PASS / FAIL>
SUMMARY

Evidence artifacts:

  • Delivery log showing received events and status
  • Signature verification results (positive and negative)
  • Screenshot or API response showing rejected invalid-signature event
  • Summary document with pass/fail per test

Exit Codes​

CodeMeaning
0All tests pass — validation success
1One or more positive tests fail
2One or more negative tests fail (missing rejection)
3Signature verification fails
4Evidence capture fails
5Credential or access error

Validation Success Criteria​

Validation passes when ALL of the following are true:

  • ✅ Stripe webhook event received and delivered (positive test)
  • ✅ Stripe-Signature header present and verified by platform
  • ✅ Manual signature re-verification matches platform result
  • ✅ Invalid signature events are rejected with 401/403
  • ✅ Missing signature header events are rejected
  • ✅ Evidence is captured and stored
  • ❌ No live credentials appear in evidence artifacts
  • ❌ No claim of "live validated" or "GA" in evidence output

Troubleshooting​

Signature Verification Fails​

  • Clock skew: Ensure platform and Stripe timestamps are within 5 minutes
  • Wrong secret: Verify whsec_... secret matches the endpoint in Stripe Dashboard
  • Payload encoding: Stripe signs the raw JSON body; verify exact payload bytes match what was signed

Delivery Not Received​

  • Webhook endpoint not configured: Verify Stripe Dashboard webhook endpoint URL points to the cloud endpoint
  • Secret not matching: Re-check webhook signing secret in Dashboard
  • Network/firewall: Confirm cloud endpoint is publicly reachable

Evidence Capture Fails​

  • Platform token expired: Re-authenticate with platform
  • API endpoint not reachable: Verify cloud endpoint is up
  • Provider not configured: Check provider is enabled in cloud deployment