Documentation Index Fetch the complete documentation index at: https://docs.oneclickdz.com/llms.txt
Use this file to discover all available pages before exploring further.
Vue d’ensemble
Une fois les commandes exécutées, récupérez les codes et numéros de série des cartes depuis l’API et livrez-les en toute sécurité aux clients. Ne stockez jamais les codes de carte en texte clair.
Critique en matière de sécurité : Les codes de carte sont des identifiants précieux. Chiffrez-les lors du stockage et de la transmission.
Référence API
GET /v3/gift-cards/checkOrder/{orderId} Récupérer les cartes exécutées de la commande
Structure des données de carte
Les commandes exécutées contiennent des cartes avec deux champs :
{
"cards" : [
{
"value" : "XXXX-XXXX-XXXX-XXXX" , // Identifiant principal (PIN/code)
"serial" : "123456789" // Identifiant secondaire (numéro de série)
}
]
}
Les champs value et serial sont sensibles et doivent être protégés.
Aides au chiffrement
const crypto = require ( 'crypto' );
// Encryption configuration
const ENCRYPTION_KEY = process . env . ENCRYPTION_KEY ; // Must be 32 bytes
const ALGORITHM = 'aes-256-gcm' ;
function encryptCardData ( text ) {
const iv = crypto . randomBytes ( 16 );
const cipher = crypto . createCipheriv (
ALGORITHM ,
Buffer . from ( ENCRYPTION_KEY , 'hex' ),
iv
);
let encrypted = cipher . update ( text , 'utf8' , 'hex' );
encrypted += cipher . final ( 'hex' );
const authTag = cipher . getAuthTag ();
return {
iv: iv . toString ( 'hex' ),
encryptedData: encrypted ,
authTag: authTag . toString ( 'hex' )
};
}
function decryptCardData ( iv , encryptedData , authTag ) {
const decipher = crypto . createDecipheriv (
ALGORITHM ,
Buffer . from ( ENCRYPTION_KEY , 'hex' ),
Buffer . from ( iv , 'hex' )
);
decipher . setAuthTag ( Buffer . from ( authTag , 'hex' ));
let decrypted = decipher . update ( encryptedData , 'hex' , 'utf8' );
decrypted += decipher . final ( 'utf8' );
return decrypted ;
}
// Usage
const encrypted = encryptCardData ( 'XXXX-XXXX-XXXX-XXXX' );
const decrypted = decryptCardData ( encrypted . iv , encrypted . encryptedData , encrypted . authTag );
Stockage sécurisé des cartes
async function storeOrderCards ( orderId , userId , cards ) {
const encryptedCards = cards . map ( card => {
const encryptedValue = encryptCardData ( card . value );
const encryptedSerial = encryptCardData ( card . serial );
return {
value: encryptedValue ,
serial: encryptedSerial ,
deliveredAt: null
};
});
await db . orders . updateOne (
{ orderId },
{
$set: {
userId ,
status: 'FULFILLED' ,
encryptedCards ,
fulfilledAt: new Date ()
}
}
);
console . log ( `Stored ${ cards . length } encrypted cards for order ${ orderId } ` );
}
// Retrieve and decrypt
async function getOrderCards ( orderId ) {
const order = await db . orders . findOne ({ orderId });
if ( ! order || ! order . encryptedCards ) {
throw new Error ( 'Order not found or cards not available' );
}
return order . encryptedCards . map ( card => ({
value: decryptCardData (
card . value . iv ,
card . value . encryptedData ,
card . value . authTag
),
serial: decryptCardData (
card . serial . iv ,
card . serial . encryptedData ,
card . serial . authTag
)
}));
}
Méthodes de livraison
1. Livraison par e-mail
async function deliverCardsViaEmail ( userId , orderId , cards ) {
const user = await db . users . findOne ({ _id: userId });
// Build email content with cards
const cardList = cards . map (( card , index ) => `
Card ${ index + 1 } :
Code: ${ card . value }
Serial: ${ card . serial }
` ). join ( ' \n\n ' );
await sendEmail ({
to: user . email ,
subject: 'Your Gift Card Order' ,
html: `
<h2>Your gift cards are ready!</h2>
<p>Order ID: ${ orderId } </p>
<pre> ${ cardList } </pre>
<p><strong>Important:</strong> Keep these codes secure and don't share them.</p>
`
});
// Mark as delivered
await db . orders . updateOne (
{ orderId },
{ $set: { 'encryptedCards.$[].deliveredAt' : new Date () } }
);
console . log ( `Delivered ${ cards . length } cards to ${ user . email } ` );
}
2. Affichage dans l’application
// API endpoint to display cards in-app
app . get ( '/api/orders/:orderId/cards' , authenticateUser , async ( req , res ) => {
const { orderId } = req . params ;
const userId = req . user . id ;
// Verify ownership
const order = await db . orders . findOne ({ orderId , userId });
if ( ! order ) {
return res . status ( 404 ). json ({ error: 'Order not found' });
}
if ( order . status !== 'FULFILLED' ) {
return res . status ( 400 ). json ({ error: 'Order not fulfilled yet' });
}
// Decrypt and return cards
const cards = await getOrderCards ( orderId );
res . json ({
orderId ,
cards: cards . map (( card , index ) => ({
cardNumber: index + 1 ,
code: card . value ,
serial: card . serial
}))
});
});
3. Téléchargement sécurisé de fichier
async function generateSecureCardFile ( orderId , cards ) {
const content = cards . map (( card , index ) => `
Gift Card ${ index + 1 }
Code: ${ card . value }
Serial: ${ card . serial }
--------------------
` ). join ( ' \n ' );
// Encrypt the file content
const encrypted = encryptCardData ( content );
// Store temporarily with unique token
const token = crypto . randomBytes ( 32 ). toString ( 'hex' );
await db . downloadTokens . insertOne ({
token ,
orderId ,
encrypted ,
expiresAt: new Date ( Date . now () + 5 * 60 * 1000 ) // 5 minutes
});
return token ;
}
// Download endpoint
app . get ( '/api/download/:token' , async ( req , res ) => {
const { token } = req . params ;
const download = await db . downloadTokens . findOne ({ token });
if ( ! download || download . expiresAt < new Date ()) {
return res . status ( 404 ). json ({ error: 'Download link expired' });
}
const content = decryptCardData (
download . encrypted . iv ,
download . encrypted . encryptedData ,
download . encrypted . authTag
);
res . setHeader ( 'Content-Type' , 'text/plain' );
res . setHeader ( 'Content-Disposition' , `attachment; filename="cards- ${ download . orderId } .txt"` );
res . send ( content );
// Delete token after use
await db . downloadTokens . deleteOne ({ token });
});
Journalisation d’audit
Journalisez les événements de livraison sans exposer les données de carte :
async function logCardDelivery ( orderId , userId , method , cardCount ) {
await db . auditLogs . insertOne ({
event: 'CARDS_DELIVERED' ,
orderId ,
userId ,
method , // 'email', 'in-app', 'download'
cardCount ,
timestamp: new Date (),
ipAddress: req . ip ,
userAgent: req . headers [ 'user-agent' ]
});
console . log ( `[AUDIT] Delivered ${ cardCount } cards for order ${ orderId } via ${ method } ` );
}
// ❌ Ne jamais journaliser les vrais codes de carte
// console.log('Card code:', card.value); // NE PAS FAIRE
Bonnes pratiques
Chiffrer au repos Toujours chiffrer les cartes avant de les stocker en base de données
Utiliser HTTPS uniquement Ne jamais transmettre les cartes sur des connexions non chiffrées
Limiter l'accès Vérifier la propriété de l’utilisateur avant d’afficher les cartes
Pas de journaux en texte clair Ne jamais journaliser les codes de carte en texte clair
Suppression sécurisée Supprimer les cartes en toute sécurité après récupération par le client si la politique l’exige
Piste d'audit Journaliser les événements de livraison sans données sensibles
Flux de livraison complet
async function completeOrderDelivery ( orderId , userId ) {
// 1. Verify order is fulfilled
const orderStatus = await checkOrderStatus ( orderId );
if ( orderStatus . status !== 'FULFILLED' && orderStatus . status !== 'PARTIALLY_FILLED' ) {
throw new Error ( 'Order not ready for delivery' );
}
// 2. Store encrypted cards
await storeOrderCards ( orderId , userId , orderStatus . cards );
// 3. Deliver to customer
await deliverCardsViaEmail ( userId , orderId , orderStatus . cards );
// 4. Log delivery
await logCardDelivery ( orderId , userId , 'email' , orderStatus . cards . length );
console . log ( `✅ Order ${ orderId } delivery complete` );
}
Liste de vérification de sécurité
Générer une clé de chiffrement
Créer une clé de chiffrement sécurisée de 32 octets et la stocker dans les variables d’environnement
Chiffrer avant de stocker
Toujours chiffrer les champs value et serial des cartes avant l’insertion en base de données
Vérifier la propriété de l'utilisateur
Vérifier que l’ID utilisateur correspond à la commande avant d’afficher les cartes
Utiliser HTTPS
S’assurer que toutes les méthodes de livraison utilisent un transport chiffré
Journalisation d'audit
Journaliser les événements de livraison sans inclure les vrais codes de carte
Suppression sécurisée
Mettre en œuvre une politique de suppression des cartes si requis par la réglementation
Étapes suivantes
Vue d'ensemble Retour à la vue d’ensemble de l’intégration
Suivre le statut Interroger l’exécution des commandes
Référence API Documentation complète de l’endpoint
Bonnes pratiques de sécurité Directives générales de sécurité
Passer des commandes Soumettre des commandes validées
Charger le catalogue Récupérer les produits disponibles