X402 Subscribe Confirm
Confirm an on-chain USDC payment for a publisher subscription. The frontend calls this AFTER the wallet returns a successful sendTransaction — we verify the tx on-chain (Base mainnet RPC: receipt status + a USDC Transfer of >= the plan price to the PUBLISHER's payout wallet) BEFORE marking the subscription active.
Trust model: the on-chain verification IS the authorization — no valid, correctly-priced USDC payment to the publisher's payout wallet means no activation, so guessing a subscription_id (a DB PK) buys nothing. The receiver verified here MUST match the wallet the payer was instructed to pay in listener_subscribe_publisher (pub.payout_wallet_address), not the platform x402 receiver. The chain is pinned to base-mainnet so a free testnet-USDC transfer cannot be passed off as payment. The tx_hash is required to be globally unused (across subscriptions and X402Payment receipts) so a settled payment can't be replayed onto another sub.
Pool-safety: this handler does NOT take Depends(get_db). It opens a short read session, releases it, runs the external Base-RPC verification with NO pooled connection held, then opens a short write session — the canonical fix for the pool-exhaustion anti-pattern (tests/test_pool_exhaustion_static_audit.py). Holding a connection across _eth_get_receipt would be exactly that anti-pattern.
Known residual (tracked follow-up, needs a coordinated FE change): the payment is bound to the publisher + amount but NOT to the individual subscriber, so a same-publisher/same-tier front-runner could confirm THEIR pending sub with a victim's just-broadcast tx. Closing it requires binding a listener/publisher auth token on confirm (verify sub.listener_email) — a breaking FE-contract change deferred to its bridge PR. This is strictly narrower than the free-activation hole this fix closes.
Request
- Base URL: https://api.storyflo.com (the document declares no server; this is the origin it was published from)
- URL: https://api.storyflo.com/v1/x402/subscribe/confirm
- Auth: none declared
Request body
Response
Successful Response
Changes
No recorded changes to this operation across all 1 revision of this API.