About cryptorefills-buy
cryptorefills-buy is an agent skill for purchasing gift cards, mobile top-ups, and eSIMs with cryptocurrency through Cryptorefills. It documents both a step-by-step order flow and an interactive guided flow, with explicit confirmation and spending safeguards.
Key features
- 01Search products and brands
- 02Check prices and validate orders
- 03Create and track purchases
- 04Support carts of up to 10 items
- 05Guide purchases interactively
- 06Require confirmation and spending limits
Use cases
- 01Buy a gift card with cryptocurrency
- 02Pay for a mobile top-up
- 03Purchase an eSIM with crypto
- 04Check payment and delivery status
MCP support
The skill requires an MCP client connected to Cryptorefills at https://api.cryptorefills.com/mcp/http. It describes tools for product search, pricing, validation, ordering, and status tracking.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ cryptorefills/ agents --skill cryptorefills-buyAfter installing, type/cryptorefills-buyin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/mcp-tools.mdorder-lifecycle.mdpayment-methods.mdtroubleshooting.mdDetails
From the project READMECryptorefills Buy — MCP Purchase Workflow
Full purchase lifecycle: search, price, validate, order, pay, track delivery. Supports all crypto payment methods, fixed and range-based products, multi-product carts, and interactive guided purchasing.
For browse-only, follow the instructions in cryptorefills-catalog. For autonomous agent purchases with USDC on Base (no account), follow cryptorefills-x402 instead.
When the user needs autonomous wallet-based purchasing without human payment interaction, switch to the cryptorefills-x402 skill instructions.
When to Activate
- User wants to buy a gift card, top up a phone, or get an eSIM with crypto
- User mentions paying with Bitcoin, Lightning, Ethereum, Solana, USDC, USDT, Litecoin, Dogecoin, TON, SUI, or other cryptocurrency
- User wants to place an order or complete a purchase on Cryptorefills
- User needs help checking order status or tracking delivery
- Keywords: "buy gift card with crypto", "pay with bitcoin", "pay with ethereum", "pay with solana", "purchase esim", "top up phone with USDC", "buy with USDT", "pay with litecoin", "pay with dogecoin"
Requirements
- MCP client connected to
https://api.cryptorefills.com/mcp/http - Required header:
User-Agent: Cryptorefills-MCP/1.0 - Crypto wallet for payment
- No Cryptorefills account or API key needed
To configure the MCP connection in Claude Code:
{
"mcpServers": {
"cryptorefills": {
"url": "https://api.cryptorefills.com/mcp/http",
"headers": { "User-Agent": "Cryptorefills-MCP/1.0" }
}
}
}
Spending Safeguards
Always confirm before purchasing. Present product name, denomination, price, and payment method — wait for explicit user approval before calling createOrder.
- Set a per-session spending limit (default: $100 max per session, $50 max per transaction — increase only if the user explicitly requests it) and track cumulative spend across orders
- Verify the quoted price from
getProductPricebefore proceeding tocreateOrder - Digital goods are non-refundable once delivered
- Gift card codes are cash-like — store securely, never share publicly or write to files
- Keep codes in memory until the user redeems them
- Log every purchase: order ID, product, amount, payment method
- Use a dedicated wallet with limited balance for agent-initiated purchases
- Terms: https://www.cryptorefills.com/terms/
Core Workflow
searchProducts → getProductPrice → validateOrder → createOrder → getOrderStatus
│ │
└── or use purchaseElicitation ────────────────┘
Two paths to purchase:
- Manual flow — Search → price → validate → create → track (full control)
- Guided flow —
purchaseElicitationwalks through the purchase interactively (recommended for conversational agents)
Step-by-Step: Manual Flow
1. Search / Discover
Use searchProducts or listBrands to find products.
searchProducts(country_code="US", q="Netflix")
Note: The search parameter is q (not query), and language is lang (not language).
Country codes must be uppercase Alpha-2 ISO (US, IT, BR). Note: the x402 skill uses lowercase — different endpoint.
2. Get Price
Fixed-denomination products (is_dynamic: false): Price is already in the listProductsForCountry response (coin_amount field). No extra call needed.
Range-based products (is_dynamic: true): Use getProductPrice to get the price for a specific amount within the range.
getProductPrice(brand_name="Amazon.com", country_code="US", face_value=75, coin="USDC")
face_value is a number (75), not a string. Returns coin_amount with the exact crypto price.
3. Validate Order
Use validateOrder before creating. Both validateOrder and createOrder use a body wrapper with payment and deliveries.
validateOrder(body={
payment: {type: "via", payment_via: "USER_WALLET", coin: "BTC", network: "Mainnet"},
deliveries: [{
denomination: "25 USD",
brand_name: "Steam",
beneficiary_account: "[email protected]",
country_code: "US"
}]
})
Key fields:
payment.type— always"via"for crypto paymentspayment.payment_via— fromgetPaymentViasWithCurrencies(e.g.,"USER_WALLET")payment.coin— cryptocurrency (e.g.,"BTC","USDC")payment.network— use the exact string fromgetPaymentViasWithCurrencies. Common values:
| Coin | network value |
|---|---|
| BTC | Mainnet |
| ETH | ETH Mainnet |
| USDC | Base, Polygon (Matic), Solana, Arbitrum |
| USDT | Polygon (Matic), Tron |
| SOL | Solana |
deliveries[].denomination— for fixed products: exact string fromlistProductsForCountry(e.g.,"25 USD"). For range products: the literal string"range"(plusproduct_valuewith the desired amount)deliveries[].brand_name— exact brand name fromlistBrandsdeliveries[].beneficiary_account— email for gift cards/eSIMs, E.164 phone for mobile rechargedeliveries[].country_code— uppercase Alpha-2
Catches errors early: invalid phone, out-of-range amount, unavailable product, minimum order amount.
4. Create Order
Same body schema as validateOrder, plus user.email is required.
createOrder(body={
user: {email: "[email protected]"},
payment: {type: "via", payment_via: "USER_WALLET", coin: "BTC", network: "Mainnet"},
deliveries: [{
denomination: "25 USD",
brand_name: "Steam",
beneficiary_account: "[email protected]",
country_code: "US"
}]
})
Returns: order_id, wallet_address, coin_amount, qr_url, qr_text (payment URI), payment_state, order_state.
Presenting payment to the user: In text-only environments, present the qr_text payment URI (e.g., bitcoin:3EFu...?amount=0.00038) — wallets can parse it directly. In rich environments, link to or render the qr_url image.
Multi-product orders: Include up to 10 items in the deliveries array. Each can be a different brand/country/delivery type.
5. Track Order
Poll getOrderStatus with the order ID.
- Poll interval: Every 30 seconds
- Payment states:
WalletCreated→PaymentRequested→PaymentReceived(orExpired) - Order states:
WaitingForPayment→Done(success) /Expired/Canceled/WaitingForManualAction - Payment windows: Lightning invoices expire in ~15 minutes. On-chain payments expire in ~60–180 minutes depending on method.
Stop polling when order reaches a terminal state.
6. Deliver
When order state is Done:
- Gift cards: Code/PIN in
deliverable.pin_code. If it starts withhttp/https, it's a URL to visit. Plain text is a manual redemption code. - Mobile top-ups: Applied automatically to the phone number. No code to deliver.
- eSIMs: QR code and activation instructions in order details.
Worked Examples (3 Product Types)
Example A: Gift Card — Steam $25 US (BTC)
1. searchProducts(country_code="US", q="Steam")
→ finds brand "Steam", category "games"
2. listProductsForCountry(country_code="US", brand_name="Steam", coin="BTC")
→ products: [{product_id: "a300c244-...", denomination: "25 USD", coin_amount: "0.00038", is_dynamic: false}]
3. validateOrder(body={
payment: {type: "via", payment_via: "USER_WALLET", coin: "BTC", network: "Mainnet"},
deliveries: [{denomination: "25 USD", brand_name: "Steam", beneficiary_account: "[email protected]", country_code: "US"}]
})
→ coin_amount: "0.00038", problems: [] (valid)
4. createOrder(body={
user: {email: "[email protected]"},
payment: {type: "via", payment_via: "USER_WALLET", coin: "BTC", network: "Mainnet"},
deliveries: [{denomination: "25 USD", brand_name: "Steam", beneficiary_account: "[email protected]", country_code: "US"}]
})
→ order_id: "e054...", wallet_address: "3EFu...", coin_amount: "0.00038", qr_text: "bitcoin:3EFu...?amount=0.00038"
5. getOrderStatus(order_id="e054...")
→ payment_state: "PaymentRequested", order_state: "WaitingForPayment"
Example A2: Range Gift Card — Amazon.com $50 US (USDC on Base)
1. searchProducts(country_code="US", q="Amazon")
→ finds brand "Amazon.com", is_dynamic: true, range $5–$500
2. getProductPrice(brand_name="Amazon.com", country_code="US", face_value=50, coin="USDC")
→ coin_amount: "51.08", product_id: "5549e92e-..."
3. validateOrder(body={
payment: {type: "via", payment_via: "USER_WALLET", coin: "USDC", network: "Base"},
deliveries: [{denomination: "range", brand_name: "Amazon.com", beneficiary_account: "[email protected]", country_code: "US", product_value: "50"}]
})
→ coin_amount: "51.08", problems: [] (valid)
→ Note: denomination is "range" (literal string), product_value is "50" (desired amount)
4. createOrder(body={
user: {email: "[email protected]"},
payment: {type: "via", payment_via: "USER_WALLET", coin: "USDC", network: "Base"},
deliveries: [{denomination: "range", brand_name: "Amazon.com", beneficiary_account: "[email protected]", country_code: "US", product_value: "50"}]
})
→ order_id, wallet_address (USDC on Base), coin_amount: "51.08"
Example B: Mobile Top-up — Claro 15 BRL Brazil (USDC on Base)
1. searchProducts(country_code="BR", q="Claro")
→ finds brand "Claro Credits", category "mobile_credits"
2. listProductsForCountry(country_code="BR", brand_name="Claro Credits", coin="USDC")
→ products: [{denomination: "15 BRL", delivery_type: "by_phone", is_dynamic: false}]
3. validateOrder(body={
payment: {type: "via", payment_via: "USER_WALLET", coin: "USDC", network: "Base"},
deliveries: [{denomination: "15 BRL", brand_name: "Claro Credits", beneficiary_account: "+5511999887766", country_code: "BR"}]
})
→ Note: beneficiary_account is the E.164 phone number (not email)
4. createOrder(body={
user: {email: "[email protected]"},
payment: {type: "via", payment_via: "USER_WALLET", coin: "USDC", network: "Base"},
deliveries: [{denomination: "15 BRL", brand_name: "Claro Credits", beneficiary_account: "+5511999887766", country_code: "BR"}]
})
→ order_id, wallet_address (USDC on Base), coin_amount
Example C: eSIM — Italy data plan (ETH)
1. searchProducts(country_code="IT", q="eSIM")
→ finds brand "eSIM", category "e-sim"
2. listProductsForCountry(country_code="IT", brand_name="eSIM", coin="ETH")
→ products: [{denomination: "1 GB 7 days", delivery_type: "by_email", is_dynamic: false}]
3. validateOrder(body={
payment: {type: "via", payment_via: "USER_WALLET", coin: "ETH", network: "ETH Mainnet"},
deliveries: [{denomination: "1 GB 7 days", brand_name: "eSIM", beneficiary_account: "[email protected]", country_code: "IT"}]
})
→ Note: denomination is "1 GB 7 days" (exact string from listProductsForCountry), beneficiary is email
4. createOrder(body={
user: {email: "[email protected]"},
payment: {type: "via", payment_via: "USER_WALLET", coin: "ETH", network: "ETH Mainnet"},
deliveries: [{denomination: "1 GB 7 days", brand_name: "eSIM", beneficiary_account: "[email protected]", country_code: "IT"}]
})
→ order_id, wallet_address (ETH), coin_amount, qr_text
Step-by-Step: Guided Elicitation
purchaseElicitation is an interactive, stateful tool that guides the agent through the entire purchase. Ideal for conversational UIs.
- Call
purchaseElicitationwith empty body{}(optionally passlangfor localized prompts) — receive asession_token - The server returns a question (e.g., "What country?", "Which brand?", "What denomination?")
- Pass the user's answer back with the
session_token - Repeat until
statusequalscomplete(order created) orerror - Use
action: "back"to revert a step if the user changes their mind
The elicitation handles product selection, denomination, delivery info, and payment method selection internally. It's the simplest path from intent to purchase.
Critical Gotchas
- Phone numbers: Must be E.164 format —
+prefix, country code, number, no spaces or dashes - Country codes: Uppercase for MCP tools (
US, notus). The x402 skill uses lowercase - Country match: Product country must match where the recipient will redeem
- Range amounts: Must fall within
min_valueandmax_value. Out-of-bounds amounts are rejected - Validate first: Always call
validateOrderbeforecreateOrderto catch errors - Payment timeout: Lightning ~15 min, on-chain ~60–180 min. Create a new order if expired
- WaitingForManualAction: Means Cryptorefills support is reviewing — inform the user and wait
- Cart limit: Maximum 10 items per
createOrdercall. Split larger orders into multiple calls - Currency in pricing: Prices quoted in fiat; payment in crypto at locked exchange rate
References
Load references only when you need deeper detail than what's in this skill file.
| File | Load when... | Content |
|---|---|---|
references/mcp-tools.md | You need exact parameter schemas for a specific MCP tool call | All 10 MCP tool signatures with parameters |
references/payment-methods.md | User asks about specific chains, networks, or payment routing | Supported cryptocurrencies, chains, payment flow |
references/order-lifecycle.md | Order enters an unexpected state or you need delivery/polling details | Order and payment state machines, delivery types |
references/troubleshooting.md | A tool call returns an error or order is stuck | Common errors, recovery steps |