Authentification
# Required headers for every API request
-H 'X-Cr-Application: YOUR_PARTNER_ID'
-H 'X-Cr-Version: YOUR_APP_VERSION'
-H 'X-Country-ISO-Code: US'
-H 'Content-Type: application/json'Méthodes de paiement
/v3/payment_viascurl -X GET 'https://api.cryptorefills.com/v3/payment_vias' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Recommandé : L'USDC sur Solana offre les frais les plus bas et le règlement le plus rapide.
Catalogue de marques
/v2/brands?country_code={countryCode}curl -X GET 'https://api.cryptorefills.com/v2/brands?country_code=US' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Variantes d'URL de logo
Chaque marque renvoie un logo_url (par défaut) et un logo_base_url. Ajoutez un suffixe à logo_base_url pour récupérer des tailles et des formats optimisés.
.webpRecommandé
{logo_base_url}.webp{logo_base_url}_500x318.webp{logo_base_url}_300x190.webp
.jpg
{logo_base_url}.jpg{logo_base_url}_500x318.jpg{logo_base_url}_300x190.jpg
Exemple : https://cdn.cryptorefills.com/logos_v2/esim_500x318.webp
Codes de pays pris en charge
233GET https://cryptorefills.com/api/available-countriesAXÅland IslandsALAlbaniaDZAlgeriaASAmerican SamoaADAndorraAOAngolaAIAnguillaAQAntarcticaAGAntigua and BarbudaARArgentinaAMArmeniaAWArubaAUAustraliaATAustriaAZAzerbaijanBSBahamasBHBahrainBDBangladeshBBBarbadosBEBelgiumBZBelizeBJBeninBMBermudaBTBhutanBOBoliviaBQBonaire, Sint Eustatius and SabaBABosnia and HerzegovinaBWBotswanaBVBouvet IslandBRBrazilIOBritish Indian Ocean TerritoryBNBrunei DarussalamBGBulgariaBFBurkina FasoBIBurundiCVCabo VerdeKHCambodiaCMCameroonCACanadaKYCayman IslandsTDChadCLChileCNChinaCXChristmas IslandCCCocos (Keeling) IslandsCOColombiaKMComorosCGCongoCKCook IslandsCRCosta RicaCICôte d'IvoireHRCroatiaCWCuraçaoCYCyprusCZCzechiaDKDenmarkDJDjiboutiDMDominicaDODominican RepublicECEcuadorEGEgyptSVEl SalvadorGQEquatorial GuineaEREritreaEEEstoniaSZEswatiniETEthiopiaFKFalkland IslandsFOFaroe IslandsFJFijiFIFinlandFRFranceGFFrench GuianaPFFrench PolynesiaTFFrench Southern TerritoriesGAGabonGMGambiaGEGeorgiaDEGermanyGHGhanaGIGibraltarGRGreeceGLGreenlandGDGrenadaGPGuadeloupeGUGuamGTGuatemalaGGGuernseyGNGuineaGWGuinea-BissauGYGuyanaHTHaitiHMHeard Island and McDonald IslandsHNHondurasHKHong KongHUHungaryISIcelandINIndiaIDIndonesiaIEIrelandIMIsle of ManILIsraelITItalyJMJamaicaJPJapanJEJerseyJOJordanKZKazakhstanKEKenyaKIKiribatiXKKosovoKWKuwaitKGKyrgyzstanLALaosLVLatviaLBLebanonLSLesothoLRLiberiaLILiechtensteinLTLithuaniaLULuxembourgMOMacaoMGMadagascarMWMalawiMYMalaysiaMVMaldivesMTMaltaMHMarshall IslandsMQMartiniqueMRMauritaniaMUMauritiusYTMayotteMXMexicoFMMicronesiaMDMoldovaMCMonacoMNMongoliaMEMontenegroMSMontserratMAMoroccoMZMozambiqueNANamibiaNRNauruNPNepalNLNetherlandsNCNew CaledoniaNZNew ZealandNINicaraguaNENigerNGNigeriaNUNiueNFNorfolk IslandMKNorth MacedoniaMPNorthern Mariana IslandsNONorwayOMOmanPKPakistanPWPalauPSPalestinePAPanamaPGPapua New GuineaPYParaguayPEPeruPHPhilippinesPNPitcairnPLPolandPTPortugalPRPuerto RicoQAQatarRERéunionRORomaniaRWRwandaBLSaint BarthélemySHSaint HelenaKNSaint Kitts and NevisLCSaint LuciaMFSaint Martin (French part)PMSaint Pierre and MiquelonVCSaint Vincent and the GrenadinesWSSamoaSMSan MarinoSTSao Tome and PrincipeSASaudi ArabiaSNSenegalRSSerbiaSCSeychellesSLSierra LeoneSGSingaporeSXSint MaartenSKSlovakiaSISloveniaSBSolomon IslandsSOSomaliaZASouth AfricaGSSouth Georgia and the South Sandwich IslandsKRSouth KoreaESSpainLKSri LankaSRSurinameSJSvalbard and Jan MayenSESwedenCHSwitzerlandTWTaiwanTJTajikistanTZTanzaniaTHThailandTLTimor-LesteTGTogoTKTokelauTOTongaTTTrinidad and TobagoTNTunisiaTRTürkiyeTMTurkmenistanTCTurks and Caicos IslandsTVTuvaluUGUgandaUAUkraineAEUnited Arab EmiratesGBUnited KingdomUSUnited StatesUMUnited States Minor Outlying IslandsUYUruguayUZUzbekistanVUVanuatuVAVatican CityVNVietnamVGVirgin Islands (British)VIVirgin Islands (U.S.)WFWallis and FutunaEHWestern SaharaYEYemenZMZambia
Fil d'accueil
/v2/homepage?country_code={countryCode}curl -X GET 'https://api.cryptorefills.com/v2/homepage?country_code=US' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Parcourir les produits
/v5/products/country/{countryCode}curl -X GET 'https://api.cryptorefills.com/v5/products/country/US?family_name=airbnb&coin=USDC&lang=en' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Obtenir le prix de la crypto
/v4/products/pricecurl -X GET 'https://api.cryptorefills.com/v4/products/price?brand_name=Airbnb&country_code=US&face_value=100&coin=USDC' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Valider la commande
/v5/orders/validationscurl -X POST 'https://api.cryptorefills.com/v5/orders/validations' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION' \
-d '{
"email": "END_USER_EMAIL",
"payment": {
"type": "via",
"payment_via": "USER_WALLET",
"coin": "USDC"
},
"deliveries": [
{
"beneficiary_account": "END_USER_EMAIL",
"brand_name": "Airbnb",
"country_code": "US",
"denomination": "100 USD",
"localized_denomination": "$100"
}
],
"lang": "en"
}'Erreurs possibles
La réponse renvoie un tableau de problèmes. Chaque entrée a la forme { problème, plus de détails ? }, et plusieurs problèmes peuvent être renvoyés à la fois. Les erreurs HTTP de niveau supérieur (suspensions) reviennent sous la forme { statut, détail, plus de détails ? } à la place.
Order amount & limits
AMOUNT_LESS_THEN_MINIMUM_ALLOWEDOrder total is below the minimum coin amount allowed.MAXIMUM_AMOUNT_PER_ORDER_EXCEEDEDOrder total exceeds the per-order maximum.DAILY_SPENDING_LIMIT_EXCEEDEDUser has hit the daily spending limit for their tier.MONTHLY_SPENDING_LIMIT_EXCEEDEDUser has hit the monthly spending limit for their tier.PRODUCT_COUNT_EXCEEDEDCart contains more products than the per-order maximum.MULTIPLE_LIMITED_PRODUCT_SAME_ORDEROrder contains more than one rate-limited product.
Product availability
NOT_AVAILABLE_PRODUCTProduct is no longer in the catalogue.OUT_OF_STOCKProduct is currently out of stock.NOT_ACTIVEProduct is inactive or paused.INVALID_BENEFICIARY_ACCOUNTBeneficiary account is invalid — e.g. phone number for a mobile topup or email for a gift card.
Payment method & network
NOT_ALLOWED_PAYMENT_VIASelected payment_via is not allowed for this order. moreDetails lists allowed kinds.UNSUPPORTED_PROTOCOL_COIN_COMBINATIONChosen protocol + coin pair is not supported. moreDetails lists supported combinations.
Authentication
LOGIN_REQUIREDOne or more products require a signed-in user.COUPON_REQUIRES_LOGINThe coupon can only be redeemed by a signed-in user.
Coupon codes
COUPON_NOT_FOUNDCoupon code does not exist.COUPON_NOT_ACTIVECoupon is not yet active.COUPON_ALREADY_SPENTCoupon has already been redeemed by this user.COUPON_MAX_USAGE_REACHEDCoupon has reached its overall usage cap.COUPON_EXPIREDCoupon is past its validity date.COUPON_BELOW_MIN_AMOUNTOrder total is below the coupon’s minimum amount.COUPON_NOT_VALID_FOR_USERCoupon is not valid for this user.COUPON_NOT_VALID_FOR_CATEGORYCoupon does not apply to the selected product categories.COUPON_NOT_VALID_FOR_KINDCoupon does not apply to the selected product kind.COUPON_NOT_VALID_FOR_BRANDCoupon does not apply to the selected brands.COUPON_NOT_VALID_FOR_COUNTRYCoupon is not valid in the order country.COUPON_NOT_VALID_FOR_STORECoupon is not valid for the requested store or region.
HTTP-level errors (top-level detail field)
SUSPENDED_COINThe selected coin is temporarily suspended.SUSPENDED_NETWORKThe selected network is temporarily suspended.
Créer une commande
/v5/orderscurl -X POST 'https://api.cryptorefills.com/v5/orders' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION' \
-d '{
"deliveries": [
{
"kind": "giftcard",
"quantity": 1,
"deliverable": {
"brand_name": "Airbnb",
"country_code": "US",
"denomination": "100",
"beneficiary_account": "END_USER_EMAIL"
}
}
],
"payment": {
"type": "via",
"coin": "USDC",
"network": "Solana",
"payment_via": "USER_WALLET"
},
"user": {
"email": "END_USER_EMAIL",
"has_accepted_newsletter": true
},
"lang": "en",
"acquisition": {
"utm_source": "your_platform"
}
}'Compte bénéficiaire
Chaque livraison doit inclure un beneficiary_account dans son livrable, c'est là que Cryptorefills livre le produit. Le format requis dépend du type de produit.
- Cartes-cadeaux et eSIM : utilisez l'adresse e-mail de l'utilisateur final — par exemple
user@example.com. - Recharges mobiles : utilisez le numéro de téléphone du destinataire au format E.164, y compris le + et le code du pays — par exemple
+14155551234.
La réponse inclut wallet_address and coin_amount. Partagez ceci avec votre utilisateur.
Suivre la commande (API de flux)
/api/orders/{orderId}/subscribe- La route API reçoit
/api/orders/{orderId}/subscribeet transmet à l'amont/v5/orders/{orderId}/subscribe. - Le hook client ouvre
EventSourcevers la route API locale, valide les charges utiles et se reconnecte avec un backoff si nécessaire.
Code essentiel côté serveur
// app/api/orders/[orderId]/subscribe/route.ts
let upstream: Response;
try {
upstream = await fetch(
`https://api.cryptorefills.com/v5/orders/${params?.orderId}/subscribe`,
{
method: 'GET',
headers: {
...(await genHeader.server(session)),
'User-Agent': user_agent,
Accept: 'text/event-stream',
Connection: 'keep-alive',
},
},
);
} catch (err) {
return NextResponse.json(
{ error: 'Failed to connect to upstream stream' },
{ status: 502 },
);
}
if (!upstream.ok || !upstream.body) {
return NextResponse.json(
{ error: 'Upstream returned an error' },
{ status: upstream.status || 502 },
);
}
// stream = ReadableStream that proxies upstream SSE events
return new Response(stream, {
status: 200,
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache, no-transform',
Connection: 'keep-alive',
'X-Accel-Buffering': 'no',
},
});Code essentiel côté client
const { data: lastEvent, error } = useSWRSubscription<TOrderSchema>(
referenceOrderId ? `orders-info-stream-${referenceOrderId}` : null,
((key, { next }) => {
let es: EventSource | null = null;
let stopped = false;
let shouldReconnect = true;
let retryTimeout: number | null = null;
let retryDelay = 1000;
const cleanup = () => {
if (es) {
es.close();
es = null;
}
if (retryTimeout !== null) {
window.clearTimeout(retryTimeout);
retryTimeout = null;
}
};
const stopForever = () => {
shouldReconnect = false;
stopped = true;
cleanup();
};
const connect = () => {
if (stopped) return;
cleanup();
es = new EventSource(`/api/orders/${referenceOrderId}/subscribe`);
es.addEventListener('message', (ev) => {
try {
const raw = JSON.parse(ev.data);
const parsed = orderSchema.safeParse(raw);
if (!parsed.success) return;
retryDelay = 1000;
next(null, parsed.data as TOrderSchema);
} catch (err) {
next(err as Error);
}
});
es.addEventListener('stop', () => {
stopForever();
});
es.onerror = () => {
if (stopped || !shouldReconnect) return;
cleanup();
retryTimeout = window.setTimeout(() => {
retryDelay = Math.min(retryDelay * 2, 30000);
connect();
}, retryDelay);
};
};
connect();
return () => {
stopped = true;
cleanup();
};
}) as SubscriptionCallback<TOrderSchema>,
);Route dans ce dépôt
app/api/orders/[orderId]/subscribe/route.ts
Côté serveur (route API)
Utilise des en-têtes de serveur basés sur la session viagenHeader.server(session), puis appelle l'amont${process.env.API_URL}/v5/orders/${params?.orderId}/subscribe. En cas d'échec de connexion, il retourne502.
Côté client (hook)
OuvreEventSource vers/api/orders/${referenceOrderId}/subscribe, valide chaque charge utile avecorderSchema.safeParse, gèrestop les événements, et se reconnecte avec un backoff exponentiel.
Suivre la commande (sondage)
/v5/orders/{orderId}curl -X GET 'https://api.cryptorefills.com/v5/orders/ord_abc123xyz' \
-H 'Content-Type: application/json' \
-H 'X-Cr-Application: YOUR_PARTNER_ID' \
-H 'X-Cr-Version: YOUR_APP_VERSION'Utilisez le sondage lorsque
Vous ne pouvez pas maintenir une connexion SSE ouverte, ou votre environnement client ne prend pas en charge EventSource de manière fiable.
États de commande typiques
WaitingForPayment -> WaitingForDelivery -> Done