Skip to main content
PlatformPaymentsShipped

clawql-payments

Status: Shipped foundation (July 2026)
Package: packages/clawql-payments
CLI: clawql payments *

clawql-payments is ClawQL's unified payments layer for human fiat and agent micropayments.

Positioning: ClawQL is the only MCP gateway that speaks three agentic payment rails nativelyStripe (subscriptions, invoices, meters, SPT), x402 (per-request USDC), and MPP / Machine Payments Protocol (session-based streaming micropayments with Stripe's compliance stack, optional Tempo via mppx) — with a WORM-audited payment event trail. Additional agent protocols (AP2, ACP) and processors (PayPal, Adyen) are on the roadmap below; docs-site .well-known stubs are discovery-only until those adapters ship.

It powers ClawQL's own managed tiers (Free / Pro / Team / Enterprise) and is available to self-hosted operators and ClawQL users who want to bill their own customers.

What ships today

CapabilityStatusNotes
Managed plan tiers + entitlementsLocal usage.json counters; limit enforcement in inference
Stripe customers, subscriptions, invoicesLive SDK when STRIPE_SECRET_KEY is set
Stripe webhook signature verificationCLI verify/process; audit on invoice.paid
Stripe Billing Meters (meterEvents.create)API + inference hook when CLAWQL_PAYMENTS_REPORT_STRIPE_METER=1
x402 gate config + facilitator HTTP verifyPOST /verify against x402.org or CDP
x402 Express middleware (402 + PAYMENT-REQUIRED)Wired into clawql-inference HTTP
x402 MCP in-process enforcementCLAWQL_X402_ENFORCE=1 on stdio / Streamable HTTP / gRPC MCP tool calls
Payment WORM audit (hash-chained JSONL)$CLAWQL_HOME/Payments/audit.jsonl + audit verify
Payment WORM audit (Postgres)CLAWQL_PAYMENTS_AUDIT_STORE=postgres for multi-node deployments
Payment audit → Loki/SIEM exportFire-and-forget push on append when CLAWQL_LOKI_PUSH_URL is set
.well-known/payments.json discoveryDynamic on MCP + inference HTTP; static route on docs site
MPP /openapi.json discoveryDynamic on MCP + inference HTTP; canonical x-payment-info.offers[]
MPP HTTP 402 + MCP -32042 runtimeDual x402 + MPP challenges when CLAWQL_MPP_ENABLED=1
MPP credential verification + receiptsMppVerificationService — x402 facilitator + Stripe SPT (STRIPE_PROFILE_ID)
MPP optional mppx adapterMppxAdapterService when CLAWQL_MPPX_ENABLED=1 + optional mppx dep
MCP JSON-RPC payment errors-32042/-32043 when CLAWQL_MPP_MCP_JSONRPC=1 (default: tool-result _meta)
Extended finance provider adverts in offers[]CLAWQL_MPP_FINANCE_PROVIDERSdiscovery labels only, not live adapters

Roadmap (not shipped)

Complementary 2026 agentic protocols and processors — build in this order:

TierItemRoleNotes
1AP2 (Google / FIDO)Cryptographic payment mandates (Intent / Cart / Payment as VCs)Authorization + non-repudiation layer under MCP/A2A; bridges to existing x402 via A2A x402 extension
1ACP (OpenAI / Stripe)Merchant-side conversational checkoutChatGPT Instant Checkout–style flows; Stripe SharedPaymentToken
1PayPal direct adapterHuman-facing wallet checkoutTable-stakes conversion for consumer wallets; distinct from AP2's PayPal settlement partner path
2Adyen direct adapterEnterprise billingWhen Dedicated/Enterprise customers need native Adyen (also an AP2 partner for agentic settlement)
3Mollie / RazorpayRegional processorsAdd when regional traction requires them

Already covered (do not duplicate): Shopify Payments (Stripe-powered), ACH Direct Debit via Stripe's APIs, card/subscription/invoice flows via Stripe. Not planned: Zelle (no merchant API), Square POS-first adapters.

Docs-site ACP / UCP / AP2 .well-known documents are scanner-facing stubs. Live settlement today is Stripe + x402 + MPP on self-hosted clawql-payments.

Architecture

clawql-payments
├── stripe/     Subscriptions, invoices, webhooks, Billing Meters, SPT
├── x402/       Wallet, gates, facilitator verify/settle, middleware
├── mpp/        OpenAPI discovery, Payment 402 challenges, verification, mppx
├── plans/      Tier definitions, entitlements, usage.json counters
├── audit/      Hash-chained append-only JSONL + integrity verify
└── cli/        clawql payments * implementations

Three usage systems (do not conflate)

ClawQL tracks usage in three independent layers. Each serves a different purpose:

LayerStoragePurposeEnv / toggle
Plan entitlements$CLAWQL_HOME/Payments/usage.jsonManaged tier caps (inference calls/mo, docs, memory)CLAWQL_PAYMENTS_ENFORCE_INFERENCE=1
Inference call storejsonl / postgres under $CLAWQL_HOME/Inference/Token counts, latency, export/finetune flywheelCLAWQL_INFERENCE_STORE
Virtual key budgets$CLAWQL_HOME/Inference/virtual-keys.jsonPer-team USD budget + rate limitsCLAWQL_INFERENCE_KEYS_ENABLED=1

Plan usage drives quota enforcement and optional Stripe Billing Meters. The call store drives observability and training data. Virtual keys drive per-team spend caps at auth time.


Local configuration

All local state lives under $CLAWQL_HOME/Payments/ (default ~/.clawql/Payments/):

FileContents
payments.jsonTenant id, plan tier, Stripe metadata, x402 wallet/facilitator
x402-gates.jsonPayment-gated HTTP paths and MCP tool names
usage.jsonMonthly counters per tenant (inference_calls, documents, memory_mb)
audit.jsonlAppend-only hash-chained payment audit log
audit.meta.jsonChain head (seq, last_hash) for fast append

Example payments.json:

{
  "tenantId": "acme-prod",
  "plan": "team",
  "stripe": {
    "accountId": "acct_xxx",
    "customerId": "cus_xxx",
    "meterEventName": "clawql_inference_calls",
    "webhookSecret": "whsec_..."
  },
  "x402": {
    "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
    "facilitatorUrl": "https://x402.org/facilitator",
    "defaultAsset": "USDC"
  }
}

File modes are 0600. Never commit secrets or webhook signing keys.


Managed plan tiers

Defined in packages/clawql-payments/src/plans/tiers.ts:

PlanInference calls/moDocuments/moMemory (MB)Seatsx402
free100101001off
pro10,0005005,0001on
team100,0005,00050,00020on
enterpriseunlimitedunlimitedunlimitedunlimitedon
clawql payments plan show
clawql payments plan upgrade --tier team
clawql payments usage report --month 2026-07

Inference entitlement enforcement

When CLAWQL_PAYMENTS_ENFORCE_INFERENCE=1, every successful inference call:

  1. Pre-checkcheckEntitlementLimit() against usage.json for the resolved tenant
  2. Execute — gateway completes the request
  3. Post-record — increment inference_calls in usage.json
  4. Optional Stripe meter — when CLAWQL_PAYMENTS_REPORT_STRIPE_METER=1, emit billing.meterEvents.create

Over-limit tenants receive 402 insufficient_quota (OpenAI-compatible error shape).

Tenant resolution order:

  1. InferenceRequest.tenantId
  2. Virtual key team header
  3. payments.jsontenantId
  4. "default"

Implementation: packages/clawql-inference/src/entitlements/.


Stripe billing

Prerequisites

  1. Stripe account with Billing Meters configured in the Dashboard
  2. Meter event name matching STRIPE_METER_EVENT_NAME or payments.jsonstripe.meterEventName
  3. Customer linked via clawql payments stripe customer create (persists customerId) or STRIPE_CUSTOMER_ID

Environment variables

VariableRequiredPurpose
STRIPE_SECRET_KEYYes (live API)Stripe SDK authentication
STRIPE_PRO_PRICE_IDFor Pro subsFlat subscription price id
STRIPE_TEAM_PRICE_IDFor Team subsFlat subscription price id
STRIPE_CUSTOMER_IDMeter reportingOverride when not in payments.json
STRIPE_METER_EVENT_NAMEMeter reportingDashboard meter event name (e.g. clawql_inference_calls)
CLAWQL_PAYMENTS_REPORT_STRIPE_METERMeter reportingSet to 1 to emit meter events after each inference call

Setup flow

export STRIPE_SECRET_KEY=sk_test_...
export STRIPE_PRO_PRICE_ID=price_...
export STRIPE_TEAM_PRICE_ID=price_...
export STRIPE_METER_EVENT_NAME=clawql_inference_calls

# 1. Store webhook secret locally (never commit)
clawql payments stripe setup --webhook-secret whsec_...

# 2. Create customer (persists customerId to payments.json)
clawql payments stripe customer create --email billing@acme.com --name "Acme Inc"

# 3. Create subscription for flat tier fee
clawql payments stripe subscription create --customer cus_xxx --plan pro

# 4. Enable meter reporting on inference
export CLAWQL_PAYMENTS_REPORT_STRIPE_METER=1
export CLAWQL_PAYMENTS_ENFORCE_INFERENCE=1
clawql inference serve --port 8080

Meter event idempotency

Each meter event includes an identifier for Stripe-side deduplication:

  • With correlation id: inference:\{tenantId\}:\{correlationId\}
  • Without: inference:\{tenantId\}:\{timestamp_ms\}

Replaying the same correlation id within Stripe's dedup window will not double-bill.

Manual meter report (debug / backfill)

clawql payments stripe meter report --value 1 --customer cus_xxx \
  --event-name clawql_inference_calls \
  --identifier inference:default:manual-test-001

Webhooks

Webhook verification is CLI-first today — suitable for sidecar processors and CI:

clawql payments stripe webhook verify \
  --payload ./event.json \
  --signature "t=...,v1=..." \
  --process

Verified invoice.paid events append STRIPE_INVOICE_PAID to the payment WORM. Invoice creation alone does not write audit entries.

Supported handlers: packages/clawql-payments/src/stripe/webhook.ts.


x402 micropayments

x402 v2 enables pay-per-request access to HTTP routes and MCP tools using USDC on EVM chains. ClawQL integrates facilitator-based verification — clients send a signed payment payload; the server verifies via POST /verify before allowing the request.

When to use x402 vs plan entitlements

ModelBest for
Plan entitlementsManaged SaaS tiers with monthly caps
x402 gatesPay-per-call APIs, public endpoints, agent-to-agent micropayments
BothHybrid: subscription base + overage per call on specific routes

They are independent toggles. A route can be x402-gated without plan enforcement, and vice versa.

Environment variables

VariableDefaultPurpose
CLAWQL_X402_ENFORCEoffEnable middleware (402 until paid)
CLAWQL_X402_FACILITATOR_URLhttps://x402.org/facilitatorFacilitator base URL
CLAWQL_X402_NETWORKeip155:84532CAIP-2 chain id (Base Sepolia testnet)
CLAWQL_X402_USDC_ASSETBase Sepolia USDCToken contract address
CLAWQL_X402_SCHEMEexactPayment scheme (exact or upto)
CLAWQL_X402_MAX_TIMEOUT_SECONDS60Payment validity window
CLAWQL_X402_FACILITATOR_BEARERBearer token for CDP / private facilitators
CDP_API_KEY_ID + CDP_API_KEY_SECRETCoinbase Developer Platform auth alternative

Wallet and facilitator URL can also be stored in payments.jsonx402.

Setup flow

export CLAWQL_X402_ENFORCE=1
export CLAWQL_X402_FACILITATOR_URL=https://x402.org/facilitator

# 1. Configure pay-to wallet
clawql payments x402 wallet setup --address 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb

# 2. Gate a route or MCP tool
clawql payments x402 gate --resource /v1/chat/completions --price 0.001 --asset USDC
clawql payments x402 gate --tool knowledge_search --price 0.0005

# 3. Start inference with middleware
clawql inference serve --port 8080

HTTP request flow

Headers:

HeaderDirectionPurpose
PAYMENT-REQUIREDResponse (402)Base64-encoded PaymentRequired JSON
PAYMENT-SIGNATURE / X-PAYMENTRequestClient payment proof (JSON or base64)
X-Clawql-ToolRequestGate MCP tools as tool:\{name\} (HTTP middleware path)
X-Correlation-IdRequestAudit correlation (optional)

MCP in-process enforcement

When CLAWQL_X402_ENFORCE=1, native MCP tool calls (tools/call over stdio, Streamable HTTP /mcp, or gRPC session transport) run the same enforceX402Gate() path as inference HTTP middleware — before the tool handler executes.

Enforcement is registered as PaymentsX402ProxyPlugin (kind: mcp-proxy) on the shared McpProxyPipeline alongside Panguard — all MCP tools pass through wrapRegisteredMcpToolHandlerrunMcpProxyBeforeCallTool. Disable the plugin with CLAWQL_PAYMENTS_X402_PROXY_PLUGIN=0 (rare; prefer turning off CLAWQL_X402_ENFORCE).

Effect entrypoints: paymentsServicesLiveLayer() merges all services; runPaymentsEffect() runs programs at async boundaries (CLI, Express, legacy exports). MCP x402 uses native mcpX402BeforeCallToolEffectX402EnforcementService (not a tryPromise shim).

Effect services (clawql-payments/plugin):

ServiceResponsibility
PaymentsConfigServicepayments.json load/save/merge
PaymentAuditServiceWORM audit append/list/verify (+ ring buffer + Loki side effects)
X402GateServicex402-gates.json CRUD
X402RuntimeConfigServiceNetwork, facilitator, wallet from config + env
X402FacilitatorServiceFacilitator verify/settle HTTP
X402EnforcementServiceGate enforcement + settlement reconciliation
UsageStoreServiceMonthly usage counters
EntitlementServicePlan limit checks (EntitlementLimitError)
PaymentsDiscoveryService/.well-known/payments.json builder
MppOpenApiServiceMPP /openapi.json builder (x-payment-info.offers[])
MppVerificationServiceMPP credential verify (x402 + Stripe SPT), challenge registry, receipts
StripeClientServiceStripe SDK client lifecycle
StripeWebhookServiceWebhook verify + WORM-audited event handling
StripeMeterServiceMeter events + inference usage reporting
StripeBillingServiceSetup, customer, subscription, invoice, portal

Public async exports (loadPaymentsConfig, enforceX402Gate, appendPaymentWormEntry, …) delegate to runPaymentsEffect. Stripe modules now use Effect services (StripeClientService, StripeWebhookService, StripeMeterService, StripeBillingService) with tagged errors (StripeSignatureError, StripeApiError, …); legacy Error subclasses remain at async boundaries for CLI compatibility.

Configure gates with clawql payments x402 gate --tool <name> --price <usdc>.

Payment proof on MCP transports:

TransportHow to attach proof
Streamable HTTPPAYMENT-SIGNATURE / X-PAYMENT on the HTTP request to /mcp
gRPC MCP sessionSame header names as gRPC metadata (lowercase keys)
stdioNo request headers — use Streamable HTTP or gRPC for paid tools

When payment is required, the tool returns an MCP result with isError: true and JSON describing the x402 PaymentRequired payload (HTTP 402 semantics in tool output). Invalid proofs emit X402_PAYMENT_FAILED audit events (same as HTTP deny paths).

402 response body (x402 v2):

{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "http://localhost:8080/v1/chat/completions",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "1000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
      "maxTimeoutSeconds": 60
    }
  ],
  "extensions": { "facilitator": "https://x402.org/facilitator" }
}

Amounts are USDC atomic units (6 decimals): 0.001 USDC"1000".

CLI reference

clawql payments x402 wallet setup --address 0x...
clawql payments x402 gate --resource /v1/chat/completions --price 0.001
clawql payments x402 gate --tool knowledge_search --price 0.0005
clawql payments x402 gate list
clawql payments x402 verify --payload ./payment.json --resource /v1/chat/completions
clawql payments x402 reconcile --date 2026-07-11

verify calls the configured facilitator with a saved payload — useful for debugging client integrations without running the full HTTP server.

Programmatic usage

import {
  createX402Gate,
  createX402PaymentMiddleware,
  enforceX402Gate,
  verifyViaFacilitator,
} from 'clawql-payments/x402'

Middleware mounts before auth in packages/clawql-inference/src/api/server.ts.


Payment audit (WORM)

Payment events append to an append-only, hash-chained audit log at $CLAWQL_HOME/Payments/audit.jsonl. Each record includes seq, prev_hash, and hash (SHA-256 over canonical JSON) so tampering breaks the chain. By default each append fsyncs to disk (CLAWQL_PAYMENTS_AUDIT_FSYNC=1).

A hot in-process mirror still feeds the MCP audit ring buffer (summary fields only). Authoritative payment history — including full structured payload — lives in audit.jsonl.

EventTrigger
STRIPE_INVOICE_PAIDVerified webhook
STRIPE_PAYMENT_FAILEDVerified webhook
STRIPE_METER_REPORTEDSuccessful meter event
X402_PAYMENT_RECEIVEDFacilitator verify + reconcile
X402_PAYMENT_FAILEDInvalid proof, facilitator error, or misconfiguration (not require_payment)
ENTITLEMENT_LIMIT_REACHEDPlan cap hit
PLAN_UPGRADED / PLAN_DOWNGRADEDclawql payments plan upgrade

Environment

VariableDefaultPurpose
CLAWQL_PAYMENTS_AUDIT_STOREjsonl (memory in tests)jsonl = durable file; memory = in-process only; postgres = shared DB
CLAWQL_PAYMENTS_AUDIT_FSYNConfsync after each append (set 0 to disable; jsonl only)
CLAWQL_PAYMENTS_DATABASE_URLPostgres connection string when AUDIT_STORE=postgres
CLAWQL_PAYMENTS_DB_*Component vars (HOST, USER, PASSWORD, NAME, PORT)
CLAWQL_INFERENCE_DATABASE_URLFallback Postgres URL when payments URL is unset (shared DB)

Postgres audit store (enterprise)

For multi-node ClawQL deployments, set:

export CLAWQL_PAYMENTS_AUDIT_STORE=postgres
export CLAWQL_PAYMENTS_DATABASE_URL=postgres://clawql:secret@db.internal:5432/clawql
# Or reuse the inference database:
# export CLAWQL_INFERENCE_DATABASE_URL=postgres://...

Records remain hash-chained (seq, prev_hash, hash) in table clawql_payments_audit. Chain head metadata lives in clawql_payments_audit_meta. clawql payments audit verify validates integrity regardless of store backend.

Loki / SIEM export

Each successful append can push the full payment payload (not just MCP ring-buffer summaries) to Grafana Loki:

export CLAWQL_LOKI_PUSH_URL=https://loki.example.com/loki/api/v1/push
export CLAWQL_LOKI_BEARER_TOKEN=...          # optional
export CLAWQL_LOKI_TENANT_ID=tenant-1        # optional X-Scope-OrgID
export CLAWQL_PAYMENTS_LOKI_JOB=clawql-payments-audit  # optional stream job label
# export CLAWQL_PAYMENTS_LOKI_PUSH=0         # disable payments push only
# export CLAWQL_ENABLE_LOKI_PUSH=0           # disable all Loki push (MCP + payments)

Push is fire-and-forget — Loki failures log to stderr and do not fail payment processing.

Payment discovery (/.well-known/payments.json)

Self-hosted ClawQL serves a dynamic payment discovery document at:

curl http://localhost:8080/.well-known/payments.json   # MCP HTTP (default PORT)
curl http://localhost:8080/.well-known/payments.json   # inference HTTP (CLAWQL_INFERENCE_PORT)

The document lists configured x402 gates (HTTP paths and MCP tools), wallet/facilitator metadata, and Stripe plan/meter info when configured. The docs site serves a static commerce discovery route at /openapi.json and /.well-known/payments.json for agent readiness scanners.

MPP discovery (/openapi.json)

Self-hosted ClawQL serves a dynamic MPP OpenAPI document at:

curl http://localhost:8080/openapi.json   # MCP HTTP or inference HTTP

Each paid route includes x-payment-info.offers[] with x402 and stripe methods when configured. Set CLAWQL_MPP_OPENAPI=0 to disable the route. See MPP discovery.

When CLAWQL_X402_ENFORCE=1, HTTP 402 responses include both x402 PAYMENT-REQUIRED and MPP WWW-Authenticate: Payment challenges. MCP paid-tool errors surface MPP metadata on tool results (org.paymentauth/payment-required) for clients that expect JSON-RPC -32042.

Credential verification runs through MppVerificationService (Effect) inside X402EnforcementService.enforceGate():

  • Authorization: Payment … — canonical MPP credentials (Stripe SPT or x402 payload in payload)
  • PAYMENT-SIGNATURE — legacy x402 credentials (still verified when MPP is enabled)
  • Successful verification returns Payment-Receipt on HTTP 200 and records settlement in the payment audit WORM
  • Stripe SPT charges require STRIPE_SECRET_KEY and optionally STRIPE_PROFILE_ID / STRIPE_NETWORK_ID for Business Network profiles

Challenge IDs issued on 402 are registered for single-use verification (replay protection). Failed verification surfaces MCP -32043 metadata on deny paths when applicable.

CLI

clawql payments audit --correlation-id seed_abc_gen_2
clawql payments audit verify          # validate hash chain integrity
clawql payments audit verify --json
clawql payments spend report --group-by provider

spend report now aggregates real amount_usd / amount_usdc values from persisted payloads (not placeholder data).

Programmatic verify

import { verifyPaymentAuditLog } from 'clawql-payments'

const result = await verifyPaymentAuditLog()
if (!result.ok) {
  console.error(result.issues)
}

Full CLI reference

# Plans
clawql payments plan show | upgrade --tier team
clawql payments usage report --month 2026-07

# Stripe
clawql payments stripe setup --webhook-secret whsec_...
clawql payments stripe customer create --email user@acme.com
clawql payments stripe subscription create --customer cus_xxx --plan pro
clawql payments stripe invoice create --customer cus_xxx --amount 500
clawql payments stripe meter report --value 1 --customer cus_xxx
clawql payments stripe webhook verify --payload ./event.json --signature "..." --process

# x402
clawql payments x402 wallet setup | gate | gate list | verify | reconcile

# Audit
clawql payments spend report --group-by provider
clawql payments audit --correlation-id xxx
clawql payments audit verify

Inference integration checklist

Self-hosted operators enabling the full payments stack:

# Plan limits
export CLAWQL_PAYMENTS_ENFORCE_INFERENCE=1

# Stripe meter (optional — requires Dashboard meter + customer)
export CLAWQL_PAYMENTS_REPORT_STRIPE_METER=1
export STRIPE_METER_EVENT_NAME=clawql_inference_calls

# x402 pay-per-call (optional — independent of plan limits)
export CLAWQL_X402_ENFORCE=1
export CLAWQL_X402_FACILITATOR_URL=https://x402.org/facilitator

clawql inference serve --port 8080

Middleware order in the HTTP app:

  1. JSON body parser
  2. x402 payment middleware (CLAWQL_X402_ENFORCE)
  3. Virtual key auth (CLAWQL_INFERENCE_KEYS_ENABLED)
  4. OpenAI-compat router (entitlement check inside gateway + HTTP layer for streaming)

See also: packages/clawql-inference/README.md.


Troubleshooting

402 insufficient_quota on inference

  • Run clawql payments plan show — check usage.inferenceCalls vs entitlements
  • Confirm tenant id: virtual key team must match the tenant you expect
  • Enterprise plan uses Infinity — verify payments.jsonplan

x402 402 with invalid x402 payment payload

  • Header must be valid JSON or base64-encoded JSON matching PaymentPayloadV2
  • Use clawql payments x402 verify --payload ./file.json --resource <url> to test facilitator path

x402 402 with x402 wallet address is not configured

  • Run clawql payments x402 wallet setup --address 0x...

Facilitator verify fails

  • Check CLAWQL_X402_FACILITATOR_URL reaches /verify (not double-suffixed)
  • For CDP: set CLAWQL_X402_FACILITATOR_BEARER or CDP_API_KEY_ID + CDP_API_KEY_SECRET
  • Testnet: ensure client payment targets CLAWQL_X402_NETWORK and CLAWQL_X402_USDC_ASSET

Stripe meter events not appearing

  • Confirm CLAWQL_PAYMENTS_REPORT_STRIPE_METER=1
  • Customer id must be in payments.json or STRIPE_CUSTOMER_ID
  • Meter event name must match Dashboard: STRIPE_METER_EVENT_NAME or payments.jsonstripe.meterEventName
  • Check payment audit for STRIPE_METER_REPORTED or CLI errors

Webhook signature failures

  • Use raw request body (not re-serialized JSON) for verification
  • Secret from clawql payments stripe setup or payments.jsonstripe.webhookSecret

Follow-up work

ItemTracking
Hosted webhook HTTP endpointnot CLI-only