Authentification
Chaque requête de votre serveur utilise l'authentification HTTP Basic : l'identifiant du projet comme nom d'utilisateur et le secret du projet comme mot de passe. Gardez le secret sur votre serveur ; il signe aussi vos webhooks.
https://payments.rubysoft.io/api
Authorization: Basic base64(PROJECT_ID:PROJECT_SECRET)Créer une facture
Utilisez une facture lorsque le client paie une commande précise. Passez votre propre identifiant de commande de 24 caractères dans payload, le prix en USD, l'écart de montant toléré (0 à 5 %), la date d'expiration et l'URL qui reçoit les webhooks de cette facture.
payloadVotre identifiant de commande, 24 caractères hexadécimaux (un ObjectId MongoDB convient)meta[price]Prix en USDmeta[tolerancePercent]Écart toléré, de 0 à 5meta[expiresAt]Expiration, au format ISO 8601, dans le futurmeta[webhookUrl]Adresse de réception des événements de cette facturecurl -G https://payments.rubysoft.io/api/invoice/load \
-u "$PROJECT_ID:$PROJECT_SECRET" \
--data-urlencode "payload=65f2c1a9e4b0d3f7a2c91e04" \
--data-urlencode "meta[price]=120" \
--data-urlencode "meta[tolerancePercent]=1" \
--data-urlencode "meta[expiresAt]=2026-12-01T12:00:00Z" \
--data-urlencode "meta[webhookUrl]=https://shop.example/webhooks/rubynex"La réponse contient un objet addresses indexé par réseau. Affichez à votre client les réseaux que vous souhaitez proposer.
{
"id": "0b6f3c1e-8a52-4d7e-9c41-2f6a8d0e5b17",
"payload": "65f2c1a9e4b0d3f7a2c91e04",
"meta": {
"type": "invoice",
"status": "pending",
"price": "120",
"paid": "0",
"expiresAt": "2026-12-01T12:00:00.000Z"
},
"addresses": {
"tron": "T…",
"ethereum": "0x…",
"bsc": "0x…",
"bitcoin": "bc1q…"
}
}Adresses de dépôt permanentes
Utilisez les adresses permanentes pour les recharges : portefeuilles, jeux, exchanges, abonnements. Passez l'identifiant de 24 caractères de votre client dans payload et obtenez à chaque fois les mêmes adresses.
curl -G https://payments.rubysoft.io/api/charge/load \
-u "$PROJECT_ID:$PROJECT_SECRET" \
--data-urlencode "payload=66a0b7d2c5e8f1a3b6d904c7"
# the same customer ID always returns the same addressesStatuts de facture
pendingEn attente du paiementpaidLe prix complet est arrivéunderpaidLe montant reçu est inférieur au prixoverpaidLe montant reçu dépasse le prix de plus de 1 %expiredAucun paiement avant la date d'expirationWebhooks
Chaque événement est un POST avec un corps JSON et un en-tête X-Webhook-Signature : le HMAC-SHA256 du corps brut, avec pour clé le secret de votre projet décodé depuis l'hexadécimal, écrit en hexadécimal. Répondez avec n'importe quel statut 2xx. Tout le reste est relancé : les événements de facture toutes les 15 secondes jusqu'à livraison, les événements de paiement toutes les 10 minutes, jusqu'à 150 fois.
Événements
invoice:<status>Une facture a changé de statutpending-paymentUn paiement a été détecté et attend ses confirmationsconfirmed-paymentUn paiement a été confirmé et créditéfailed-paymentUn paiement n'a pas pu être traitéPOST /webhooks/rubynex
Content-Type: application/json
X-Webhook-Signature: 9c1fd2…e07a
{
"id": "4e1a…c93f",
"message": {
"event": "invoice:paid",
"data": { "id": "0b6f3c1e-…", "payload": "65f2c1a9e4b0d3f7a2c91e04" }
},
"attempt": 0,
"timestamp": 1764590400
}Vérifier la signature
import crypto from 'node:crypto';
import express from 'express';
const secret = Buffer.from(process.env.RUBYNEX_SECRET, 'hex');
// keep the raw body: the signature covers its exact bytes
app.post('/webhooks/rubynex', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', secret).update(req.body).digest('hex');
const given = req.get('X-Webhook-Signature') ?? '';
if (given.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
return res.sendStatus(401);
}
const { message } = JSON.parse(req.body);
if (message.event === 'invoice:paid') markOrderPaid(message.data.payload);
res.sendStatus(200);
});Confirmations par réseau
| Réseau | Cryptos | Confirmations | Délai de crédit |
|---|---|---|---|
| TRXUSDT | 1 | environ 3 s | |
| ETHUSDTUSDCDAI | 5 | environ 1 min | |
| BNBUSDTUSDCDAI | 10 | environ 8 s | |
| POLUSDTUSDCDAI | 20 | environ 40 s | |
| ETHUSDTUSDC | 10 | environ 20 s | |
| BTC | 1 | environ 10 min | |
| XRP | 1 | environ 4 s | |
| DOGE | 3 | environ 3 min |
Limites à connaître
- Les paiements de 1 $ ou moins sont ignorés comme poussière
- Tolérance d'écart sur une facture : jusqu'à 5 %
- Une facture est surpayée lorsque le montant reçu dépasse son prix de plus de 1 %
- Le secret d'un projet peut être changé une fois toutes les 5 minutes
Prêt pour vos clés ?
Nous créons votre projet et vous envoyons son identifiant et son secret.