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'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"
}'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"
}
}
],
"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"
}
}'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