<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Grov.fun</title>
    <description>The latest articles on DEV Community by Grov.fun (@grovdotfun).</description>
    <link>https://dev.to/grovdotfun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122974%2F1d081bd8-caeb-41b0-8354-47b5517bda0c.png</url>
      <title>DEV Community: Grov.fun</title>
      <link>https://dev.to/grovdotfun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grovdotfun"/>
    <language>en</language>
    <item>
      <title>Building a checkout for AI agents with x402 and MPP</title>
      <dc:creator>Grov.fun</dc:creator>
      <pubDate>Sun, 13 Sep 2026 09:10:47 +0000</pubDate>
      <link>https://dev.to/grovdotfun/building-a-checkout-for-ai-agents-with-x402-and-mpp-17am</link>
      <guid>https://dev.to/grovdotfun/building-a-checkout-for-ai-agents-with-x402-and-mpp-17am</guid>
      <description>&lt;p&gt;We built Grov, a paid social growth storefront for people and AI agents. Human buyers browse a catalog and use a checkout. Agents use an HTTP API and pay in USDC through x402 or MPP, without creating a Grov account or requesting a Grov API key.&lt;/p&gt;

&lt;p&gt;The useful engineering question is broader than our product: how do you sell something to software that can choose a service, authorize a payment, and come back for the result?&lt;/p&gt;

&lt;p&gt;Here is the request flow we use, including a quote you can inspect without spending anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Make the catalog readable before asking for payment
&lt;/h2&gt;

&lt;p&gt;An agent needs more than an endpoint URL. It needs the service identifier, required input, quantity limits, and a way to understand the response.&lt;/p&gt;

&lt;p&gt;We generate our storefront and agent discovery documents from the same catalog. This keeps the available services and their limits consistent across the two interfaces.&lt;/p&gt;

&lt;p&gt;You can inspect the public catalog and usage instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; https://grov.fun/skill.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also an &lt;a href="https://grov.fun/openapi.json" rel="noopener noreferrer"&gt;OpenAPI document&lt;/a&gt; for clients that prefer a structured interface description. Treat catalog prices as discovery information. The live payment challenge is the quote to evaluate before paying.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ask for a quote with an ordinary HTTP request
&lt;/h2&gt;

&lt;p&gt;This example requests a quote for 50 paid likes on one of our own public demo posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://grov.fun/api/base/xlikes'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'url=https://x.com/grovdotfun/status/2098556423139455038'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'amount=50'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without a payment credential, the expected response is &lt;strong&gt;HTTP 402 Payment Required&lt;/strong&gt;. This command does not pay or place an order.&lt;/p&gt;

&lt;p&gt;For x402, the response describes the accepted payment scheme, network, token, amount, and recipient. The client should inspect those requirements before signing anything. It still needs a funded wallet and authorization to spend. “No API key” does not mean “no payment credentials.”&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use the payment client for the protocol you selected
&lt;/h2&gt;

&lt;p&gt;Both protocols use a challenge and a paid retry, but their headers are different:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;x402&lt;/th&gt;
&lt;th&gt;MPP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Initial response&lt;/td&gt;
&lt;td&gt;HTTP 402&lt;/td&gt;
&lt;td&gt;HTTP 402&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Challenge header&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PAYMENT-REQUIRED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WWW-Authenticate: Payment ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paid retry header&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PAYMENT-SIGNATURE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization: Payment ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For x402, a payment-aware client such as &lt;code&gt;@x402/fetch&lt;/code&gt; can handle the challenge and retry. For MPP, use a client matching the selected payment method. Our &lt;a href="https://grov.fun/docs" rel="noopener noreferrer"&gt;API documentation&lt;/a&gt; includes examples for both.&lt;/p&gt;

&lt;p&gt;Before allowing a paid retry, check the recipient, network, currency, and amount against the user's instructions and spending limit. Never construct a new payment just because a previous request timed out. First establish whether that payment succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Separate payment from delivery
&lt;/h2&gt;

&lt;p&gt;A successful payment creates an order. It does not mean the work is complete.&lt;/p&gt;

&lt;p&gt;Our order response includes an &lt;code&gt;orderId&lt;/code&gt;, a private &lt;code&gt;secret&lt;/code&gt;, and a &lt;code&gt;statusUrl&lt;/code&gt;. Save these immediately. The secret is the credential for reading that order, so it belongs in private agent state, not a public log or a conversation screenshot.&lt;/p&gt;

&lt;p&gt;A later status request is free. For example, after an order has been created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://grov.fun/api/base/xlikes'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'action=view'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Secret: YOUR_ORDER_SECRET'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delivery progresses separately from checkout. Agents need to distinguish “paid and queued” from “completed,” and keep checking the existing order instead of purchasing again while work is still in progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we want feedback on
&lt;/h2&gt;

&lt;p&gt;The pattern is: discover the service, inspect the live quote, authorize the payment, save the receipt and access token, then track the result.&lt;/p&gt;

&lt;p&gt;We are the team behind &lt;a href="https://grov.fun/" rel="noopener noreferrer"&gt;Grov&lt;/a&gt;. If you are building agents that buy services, what would you need before trusting this flow in production: clearer spending controls, better receipts, a sandbox, or something else?&lt;/p&gt;

</description>
      <category>x402</category>
      <category>ai</category>
      <category>webdev</category>
      <category>api</category>
    </item>
  </channel>
</rss>
