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
L’endpoint des produits retourne les cartes de recharge internet disponibles pour les services ADSL ou 4G LTE avec les tarifs en temps réel et la disponibilité du stock. Les produits doivent être mis en cache brièvement pour minimiser les appels API.
Mettez en cache les données de produit pendant 5-10 minutes . Les niveaux de stock changent plus fréquemment que pour les cartes-cadeaux.
Référence API
GET /v3/internet/products Documentation complète de l’endpoint
Chargement de base des produits
async function loadInternetProducts ( type ) {
if ( ! [ 'ADSL' , '4G' ]. includes ( type )) {
throw new Error ( 'Invalid type. Must be ADSL or 4G' );
}
const response = await fetch (
`https://api.oneclickdz.com/v3/internet/products?type= ${ type } ` ,
{
headers: {
"X-Access-Token" : process . env . API_KEY ,
},
}
);
if ( ! response . ok ) {
throw new Error ( `Failed to load products: ${ response . status } ` );
}
const result = await response . json ();
return result . data . products ;
}
// Usage
const adslProducts = await loadInternetProducts ( 'ADSL' );
const lteProducts = await loadInternetProducts ( '4G' );
console . log ( `ADSL: ${ adslProducts . length } products` );
console . log ( `4G: ${ lteProducts . length } products` );
Structure de la réponse
{
"success" : true ,
"data" : {
"products" : [
{
"value" : 500 ,
"cost" : 490 ,
"available" : true
},
{
"value" : 1000 ,
"cost" : 980 ,
"available" : true
},
{
"value" : 2000 ,
"cost" : 1960 ,
"available" : true
},
{
"value" : 5000 ,
"cost" : 4900 ,
"available" : false
}
]
},
"meta" : {
"timestamp" : "2025-11-01T12:00:00.000Z" ,
"type" : "ADSL"
}
}
Implémentation du cache
class ProductCache {
constructor ( ttlMinutes = 10 ) {
this . cache = new Map ();
this . ttl = ttlMinutes * 60 * 1000 ;
}
async get ( type ) {
const cached = this . cache . get ( type );
const now = Date . now ();
// Return cached if still valid
if ( cached && ( now - cached . timestamp ) < this . ttl ) {
console . log ( `Returning cached ${ type } products` );
return cached . data ;
}
// Fetch fresh data
console . log ( `Fetching fresh ${ type } products` );
const products = await loadInternetProducts ( type );
this . cache . set ( type , {
data: products ,
timestamp: now ,
});
return products ;
}
invalidate ( type ) {
if ( type ) {
this . cache . delete ( type );
} else {
this . cache . clear ();
}
}
}
// Usage
const cache = new ProductCache ( 10 ); // TTL 10 minutes
// First call - fetches from API
const adsl1 = await cache . get ( 'ADSL' );
// Second call within 10 minutes - returns cached
const adsl2 = await cache . get ( 'ADSL' );
// Type différent - récupère séparément
const lte = await cache . get ( '4G' );
// Force refresh
cache . invalidate ( 'ADSL' );
const adsl3 = await cache . get ( 'ADSL' ); // Récupère de nouvelles données
Filtrage des produits disponibles
N’afficher que les produits en stock :
function getAvailableProducts ( products ) {
return products . filter ( p => p . available );
}
// Usage
const allProducts = await cache . get ( 'ADSL' );
const available = getAvailableProducts ( allProducts );
console . log ( ` ${ available . length } / ${ allProducts . length } products in stock` );
if ( available . length === 0 ) {
console . log ( 'No products available at the moment' );
}
Application de la marge client
Ajoutez votre marge bénéficiaire aux prix de gros :
function applyMarkup ( products , markupPercent = 5 ) {
return products
. filter ( p => p . available )
. map ( p => ({
value: p . value ,
wholesaleCost: p . cost , // Store but don't show
customerPrice: Math . ceil ( p . cost * ( 1 + markupPercent / 100 )),
available: true ,
}));
}
// Usage
const products = await cache . get ( 'ADSL' );
const customerPrices = applyMarkup ( products , 5 ); // 5% markup
customerPrices . forEach ( p => {
console . log ( ` ${ p . value } DA card: ${ p . customerPrice } DA` );
// Ne pas journaliser wholesaleCost en production !
});
Construction de l’Interface Produit
Exemple de structure pour afficher les produits aux clients :
async function buildProductOptions ( type , markupPercent = 5 ) {
const products = await cache . get ( type );
return {
serviceType: type ,
serviceName: type === 'ADSL' ? 'Internet ADSL' : 'Internet 4G LTE' ,
options: products
. filter ( p => p . available )
. map ( p => ({
value: p . value ,
label: ` ${ p . value } DA` ,
price: Math . ceil ( p . cost * ( 1 + markupPercent / 100 )),
inStock: true ,
}))
. sort (( a , b ) => a . value - b . value ) // Trier par valeur croissante
};
}
// Utilisation
const adslOptions = await buildProductOptions ( 'ADSL' , 5 );
const lteOptions = await buildProductOptions ( '4G' , 5 );
// Retourne une structure prête pour l'interface :
// {
// serviceType: 'ADSL',
// serviceName: 'Internet ADSL',
// options: [
// { value: 500, label: '500 DA', price: 515, inStock: true },
// { value: 1000, label: '1000 DA', price: 1029, inStock: true },
// ...
// ]
// }
Chargement des deux types de service
Récupérez les produits ADSL et 4G en parallèle :
async function loadAllInternetProducts () {
const [ adsl , lte ] = await Promise . all ([
cache . get ( 'ADSL' ),
cache . get ( '4G' ),
]);
return {
adsl: applyMarkup ( adsl , 5 ),
lte: applyMarkup ( lte , 5 ),
};
}
// Usage
const allProducts = await loadAllInternetProducts ();
console . log ( 'ADSL:' , allProducts . adsl . length , 'products' );
console . log ( '4G:' , allProducts . lte . length , 'products' );
Bonnes pratiques
Cache 5-10 minutes Équilibre entre fraîcheur et réduction de la charge API
Filtrer les disponibles uniquement N’afficher que les produits où available: true
Masquer les prix de gros Ne jamais afficher les valeurs brutes de cost aux clients
Gérer les erreurs gracieusement Revenir aux données en cache si l’API est temporairement indisponible
Étapes suivantes
Valider les numéros Vérifier les numéros de téléphone avant la commande
Envoyer les recharges Soumettre des commandes avec gestion des erreurs
Référence API Documentation complète de l’endpoint
Vue d'ensemble Retour à la vue d’ensemble de l’intégration
Suivre le statut Surveiller l’exécution des commandes
Livrer les cartes Livrer les codes de carte en toute sécurité