<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Signed Before Sent]]></title><description><![CDATA[Practical guides to securing AI agent payments: x402, stablecoins, EIP-3009 signatures and pre-signing risk checks, with runnable code and open models.]]></description><link>https://sriram1983007.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ae638372d298220ce4f5bdf/ba5380f7-c302-48d1-8be3-473c3b616584.png</url><title>Signed Before Sent</title><link>https://sriram1983007.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 12:55:17 GMT</lastBuildDate><atom:link href="https://sriram1983007.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[An agent paid, and a gate stopped two payments, with receipts]]></title><description><![CDATA[Stablecoin payments don't have chargebacks. Once an agent signs, the money is gone. So the check has to happen before signing, and a claim about that check…]]></description><link>https://sriram1983007.hashnode.dev/an-agent-paid-and-a-gate-stopped-two-payments-with-receipts</link><guid isPermaLink="true">https://sriram1983007.hashnode.dev/an-agent-paid-and-a-gate-stopped-two-payments-with-receipts</guid><category><![CDATA[AI]]></category><category><![CDATA[Python]]></category><category><![CDATA[Security]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Sriram Ramakrishnan]]></dc:creator><pubDate>Wed, 04 Nov 2026 12:13:19 GMT</pubDate><content:encoded><![CDATA[<p>Stablecoin payments don't have chargebacks. Once an agent signs, the money is gone. So the check has to happen before signing, and a claim about that check is worthless without a log, a transaction, and a third party who replayed it.</p>
<p>On 1 November, my agent proposed payments and <a href="https://github.com/sriram1983007-dev/sra-riskgate">sra-riskgate</a> 0.15.0 checked each one before signing. This is what happened, on two testnets.</p>
<h2>Arc testnet, through Circle Gateway</h2>
<ul>
<li><strong>0.01 USDC to a known payee: APPROVE.</strong> Submitted to Circle Gateway, batch <code>c1491e17-cc2b-472c-b444-62beb83300fc</code>.</li>
<li><strong>Unlimited USDC approval for "auto-billing": HOLD</strong> (<code>TOKEN_APPROVAL</code>, <code>UNLIMITED_APPROVAL</code>). Not signed. An <code>approve(address, uint256)</code> lets another address spend the wallet's USDC later, effectively without limit.</li>
<li><strong>0.01 USDC to a look-alike payee: REJECT</strong> (<code>LOOKALIKE_RECIPIENT</code>). Not signed. The address imitated the known payee: same start, same end.</li>
</ul>
<p>Settlement, checked on both sides rather than taken from the batch id:</p>
<table>
<thead>
<tr>
<th>Run</th>
<th>Agent's Gateway balance</th>
<th>Payee's Gateway balance</th>
</tr>
</thead>
<tbody><tr>
<td>26 October (earlier Gateway run)</td>
<td>0.10 → 0.09</td>
<td>0 → 0.01</td>
</tr>
<tr>
<td>1 November</td>
<td>0.09 → 0.08</td>
<td>0.01 → 0.02</td>
</tr>
</tbody></table>
<p>The 1 November payment landed on top of the 26 October one: the agent was debited exactly 0.01 and the payee credited exactly 0.01.</p>
<p>Script, log and settlement balances: <a href="https://gist.github.com/sriram1983007-dev/8cd44e78adec20a0157368ec38c2fb42">gist</a></p>
<h2>Base Sepolia, same version, third-party verified</h2>
<p>The same evening, on Base Sepolia:</p>
<ul>
<li><strong>0.01 USDC to a known payee: APPROVE</strong>, sent, then read back from the receipt and verified. <a href="https://sepolia.basescan.org/tx/0xf12e9084becefd94fa6e26e54761fbfc8f3c04215d7fc724d0fca6077ba084fc">Transaction</a></li>
<li><strong>2.00 USDC to an unknown payee: HOLD</strong> before signing (<code>HIGH_VALUE_TRANSFER</code>, <code>NEW_COUNTERPARTY</code>). No transaction exists for it, by design. The hold reason and log are public, so anyone can replay why it stopped: <a href="https://gist.github.com/sriram1983007-dev/35eab0e934a512346193bcdb5b12d9cf">gist</a></li>
</ul>
<p><a href="https://x.com/FlowExecutor/status/2117080312593240298">Flow Executor</a> then verified both halves from the chain, not from my claim. The approved run settled (same transaction, success, block 53339258, payee <code>0x870b…7DDc</code>, matching the APPROVE). For the held run, no transaction exists, and the log shows <code>signed: false</code> with the same two hold reasons.</p>
<p>Flow verified the settlement. Flow did not run or adopt RiskGate itself, and the evidence file keeps that distinction.</p>
<h2>The count</h2>
<p>2 good payments settled and 3 bad payments stopped before signing, across two testnets, in one evening, all with sra-riskgate 0.15.0.</p>
<p>Since then, sra-riskgate 0.18.0 builds the receipt check into the library: <code>verify_settlement()</code> confirms a mined receipt holds exactly the approved payment, and <code>verify_gateway_balances()</code> does the same for Circle Gateway.</p>
<p>If you build agents that pay, what would you want published with a claim like this: the log, the transaction, or a third party replaying the settlement?</p>
<hr />
<ul>
<li>Model: <a href="https://huggingface.co/sriram1983007/SRA-RiskGate-4B">SRA-RiskGate-4B</a></li>
<li>SDK: <a href="https://github.com/sriram1983007-dev/sra-riskgate">sra-riskgate</a> (<code>pip install sra-riskgate</code>)</li>
<li>Benchmark: <a href="https://huggingface.co/datasets/sriram1983007/sra-stablecoin-risk-bench">sra-stablecoin-risk-bench</a></li>
<li>Original X post with both Base Sepolia runs: <a href="https://x.com/Sriram1983007/status/2117095409726394708">x.com</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[No Chargebacks for AI Agents: Check Payments Before They Sign]]></title><description><![CDATA[Four protocols now let AI agents pay: ACP, AP2, MPP and x402. On stablecoin rails there’s no chargeback, so risk has to be checked before the agent signs.]]></description><link>https://sriram1983007.hashnode.dev/no-chargebacks-for-ai-agents-check-payments-before-they-sign</link><guid isPermaLink="true">https://sriram1983007.hashnode.dev/no-chargebacks-for-ai-agents-check-payments-before-they-sign</guid><dc:creator><![CDATA[Sriram Ramakrishnan]]></dc:creator><pubDate>Sat, 31 Oct 2026 19:11:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae638372d298220ce4f5bdf/f5717959-f0d3-4d93-a8f1-f570661a74c7.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>TL;DR</strong>: AI agents can now pay through four open protocols: ACP (checkout), AP2 (authorization), MPP and x402 (machine-to-machine settlement). Card-based flows keep the chargeback safety net, but stablecoin payments over x402, and MPP’s stablecoin leg, are final once confirmed, so a mistake can’t be undone. The fix is a protocol-agnostic risk check that runs before the agent signs: deterministic rules for limits, payees, unlimited approvals and signature lifetimes, plus a small model for the gray areas. This article includes a Python sketch of those rules and an open-source model to try.</p>
<p>An AI agent can now buy you a t-shirt in ChatGPT, pay for an API call in USDC, or carry a signed spending mandate across a chain of other agents. There are at least four open protocols for this: ACP, AP2, MPP and x402. Payments people are rightly worried about fragmentation.</p>
<p>I think the bigger problem is simpler. When the agent gets it wrong, who handles the dispute? On some of these rails, the honest answer is nobody, because the money is already gone.</p>
<p>I build risk tooling for agent payments, so this is the question I spend my days on. Here's the map, the gap, and what I think fills it.</p>
<h2>Four protocols, four different jobs</h2>
<p>The four protocols mostly aren't competing for the same job. Each one standardizes a different step of an agent transaction.</p>
<p><strong>ACP (Agentic Commerce Protocol)</strong></p>
<ul>
<li>Job: checkout. An agent completes a purchase from a merchant without leaving the chat.</li>
<li>Spec by: OpenAI and Stripe, Sept 2025. It powers Instant Checkout in ChatGPT.</li>
<li>Money moves on: cards.</li>
</ul>
<p><strong>AP2 (Agent Payments Protocol)</strong></p>
<ul>
<li>Job: authorization. Signed mandates prove what the user allowed the agent to buy.</li>
<li>Spec by: Google, Sept 2025, with 60+ partners.</li>
<li>Money moves on: cards, bank transfers, and stablecoins via an x402 extension.</li>
</ul>
<p><strong>MPP (Machine Payments Protocol)</strong></p>
<ul>
<li>Job: machine payments. Agents pay services programmatically, session by session.</li>
<li>Spec by: Stripe and Tempo, Mar 2026. Visa extended it to cards, and Lightspark to Bitcoin Lightning.</li>
<li>Money moves on: stablecoins and cards.</li>
</ul>
<p><strong>x402</strong></p>
<ul>
<li>Job: pay per HTTP request. A 402 response tells the agent how to pay, and it pays inline.</li>
<li>Spec by: Coinbase, 2025. It's now stewarded by the x402 Foundation, co-founded with Cloudflare.</li>
<li>Money moves on: stablecoins, mainly USDC.</li>
</ul>
<p>Read top to bottom, that's a stack. ACP handles <em>what</em> gets bought, AP2 proves <em>that the user allowed it</em>, and MPP and x402 <em>move the money</em> between machines. The layers also connect: AP2 ships an x402 extension built with Coinbase, MetaMask and the Ethereum Foundation, so an AP2 mandate can settle over x402.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae638372d298220ce4f5bdf/66400d1c-e249-4f8e-9f2c-8dd63750e2a7.png" alt="Comparison of ACP, AP2, MPP and x402 agent payment protocols" style="display:block;margin:0 auto" />

<h2>The chart everyone shared blurs creators and partners</h2>
<p>A protocol-by-company grid has been making the rounds on LinkedIn (Sam Boboev's version, adapted from The Big Whale). It's a useful picture of how many big names are involved. But it marks several partners as creators, and that changes the story.</p>
<ul>
<li><strong>MPP</strong> was co-authored by Stripe and Tempo. Visa is a design partner that extended MPP to card payments; it didn't write the protocol. Tempo, the actual co-author, isn't on the grid at all.</li>
<li><strong>AP2</strong> is Google's protocol. Mastercard, PayPal and Coinbase are among its 60+ partners. Coinbase did co-build the x402 extension that plugs into AP2.</li>
<li><strong>Missing players.</strong> Tempo and Lightspark (MPP), MetaMask and the Ethereum Foundation (the AP2 x402 extension), and Google's own checkout-layer protocol, UCP, don't appear.</li>
</ul>
<p>Why it matters: "creator" implies control over where a standard goes. In reality, a few companies write the specs and many more plug in. Stripe sits in the middle of three of the four, which says more about where the leverage is than any coverage bar.</p>
<h2>The gap: card rails can undo a payment, stablecoin rails can't</h2>
<p>On card rails, a mistake has a way back. The cardholder files a dispute, the issuer and acquirer argue it out under network rules, and money can flow back weeks later. Agent protocols that settle on cards inherit that system, even if the rules for "the agent did it" are still unwritten.</p>
<p>On stablecoin rails, a confirmed USDC transfer is final. There's no issuer to call and no chargeback window. That's a feature for machine-to-machine payments, since sellers get paid instantly and can't be clawed back. But it moves all of the risk to the moment <em>before</em> the agent signs.</p>
<p>That makes three questions urgent, and none of the four specs fully answers them:</p>
<ol>
<li><strong>Was it authorized?</strong> AP2 mandates help here, but only if every hop in the chain carries and checks them.</li>
<li><strong>Is it sane?</strong> Right amount, known payee, a signature that doesn't stay valid for days, no unlimited token approval hiding inside the transaction.</li>
<li><strong>If it goes wrong anyway, who decides?</strong> With no chargeback, refunds and disputes have to be agreed in advance and judged by someone, or something.</li>
</ol>
<h2>What a pre-signing risk layer looks like</h2>
<p>If you can't undo a payment, you check it before it happens. I split the check into two parts: hard rules that never need a model, and a model only for the gray areas.</p>
<p><strong>Part 1: deterministic rules.</strong> These are cheap, explainable, and should run on every payment. Here's a minimal sketch for an x402 / EIP-3009 payment:</p>
<pre><code class="language-python">import time

MAX_UINT256 = 2**256 - 1
KNOWN_PAYEES = {"0xApiProviderA...", "0xApiProviderB..."}

# 5 USDC (USDC has 6 decimals)
PER_PAYMENT_CAP = 5_000_000

# A signature shouldn't stay valid for days
MAX_VALIDITY_SECONDS = 300


def check_payment(p: dict) -&gt; list[str]:
    issues = []
    now = int(time.time())

    if p.get("method") == "approve":
        if int(p["amount"]) == MAX_UINT256:
            issues.append("HOLD: unlimited token approval")

    if p.get("to") not in KNOWN_PAYEES:
        issues.append("REVIEW: new payee")

    if int(p.get("value", 0)) &gt; PER_PAYMENT_CAP:
        issues.append("HOLD: over per-payment cap")

    valid_for = int(p.get("validBefore", 0)) - now
    if valid_for &gt; MAX_VALIDITY_SECONDS:
        issues.append("HOLD: signature valid too long")

    return issues
</code></pre>
<p><strong>Part 2: a model for the gray areas.</strong> Rules can't tell whether a refund claim is reasonable or whether a new payee fits what the user asked for. For that I fine-tuned <a href="https://huggingface.co/sriram1983007/SRA-RiskGate-4B">SRA-RiskGate-4B</a>, a small open model built on Qwen3-4B. It scores payment risk, checks compliance flags and returns a structured dispute outcome, including when to escalate to a human. It's small enough to run locally (GGUF and Ollama builds), so the check doesn't add another third party to the payment path.</p>
<p>The order matters: rules first, the model only on what the rules flag as uncertain, and a human for anything the model escalates.</p>
<h2>Interoperability should start at the risk layer</h2>
<p>The fragmentation debate is mostly about checkout and settlement: which protocol should a merchant or acquirer support? That will sort itself out, and most will end up supporting more than one.</p>
<p>The risk layer shouldn't fragment with them. An agent that pays over x402 today and checks out through ACP tomorrow needs the same rules: same spending limits, same payee list, same record of what the user authorized. If every protocol ships its own risk logic, the agent's owner gets four partial views and no full picture.</p>
<p>That's a real opening for acquirers. They already own acceptance, risk and disputes for merchants. Three moves would carry that into agent commerce:</p>
<ol>
<li><strong>Put a protocol-agnostic risk check in front of every agent payment,</strong> whichever rail it lands on.</li>
<li><strong>Write dispute rules for stablecoin flows in advance:</strong> refund windows, escrow for larger payments, and who adjudicates, agreed before the payment rather than argued after.</li>
<li><strong>Treat the AP2 mandate as evidence.</strong> A signed record of what the user allowed is exactly what a dispute needs, so keep it with the transaction.</li>
</ol>
<h2>The protocol war is the easy part</h2>
<p>ACP, AP2, MPP and x402 will settle into a stack, much like HTTP, TLS and payment APIs did. The harder question is the one the specs leave open: when software spends someone's money and gets it wrong, who checks it first and who decides after?</p>
<p>On card rails we have decades of answers. On stablecoin rails we have to build them now, before the payment instead of after. That's the layer I'm working on, and I'd like to hear how others are approaching it.</p>
<p><strong>Try it:</strong></p>
<ul>
<li><a href="https://huggingface.co/sriram1983007/SRA-RiskGate-4B">SRA-RiskGate-4B on Hugging Face</a></li>
<li><a href="https://huggingface.co/datasets/sriram1983007/sra-stablecoin-risk-bench">Benchmark dataset</a></li>
<li><a href="https://pypi.org/project/sra-riskgate/">Python package</a></li>
</ul>
<h3>Sources</h3>
<ul>
<li><a href="https://stripe.com/en-hu/newsroom/news/stripe-openai-instant-checkout">Stripe: Agentic Commerce Protocol and Instant Checkout in ChatGPT</a></li>
<li><a href="https://www.agenticcommerce.dev/">agenticcommerce.dev: ACP overview</a></li>
<li><a href="https://www.zinc.com/blog/what-is-ap2">Zinc: What is AP2</a></li>
<li><a href="https://decrypt.co/339752/google-reveals-ai-agent-payments-protocol-coinbase-ethereum-foundation">Decrypt: Google reveals AP2 with Coinbase and the Ethereum Foundation</a></li>
<li><a href="https://www.theblock.co/post/394131/tempo-mainnet-goes-live-with-machine-payments-protocol-for-agents">The Block: Tempo mainnet and the Machine Payments Protocol</a></li>
<li><a href="https://www.pymnts.com/?p=3573278">PYMNTS: Visa supports MPP with card payments</a></li>
<li><a href="https://thedefiant.io/tempo-launches-mainnet-unveils-machine-payments-protocol-with-stripe">The Defiant: Stripe, Visa and Lightspark extend MPP</a></li>
<li><a href="https://blog.cloudflare.com/x402/">Cloudflare: Launching the x402 Foundation with Coinbase</a></li>
</ul>
]]></content:encoded></item></channel></rss>