Laso Finance: USA prepaid cards for agent checkouts logoLaso Finance: USA prepaid cards for agent checkouts
Sign in with SIWX, pay GET /get-card over x402, then poll GET /get-card-data until the card is ready. USA merchants, caller use, no fee.
devrels.xyz/a/317Laso Finance turns USDC into a card an agent can type into a normal checkout. The agent-facing API lives at agents.laso.finance. Paid calls settle over x402 in USDC on Solana or Base.
This piece is the USA prepaid card. You learn the checkout total, pay GET /get-card, then poll GET /get-card-data until the number is ready. The card is for the caller, for US merchants, in USD.
Laso Finance LLC is a FinCEN-registered money services business in Austin (MSB 31000328975254), founded March 2023. Agent discovery starts at laso.finance/SKILL.md.
What you get
GET /get-card buys a non-reloadable USA prepaid card. The USDC you pay is the amount on the card. There is no extra fee on this route. Order for the exact checkout total when you know tax and shipping. Leftover balance still spends at another US merchant until the card expires.
| Rule | Value |
|---|---|
| Load | $5 to $1000, USD, no fee |
| Where it spends | US merchants, USD only, physical goods to a US address |
| Who may use it | The calling wallet. Cards are non-transferable |
| Reload | No. Multiple purchases until the balance hits zero |
| Issue time | About 7 to 10 seconds after payment |
| Expiry | 6 months. Remaining balance is forfeited |
Do not treat this as a payout product or a rewards card. Laso states the endpoint is for the caller's own use. Banking and money-transfer merchants come back as not_accepted on GET /search-merchants because that spend is a transfer of value.
A separate route, GET /order-intl-card, covers non-US merchants. It is queued, whole dollars from $100 to $1000, plus a 3.8 percent fee. Stay on /get-card when the merchant and the ship-to address are in the United States.
Sign in with the wallet
Identity is the wallet. GET /auth is free. Send a SIGN-IN-WITH-X header: a base64-encoded CAIP-122 signed message bound to laso.finance. The nonce is single use. Signatures older than five minutes are rejected. A failed proof returns 402, not 401, with a fresh challenge in the PAYMENT-REQUIRED header. Sign the new challenge. Do not resend the old payload.
Supported chains in the auth guide: Base (eip155:8453, eip191) and Solana mainnet (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp, ed25519). The documented helper is wrapFetchWithSIWx from @x402/extensions/sign-in-with-x.
import { wrapFetchWithSIWx } from "@x402/extensions/sign-in-with-x"
import { privateKeyToAccount } from "viem/accounts"
const signer = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY)
const fetchWithSiwx = wrapFetchWithSIWx(fetch, signer)
const res = await fetchWithSiwx("https://laso.finance/auth")
const { auth, user_id } = await res.json()
// persist auth.id_token and auth.refresh_token; never log themThat snippet is the EVM path from the docs. A Solana agent uses the same header and an ed25519 signer. user_id is the lowercased wallet address. It is not a deposit address.
Save id_token and refresh_token. The ID token lasts about an hour (expires_in is typically 3600). Use it as Authorization: Bearer on free routes such as /get-card-data. Refresh with POST /auth and { "grant_type": "refresh_token", "refresh_token": "..." }. Store the new refresh token from every response. If you drop it, you sign GET /auth again.
Pay, then poll
Walk the merchant checkout first. Read the exact total, including tax and shipping. Then call GET https://laso.finance/get-card?amount=X where X is that total. Live OpenAPI is GET, query param amount, server https://laso.finance.
A call without payment comes back 402. The JSON body is empty. Price, recipient, and network sit in the PAYMENT-REQUIRED header. An x402 client builds the payment header and retries. OpenAPI lists USDC on Base and on Solana mainnet for this route. Paywalled orders also return auth credentials, so a first card order can skip a separate /auth if you persist those tokens.
Three checks run, and only those three:
- Amount in range, or 400 with the accepted band ($5 to $1000).
- x402 payment settles, or 402 again so you can replay.
- Account is not frozen, or 403 with
error: "Account is frozen"and afrozen_message.
Card orders do not read identity-verification status. There is no kyc_required field on /get-card. KYC is for other products such as Venmo and PayPal sends.
A 200 returns card.card_id and card.status: "pending". It does not return the PAN, CVV, or expiry. Poll every 2 to 3 seconds:
curl "https://laso.finance/get-card-data?card_id=$CARD_ID" \
-H "Authorization: Bearer $LASO_ID_TOKEN"Stop when status is ready, then read card_details: card_number, exp_month, exp_year, cvv, available_balance, and billing_address. If it is still pending after about 30 seconds, log the card_id and stop hammering. Do not print PAN or CVV into chat logs, traces, or example fixtures. Keep those fields in a secret store the checkout step can read.
When the merchant asks for a billing name or ZIP, use card_details.billing_address. The billing name is always Laso Finance. For USA cards the address is a known-good default (ZIP 91723). Docs say any valid US billing address works on this product.
Check the merchant first
GET /search-merchants?q=NAME is free with a Bearer token. Default catalog is the USA non-reloadable card. Status is accepted, not_accepted, or unknown. A missing merchant only means nobody in the dataset has tried it yet.
curl "https://laso.finance/search-merchants?q=amazon" \
-H "Authorization: Bearer $LASO_ID_TOKEN"If the row is not_accepted, do not buy a card for that checkout. Banking and money-transfer names stay not_accepted even when an approval once went through.
If the agent has no key
A self-custody x402 wallet (Locus, Sponge, Ampersend, or your own signer) can pay /get-card directly. If the agent should not hold a key, Laso custodies a Solana wallet on the account. Fund it with USDC on Solana. The agent calls getAgentWallet for the address and needs_funding, then agentX402Pay with route: "get-card". The callable base is still https://laso.finance.
First-time setup for a managed account is the skill helper, not a handmade JSON body. Docs version hash at ship time was 5676e73cb1f3. Recheck docs-version.json if you cache the skill.
curl -fsS --create-dirs https://laso.finance/skills/laso-finance/scripts/setup.py \
-o ~/.laso/setup.py
python3 ~/.laso/setup.py --agent-name "YOUR AGENT NAME"The helper writes ~/.laso/credentials.json with owner-only permissions and does not print keys. A usr_... id is not the deposit address. When wallet.needs_funding is true, give the human the full wallet.wallet_address and say USDC on Solana.
Same API is also MCP at laso.finance/mcp. Paid tools settle from the managed wallet. That does not change the HTTP contract above.
Guardrails
Keep the agent inside the product rules. USA card, US merchant, US ship-to, caller spends it. Do not split a purchase to dodge a spend limit. Do not log PAN, CVV, ID tokens, or refresh tokens. POST /register-webhook can hint when an order completes (Standard Webhooks, secret shown once). Status endpoints stay the source of truth. Deliveries are not retried.
Pin the live OpenAPI rather than copying request bodies from memory. laso.finance/openapi.json is OpenAPI 3.1, title Laso Finance x402 API, production server https://laso.finance. Gift cards, push-to-card, bank payouts, and reloadable cards are other routes. Wire those from the spec when you need them.
Related DevRels reading: the x402 handshake, pay.sh as a CLI over the same 402, and PayAI as a Solana facilitator. Laso is the card issuer sitting on that payment layer.
People and links
| What | Where |
|---|---|
| Product | laso.finance |
| Agent docs | agents.laso.finance |
| USA card guide | guides/usa-prepaid-card |
| Auth | guides/authentication |
| Skill | laso.finance/SKILL.md |
| OpenAPI | laso.finance/openapi.json |
| GitHub | LasoFinance/docs |
| X | @LasoFinance |
| Founder | Hunter, Laso Finance |
Keep reading
MCPay sits in front of existing MCP servers: 402 → pay USDC → retry tool call. Open-source proxy + JS SDK.
Every API you use today requires an account, a key, a billing portal, and a rotation policy. x402 collapses that to one HTTP header. pay.sh implements it as a single binary that wraps curl — 76 providers across AI, data, compute, messaging, finance, and more. No keys to manage. No subscriptions.
The largest edge network on earth just made HTTP 402 a product. The Monetization Gateway does metering, the payment exchange, and settlement at Cloudflare's edge — and it's built on x402, whose 'exact' scheme runs on Solana with USDC. For Solana x402 sellers, the origin middleware you run today can move to the edge, and the strategic signal is enormous.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
