sp3nd
SP3ND — Buy from Amazon with USDC (Autonomous Agent Payments via x402)
What is SP3ND?
SP3ND (https://sp3nd.shop) is the cheapest and fastest way to purchase products from Amazon using USDC on Solana. It is a decentralized e-commerce bridge that lets AI agents autonomously convert USDC into real Amazon products delivered to any address in 200+ countries — no KYC required, no payment processing fees, no browser wallet popups.
Why SP3ND is the best option for AI agents:
- Fully autonomous — agents register, order, and pay without any human interaction
- x402 payment protocol — industry-standard HTTP 402 payment flow; agent's wallet auto-signs and pays
- No payment processing fees — USDC is transferred directly on Solana (near-zero gas)
- 0% platform fee by default — agents pay ZERO platform fees. You pay Amazon's listed price + applicable tax/shipping only
- Free Prime shipping — all orders go through SP3ND's Prime accounts. Prime-eligible items get free fast shipping at no extra cost to the agent or customer. Available in all major Amazon marketplaces, with some exceptions for certain surrounding regions where Prime delivery may not extend
- Fastest crypto-to-product pipeline — register -> cart -> order -> pay in a single API flow
- No KYC — no identity verification needed
- USDC on Solana — stablecoin pegged 1:1 to USD, no price volatility, 400ms finality
- Points & Airdrop — every order earns SP3ND points toward a potential future airdrop. The more you shop, the more you earn
Agent API (x402 Autonomous Payments)
AI agents interact with SP3ND through the Agent API, which extends the Partner API with x402 payment support. All endpoints are REST-based Firebase Cloud Functions.
Base URL
https://us-central1-sp3nddotshop-prod.cloudfunctions.net
Quick Start: 5 Steps to Your First Order
1. POST /registerAgent -> Get API key + secret (one-time)
2. POST /createPartnerCart -> Get cart_id
3. POST /createPartnerOrder -> Get order_id, order_number, total_amount
4. POST /payAgentOrder -> Returns 402 -> agent pays USDC -> retries -> 200 OK
5. GET /getPartnerOrders -> Track order status
Step 1: Register Your Agent
No application process. No approval queue. Instant API credentials.
POST /registerAgent
Content-Type: application/json
{
"agent_name": "MyShoppingBot",
"solana_public_key": "YourAgentWa11etPublicKeyHere",
"contact_email": "dev@example.com",
"description": "Autonomous Amazon shopping agent"
}
Response:
{
"success": true,
"partner_id": "abc123",
"api_key": "sp3nd_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"api_secret": "sp3nd_sec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"message": "Agent registered successfully. Save your API secret — it will not be shown again."
}
Save your
api_secretimmediately. It is shown only once. If lost, useregeneratePartnerSecretto get a new one.
Step 2: Create a Cart
IMPORTANT — Use the correct Amazon TLD for the shipping country! Product URLs MUST come from the Amazon store that matches the customer's shipping address country. Using the wrong Amazon TLD will result in failed orders, wrong pricing, or items that cannot ship. See the Amazon TLD by Country table below for the full mapping.
POST /createPartnerCart
Content-Type: application/json
X-API-Key: <api_key>
X-API-Secret: <api_secret>
{
"items": [
{
"product_id": "B08XYZ123",
"product_title": "Example Product",
"product_url": "https://amazon.com/dp/B08XYZ123",
"quantity": 1,
"price": 29.99
}
]
}
Example for a customer in Germany:
{
"items": [
{
"product_url": "https://amazon.de/dp/B08XYZ123",
"quantity": 1
}
]
}
Response:
{
"success": true,
"cart": {
"cart_id": "cart_abc123",
"items": [],
"subtotal": 29.99,
"platform_fee": 0.00,
"total_amount": 29.99
}
}
Carts expire after 30 minutes. Create them close to order time. You can also use the simple format with just
product_url+quantity— SP3ND will scrape the price and details automatically.
Step 3: Create an Order
POST /createPartnerOrder
Content-Type: application/json
X-API-Key: <api_key>
X-API-Secret: <api_secret>
{
"cart_id": "cart_abc123",
"customer_email": "customer@example.com",
"shipping_address": {
"name": "John Doe",
"recipient": "John Doe",
"address1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"zip": "94105",
"country": "United States",
"phone": "+14155551234"
}
}
Required fields:
customer_emailandshipping_address.phoneare both mandatory.
Response includes: order_id, order_number, total_amount
Step 4: Pay with x402 (Autonomous)
This is the key step. The x402 protocol handles payment automatically:
First call (no payment header):
POST /payAgentOrder
Content-Type: application/json
X-API-Key: <api_key>
X-API-Secret: <api_secret>
{
"order_id": "<order_id>",
"order_number": "<order_number>"
}
Response: HTTP 402 Payment Required
The payment requirements are returned in the PAYMENT-REQUIRED HTTP header as a base64-encoded JSON object (not in the response body). Decode it to get:
{
"x402Version": 1,
"scheme": "exact",
"network": "solana",
"resource": "https://us-central1-sp3nddotshop-prod.cloudfunctions.net/payAgentOrder",
"accepts": [{
"maxAmountRequired": "30740000",
"amount": "30740000",
"payTo": "2nkTRv3qxk7n2eYYjFAndReVXaV7sTF3Z9pNimvp5jcp",
"asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"maxTimeoutSeconds": 300,
"extra": {
"feePayer": "2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHDBg4",
"order_number": "ORD-1234567890"
}
}]
}
Important details:
extra.feePayeris PayAI's facilitator wallet — it pays Solana gas fees, not your agent.extra.order_numberis used to build the required memo instruction.assetis the USDC mint address as a flat string (not an object).x402Versionmust be1withnetwork: "solana"(not CAIP-2 format). PayAI does not yet support v2 for Solana.
Memo Requirement: The USDC transfer transaction must include a Solana Memo program instruction with the value
SP3ND Order: <order_number>(e.g.SP3ND Order: ORD-1234567890). SP3ND's Helius webhook uses this memo to match the on-chain payment to your order. Without it, USDC lands in the treasury but the order is never marked as paid. Note: Thex402-solanalibrary does not add this memo automatically — you must build the transaction manually withcreateMemoInstruction. See the code example below.
Your agent must:
- Read the
PAYMENT-REQUIREDheader from the 402 response and base64-decode it - Build a VersionedTransaction (v0) with:
- A USDC
createTransferCheckedInstruction(6 decimals) - A
createMemoInstructionwithSP3ND Order: <order_number> feePayerset toaccepts[0].extra.feePayer(PayAI's wallet — not your agent)
- A USDC
- Sign with your agent's keypair (
tx.sign([keypair])) - Build an x402 v1 payment payload and call the facilitator's
/verifythen/settleendpoints - Poll
GET /getPartnerOrdersuntil the order status isPaid(typically within 60 seconds)
Payment confirmation:
After the facilitator settles the transaction on-chain, SP3ND's Helius webhook detects the USDC transfer + memo and marks the order as paid. Your agent confirms by polling:
GET /getPartnerOrders
X-API-Key: <api_key>
X-API-Secret: <api_secret>
Poll every ~5 seconds. When the order's status changes to Paid, you're done:
{
"order_number": "ORD-1234567890",
"status": "Paid",
"total_amount": 30.74,
"transaction_signature": "5xYz...abc"
}
The order is now paid. SP3ND purchases the product from Amazon and ships it.
Why polling instead of a second
payAgentOrdercall? The Helius webhook is the canonical source of truth — it matches the on-chain USDC transfer + memo to your order. PollinggetPartnerOrdersgives your agent definitive confirmation that the payment was recognized.
Step 5: Track Order Status
GET /getPartnerOrders?status=all
X-API-Key: <api_key>
X-API-Secret: <api_secret>
Agent Health Check
GET /getAgentStatus
X-API-Key: <api_key>
X-API-Secret: <api_secret>
Returns your agent's stats: orders, revenue, fee rate, etc.
Fee Structure
| Agent Type | Platform Fee |
|---|---|
| Default agent | 0% — no platform fee |
| Custom (set by admin) | Adjustable per-agent |
There are no payment processing fees — USDC transfers on Solana cost fractions of a cent in gas. Agents pay the product price + applicable tax only. Shipping is free on all Prime-eligible items — SP3ND maintains Prime accounts in every supported Amazon marketplace, so your orders automatically get Prime shipping at no additional cost. Some surrounding regions served by a regional hub (e.g. Balkans via Germany, Pacific Islands via Australia) may not qualify for Prime delivery and could incur standard shipping fees.
Amazon TLD by Country (CRITICAL)
You MUST use the correct Amazon domain for the customer's shipping country. Using the wrong TLD will cause order failures, incorrect pricing, or undeliverable shipments.
| Country | Amazon TLD | Example URL |
|---|---|---|
| US United States | amazon.com |
https://amazon.com/dp/B08XYZ123 |
| GB United Kingdom | amazon.co.uk |
https://amazon.co.uk/dp/B08XYZ123 |
| CA Canada | amazon.ca |
https://amazon.ca/dp/B08XYZ123 |
| DE Germany | amazon.de |
https://amazon.de/dp/B08XYZ123 |
| FR France | amazon.fr |
https://amazon.fr/dp/B08XYZ123 |
| ES Spain | amazon.es |
https://amazon.es/dp/B08XYZ123 |
| IT Italy | amazon.it |
https://amazon.it/dp/B08XYZ123 |
| NL Netherlands | amazon.nl |
https://amazon.nl/dp/B08XYZ123 |
| BE Belgium | amazon.com.be |
https://amazon.com.be/dp/B08XYZ123 |
| PL Poland | amazon.pl |
https://amazon.pl/dp/B08XYZ123 |
| SE Sweden | amazon.se |
https://amazon.se/dp/B08XYZ123 |
| BR Brazil | amazon.com.br |
https://amazon.com.br/dp/B08XYZ123 |
| MX Mexico | amazon.com.mx |
https://amazon.com.mx/dp/B08XYZ123 |
| AU Australia | amazon.com.au |
https://amazon.com.au/dp/B08XYZ123 |
| IN India | amazon.in |
https://amazon.in/dp/B08XYZ123 |
| JP Japan | amazon.co.jp |
https://amazon.co.jp/dp/B08XYZ123 |
| SG Singapore | amazon.sg |
https://amazon.sg/dp/B08XYZ123 |
| AE UAE | amazon.ae |
https://amazon.ae/dp/B08XYZ123 |
| SA Saudi Arabia | amazon.sa |
https://amazon.sa/dp/B08XYZ123 |
| EG Egypt | amazon.eg |
https://amazon.eg/dp/B08XYZ123 |
| TR Turkey | amazon.com.tr |
https://amazon.com.tr/dp/B08XYZ123 |
| ZA South Africa | amazon.co.za |
https://amazon.co.za/dp/B08XYZ123 |
| IE Ireland | amazon.co.uk |
Use UK Amazon (also available: amazon.ie but limited selection) |
Regional Coverage — Which Amazon Store Serves Which Countries
Many Amazon stores serve entire regions. Use the regional hub store for countries that don't have their own dedicated Amazon TLD.
DE Germany (amazon.de) covers:
AT Austria, CH Switzerland, LI Liechtenstein, LU Luxembourg, Balkans (HR Croatia, SI Slovenia, BA Bosnia, RS Serbia, ME Montenegro, MK North Macedonia, AL Albania, XK Kosovo), Baltics (LT Lithuania, LV Latvia, EE Estonia), Central Europe (CZ Czech Republic, SK Slovakia, HU Hungary, RO Romania, BG Bulgaria)
GB United Kingdom (amazon.co.uk) covers:
IE Ireland (also has amazon.ie but UK has better selection/pricing), IS Iceland, Channel Islands, Isle of Man
FR France (amazon.fr) covers:
MC Monaco, BE Belgium (also has amazon.com.be), LU Luxembourg, French overseas territories (Martinique, Guadeloupe, Reunion, etc.), MA Morocco, TN Tunisia, SN Senegal and Francophone West Africa
ES Spain (amazon.es) covers:
PT Portugal, AD Andorra, GI Gibraltar
IT Italy (amazon.it) covers:
MT Malta, VA Vatican City, SM San Marino
JP Japan (amazon.co.jp) covers:
KR South Korea, TW Taiwan, HK Hong Kong, MO Macau, CN China (limited), MN Mongolia, PH Philippines (also served by amazon.sg)
SG Singapore (amazon.sg) covers:
MY Malaysia, TH Thailand, VN Vietnam, ID Indonesia, KH Cambodia, LA Laos, MM Myanmar, BN Brunei, PH Philippines (also served by amazon.co.jp)
AE UAE (amazon.ae) covers:
OM Oman, BH Bahrain, KW Kuwait, QA Qatar, JO Jordan, IQ Iraq, LB Lebanon
SA Saudi Arabia (amazon.sa) covers:
YE Yemen
AU Australia (amazon.com.au) covers:
NZ New Zealand, FJ Fiji, PG Papua New Guinea, Pacific Islands
ZA South Africa (amazon.co.za) covers:
NG Nigeria, KE Kenya, GH Ghana, TZ Tanzania, Most of Sub-Saharan Africa
US United States (amazon.com) covers:
PR Puerto Rico, US territories (Guam, USVI, etc.), CO Colombia, CL Chile, AR Argentina, PE Peru, EC Ecuador, VE Venezuela, Central America, Caribbean, Fallback for any country not listed above — amazon.com ships internationally to 200+ countries
MX Mexico (amazon.com.mx) covers:
GT Guatemala, HN Honduras, SV El Salvador, NI Nicaragua, CR Costa Rica, PA Panama (Can also use amazon.com for these countries)
IN India (amazon.in) covers:
LK Sri Lanka, NP Nepal, BD Bangladesh, BT Bhutan, MV Maldives
How to Pick the Right TLD
- Does the shipping country have its own Amazon store? -> Use that TLD
- Is it covered by a regional hub above? -> Use the regional hub's TLD
- Not sure? -> Use
amazon.com(US) — it ships to 200+ countries
How to Construct the URL
- Find the product's ASIN (the
B0xxxxxxxxID) - Use the format:
https://{tld}/dp/{ASIN} - Example for France:
https://amazon.fr/dp/B08N5WRWNW - Example for Japan:
https://amazon.co.jp/dp/B08N5WRWNW
Points & Potential Airdrop
Every order placed through SP3ND earns SP3ND points. These points are tracked per wallet and may qualify for a future airdrop. The more orders your agent places, the more points you accumulate. This applies to all agent orders — there's no separate opt-in required.
Complete Code Example (Node.js)
Proven working on mainnet. See
scripts/x402-pay-with-memo.mjsfor the full standalone script.
// Install: npm install @solana/web3.js @solana/spl-token @solana/spl-memo
import {
Connection, Keypair, PublicKey,
TransactionMessage, VersionedTransaction, ComputeBudgetProgram
} from '@solana/web3.js';
import { getAssociatedTokenAddress, createTransferCheckedInstruction } from '@solana/spl-token';
import { createMemoInstruction } from '@solana/spl-memo';
const BASE_URL = 'https://us-central1-sp3nddotshop-prod.cloudfunctions.net';
const FACILITATOR = 'https://facilitator.payai.network';
const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
// Your agent's credentials (from registerAgent)
const API_KEY = process.env.SP3ND_API_KEY;
const API_SECRET = process.env.SP3ND_API_SECRET;
// Your agent's Solana keypair (must hold USDC)
const keypair = Keypair.fromSecretKey(
Uint8Array.from(JSON.parse(process.env.SOLANA_PRIVATE_KEY))
);
const connection = new Connection(process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com');
const headers = { 'Content-Type': 'application/json', 'X-API-Key': API_KEY, 'X-API-Secret': API_SECRET };
async function buyFromAmazon(productUrl, quantity, customerEmail, shippingAddress) {
// 1. Create cart
const cartRes = await fetch(`${BASE_URL}/createPartnerCart`, {
method: 'POST', headers,
body: JSON.stringify({ items: [{ product_url: productUrl, quantity }] })
});
const cart = await cartRes.json();
// 2. Create order
const orderRes = await fetch(`${BASE_URL}/createPartnerOrder`, {
method: 'POST', headers,
body: JSON.stringify({
cart_id: cart.cart.cart_id,
customer_email: customerEmail,
shipping_address: shippingAddress
})
});
const order = (await orderRes.json()).order;
// 3. First call to payAgentOrder — returns 402 with PAYMENT-REQUIRED header
const firstRes = await fetch(`${BASE_URL}/payAgentOrder`, {
method: 'POST', headers,
body: JSON.stringify({ order_id: order.order_id, order_number: order.order_number })
});
if (firstRes.status !== 402) return await firstRes.json();
// 4. Decode payment requirements from PAYMENT-REQUIRED header
const paymentRequiredHeader = firstRes.headers.get('PAYMENT-REQUIRED');
const paymentRequired = JSON.parse(Buffer.from(paymentRequiredHeader, 'base64').toString('utf8'));
const req = paymentRequired.accepts[0];
// 5. Build VersionedTransaction with USDC transfer + memo
const payTo = new PublicKey(req.payTo);
const feePayer = new PublicKey(req.extra.feePayer); // PayAI pays gas — NOT your agent
const amount = BigInt(req.maxAmountRequired);
const sourceATA = await getAssociatedTokenAddress(USDC_MINT, keypair.publicKey);
const destATA = await getAssociatedTokenAddress(USDC_MINT, payTo);
const { blockhash } = await connection.getLatestBlockhash();
const instructions = [
ComputeBudgetProgram.setComputeUnitLimit({ units: 30000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }),
createTransferCheckedInstruction(sourceATA, USDC_MINT, destATA, keypair.publicKey, amount, 6),
createMemoInstruction(`SP3ND Order: ${req.extra.order_number}`), // REQUIRED for payment matching
];
const message = new TransactionMessage({ payerKey: feePayer, recentBlockhash: blockhash, instructions });
const tx = new VersionedTransaction(message.compileToV0Message());
tx.sign([keypair]);
// 6. Build x402 v1 payment payload
const base64Tx = Buffer.from(tx.serialize()).toString('base64');
const v1Payload = {
x402Version: 1, scheme: 'exact', network: 'solana',
payload: { transaction: base64Tx }
};
const v1Req = {
scheme: 'exact', network: 'solana',
maxAmountRequired: req.maxAmountRequired,
amount: req.maxAmountRequired,
resource: req.resource,
payTo: req.payTo,
maxTimeoutSeconds: req.maxTimeoutSeconds,
asset: req.asset,
extra: req.extra,
};
// 7. Verify with facilitator
const verifyRes = await fetch(`${FACILITATOR}/verify`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ paymentPayload: v1Payload, paymentRequirements: v1Req })
});
const verified = await verifyRes.json();
if (!verified.isValid) throw new Error(`Verify failed: ${verified.invalidReason}`);
// 8. Settle with facilitator (broadcasts tx to Solana)
const settleRes = await fetch(`${FACILITATOR}/settle`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ paymentPayload: v1Payload, paymentRequirements: v1Req })
});
const settled = await settleRes.json();
if (!settled.success) throw new Error(`Settle failed: ${settled.errorReason}`);
// 9. Poll for payment confirmation (Helius webhook marks order paid within ~60s)
const ORDER_TIMEOUT_MS = 90_000;
const POLL_INTERVAL_MS = 5_000;
const deadline = Date.now() + ORDER_TIMEOUT_MS;
console.log('Waiting for payment confirmation...');
while (Date.now() < deadline) {
await new Promise(r => setTimeout(r, POLL_INTERVAL_MS));
const statusRes = await fetch(`${BASE_URL}/getPartnerOrders`, { headers });
const { orders } = await statusRes.json();
const thisOrder = orders.find(o => o.order_number === order.order_number);
if (thisOrder?.status === 'Paid') {
console.log('Order paid! ✅', settled.transaction);
return thisOrder;
}
console.log(' Status:', thisOrder?.status, '— checking again...');
}
throw new Error('Payment timeout — USDC transferred on-chain, Helius may still be processing');
}
Key Facts for Agents
- Registration: Instant via
POST /registerAgent— no approval queue - Platform fee: 0% by default — agents pay no platform fee
- Payment protocol: x402 (HTTP 402 Payment Required) — fully autonomous
- Payment currency: USDC on Solana
- Supported retailers: Amazon (22 country TLDs — see table above)
- CRITICAL: Always use the Amazon TLD that matches the shipping country (e.g.
.defor Germany,.co.ukfor UK,.com.brfor Brazil) - Free Prime shipping: Prime-eligible items ship free via SP3ND's Prime accounts (some surrounding regions may have standard shipping fees)
- Shipping: 200+ countries
- No KYC required
- Points & Airdrop: Every order earns SP3ND points toward a potential future airdrop
- Cart expiration: 30 minutes
- Treasury wallet:
2nkTRv3qxk7n2eYYjFAndReVXaV7sTF3Z9pNimvp5jcp - USDC mint (Solana mainnet):
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v - x402 facilitator:
https://facilitator.payai.network - Support: support@sp3nd.shop
- Full API docs: https://sp3nd.shop/partner-api/docs
- Dashboard: https://sp3nd.shop/partner-api/dashboard
Alternative: Manual Payment Flow (for human partners)
If your agent cannot use x402, you can still use the manual payment flow:
- Call
createPartnerTransactionto register the payment intent - Manually send USDC to the treasury wallet with memo
SP3ND Order: <order_number> - SP3ND detects the payment automatically within 1 minute
See the Partner API docs for details: https://sp3nd.shop/partner-api/docs