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
La première étape de l’intégration des recharges mobiles consiste à récupérer la liste des forfaits disponibles depuis l’API. Les forfaits incluent tous les opérateurs (Mobilis, Djezzy, Ooredoo, Pixx) avec des options de montants dynamiques et fixes.
Les forfaits sont stables et changent rarement. Mettez-les en cache dans votre base de données pour réduire les appels API et améliorer les performances.
Référence API Consultez la documentation API complète pour l’endpoint GET /v3/mobile/plans
Comprendre les types de forfaits
Forfaits dynamiques
Les forfaits dynamiques permettent des montants variables dans une plage min/max :
{
"code" : "PREPAID_DJEZZY" ,
"name" : "Djezzy Prepaid" ,
"operator" : "Djezzy" ,
"cost" : 0.98 ,
"isEnabled" : true ,
"min_amount" : 50 ,
"max_amount" : 5000
}
Cas d’usage :
Recharges prépayées (crédit)
Paiements de factures postpayées (facture)
Crédit d’appels internationaux
Forfaits fixes
Les forfaits fixes ont des montants prédéterminés :
{
"code" : "PIXX_500" ,
"name" : "Pixx 500 DA" ,
"operator" : "Pixx" ,
"cost" : 0.97 ,
"isEnabled" : true ,
"amount" : 500
}
Cas d’usage :
Offres promotionnelles spéciales
Packs data
Activations de services
Forfaits spéciaux qui récupèrent les offres disponibles pour un numéro spécifique :
{
"code" : "GETMENU_Mobilis" ,
"name" : "Mobilis GetMenu" ,
"operator" : "Mobilis" ,
"cost" : 0.98 ,
"isEnabled" : true ,
"min_amount" : 50 ,
"max_amount" : 5000
}
Retourne : Un tableau de suggested_offers avec tous les forfaits disponibles pour ce numéro spécifique.
Récupérer les forfaits depuis l’API
Requête de base
curl https://api.oneclickdz.com/v3/mobile/plans \
-H "X-Access-Token: YOUR_API_KEY"
Structure de la réponse
{
"success" : true ,
"data" : {
"dynamicPlans" : [
{
"code" : "PREPAID_MOBILIS" ,
"name" : "📱 PREPAID | عادي" ,
"operator" : "Mobilis" ,
"cost" : 0.96 ,
"isEnabled" : true ,
"min_amount" : 40 ,
"max_amount" : 3999
},
{
"code" : "GROS_MOBILIS" ,
"name" : "📱 GROS MOBILIS | جملة" ,
"operator" : "GMobilis" ,
"isEnabled" : true ,
"min_amount" : 5000 ,
"max_amount" : 300000
}
],
"fixedPlans" : [
{
"code" : "MIX500_MOBILIS" ,
"name" : "📱🌐 AUTO | MIX 500" ,
"operator" : "Mobilis" ,
"isEnabled" : true ,
"cost" : 0.96 ,
"amount" : 500
},
{
"code" : "MIX1000_OOREDOO" ,
"name" : "📱🌐 AUTO | MIX 1000" ,
"operator" : "Ooredoo" ,
"isEnabled" : true ,
"cost" : 0.99 ,
"amount" : 1000
}
]
},
"meta" : {
"timestamp" : "2025-10-29T00:35:59.220Z"
}
}
Comprendre le champ Cost
Le champ cost représente votre multiplicateur de prix de gros :
Exemple : cost = 0.98 Pour une recharge de 1000 DZD :
Valeur nominale : 1000 DZD (ce que l’utilisateur reçoit)
Votre coût : 1000 × 0,98 = 980 DZD (ce que vous payez)
Votre marge : 1000 - 980 = 20 DZD (2 %)
Ajoutez votre marge : const faceValue = 1000 ;
const cost = 0.98 ;
const ourCost = faceValue * cost ; // 980 DZD
// Add 5% profit margin
const markup = 0.05 ;
const sellPrice = ourCost * ( 1 + markup ); // 1029 DZD
const profit = sellPrice - ourCost ; // 49 DZD
N’exposez jamais le champ cost aux utilisateurs finaux ! Il s’agit de vos tarifs de gros. Calculez et affichez toujours vos propres prix de détail.
Mettre les forfaits en cache dans la base de données
Comme les forfaits changent rarement, mettez-les en cache localement avec vos tarifs :
Schéma de base de données
CREATE TABLE mobile_plans (
id SERIAL PRIMARY KEY ,
code VARCHAR ( 100 ) UNIQUE NOT NULL ,
name VARCHAR ( 255 ) NOT NULL ,
operator VARCHAR ( 50 ) NOT NULL ,
type VARCHAR ( 20 ) NOT NULL , -- 'dynamic' or 'fixed'
-- Cost info
wholesale_cost DECIMAL ( 5 , 4 ) NOT NULL ,
sell_price_multiplier DECIMAL ( 5 , 4 ) NOT NULL ,
-- Amount limits
min_amount INTEGER ,
max_amount INTEGER ,
fixed_amount INTEGER ,
-- Status
is_enabled BOOLEAN DEFAULT true,
is_visible BOOLEAN DEFAULT true,
-- Metadata
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_synced_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_mobile_plans_operator ON mobile_plans(operator);
CREATE INDEX idx_mobile_plans_enabled ON mobile_plans(is_enabled);
CREATE INDEX idx_mobile_plans_code ON mobile_plans(code);
Fonction de synchronisation
const db = require ( './database' );
async function syncMobilePlans () {
try {
console . log ( '🔄 Syncing mobile plans...' );
// Fetch plans from API
const plans = await fetchMobilePlans ();
// Calculate your pricing
const PROFIT_MARGIN = 0.05 ; // 5% profit
for ( const plan of plans ) {
const isFixed = !! plan . amount ;
const planData = {
code: plan . code ,
name: plan . name ,
operator: plan . operator ,
type: isFixed ? 'fixed' : 'dynamic' ,
wholesaleCost: plan . cost ,
sellPriceMultiplier: plan . cost * ( 1 + PROFIT_MARGIN ),
minAmount: plan . min_amount || null ,
maxAmount: plan . max_amount || null ,
fixedAmount: plan . amount || null ,
isEnabled: plan . isEnabled ,
lastSyncedAt: new Date ()
};
// Upsert (insert or update)
await db . mobilePlans . upsert ({
where: { code: plan . code },
update: planData ,
create: planData
});
}
console . log ( `✅ Successfully synced ${ plans . length } plans` );
// Log statistics
const stats = {
total: plans . length ,
dynamic: plans . filter ( p => ! p . amount ). length ,
fixed: plans . filter ( p => p . amount ). length ,
enabled: plans . filter ( p => p . isEnabled ). length
};
console . log ( '📊 Plan statistics:' , stats );
return stats ;
} catch ( error ) {
console . error ( '❌ Failed to sync plans:' , error );
throw error ;
}
}
// Run sync on startup
syncMobilePlans ();
// Schedule daily sync at midnight
const cron = require ( 'node-cron' );
cron . schedule ( '0 0 * * *' , () => {
console . log ( '⏰ Running scheduled plan sync...' );
syncMobilePlans ();
});
Servir les forfaits aux utilisateurs
Lorsque les utilisateurs demandent des forfaits, servez-les depuis votre base de données avec vos tarifs :
async function getUserPlans ( filters = {}) {
const { operator , type , enabled = true } = filters ;
const query = { isEnabled: enabled , isVisible: true };
if ( operator ) query . operator = operator ;
if ( type ) query . type = type ;
const plans = await db . mobilePlans . findMany ({
where: query ,
orderBy: [
{ operator: 'asc' },
{ fixedAmount: 'asc' },
{ name: 'asc' }
]
});
// Transform for user display (remove wholesale cost!)
return plans . map ( plan => ({
code: plan . code ,
name: plan . name ,
operator: plan . operator ,
type: plan . type ,
minAmount: plan . minAmount ,
maxAmount: plan . maxAmount ,
amount: plan . fixedAmount ,
// Don't expose wholesale cost!
// Only expose what user needs
}));
}
// API endpoint
app . get ( '/api/mobile/plans' , async ( req , res ) => {
try {
const { operator } = req . query ;
const plans = await getUserPlans ({ operator });
res . json ({ success: true , data: { plans } });
} catch ( error ) {
res . status ( 500 ). json ({
success: false ,
error: error . message
});
}
});
Filtrer les forfaits
Par opérateur
const mobilisPlans = await getUserPlans ({ operator: 'Mobilis' });
const djezzyPlans = await getUserPlans ({ operator: 'Djezzy' });
const ooredooPlans = await getUserPlans ({ operator: 'Ooredoo' });
Par numéro de téléphone
function getOperatorFromPhone ( phone ) {
const prefixMap = {
'065' : [ 'Mobilis' ],
'066' : [ 'Mobilis' , 'Ooredoo' ],
'067' : [ 'Mobilis' ],
'077' : [ 'Djezzy' , 'Mobilis' ],
'078' : [ 'Djezzy' ],
'055' : [ 'Ooredoo' , 'Djezzy' , 'Mobilis' ],
'056' : [ 'Ooredoo' ],
'068' : [ 'Pixx' ]
};
const prefix = phone . substring ( 0 , 3 );
return prefixMap [ prefix ] || [];
}
async function getPlansForPhone ( phone ) {
const operators = getOperatorFromPhone ( phone );
if ( operators . length === 0 ) {
throw new Error ( 'Invalid phone number prefix' );
}
const plans = await db . mobilePlans . findMany ({
where: {
operator: { in: operators },
isEnabled: true ,
isVisible: true
}
});
return plans ;
}
Bonnes pratiques
Mettre en cache localement
Mettez toujours les forfaits en cache dans votre base de données. Les forfaits changent rarement et le cache améliore considérablement les performances.
Masquer les coûts de gros
N’exposez jamais le champ cost aux utilisateurs finaux. N’affichez que vos tarifs de détail.
Synchroniser régulièrement
Mettez en place une tâche cron quotidienne pour synchroniser les forfaits. Cela garantit que vous disposez des dernières offres et disponibilités.
Vérifiez toujours isEnabled avant d’afficher les forfaits. Les forfaits désactivés peuvent être temporairement indisponibles en raison de problèmes avec l’opérateur.
Ajouter une marge bénéficiaire
Calculez votre prix de vente en ajoutant une marge bénéficiaire raisonnable (généralement 3 à 10 %) au coût de gros.
Indexer votre base de données
Créez des index sur les champs fréquemment interrogés (operator, code, isEnabled) pour des recherches rapides.
Étapes suivantes
Étape 2 : Validation Apprenez à valider les numéros de téléphone et les saisies utilisateur
Référence API des forfaits Documentation API complète pour GET /v3/mobile/plans
API de solde du compte Apprenez à vérifier le solde de votre compte
Guide des tarifs Comprendre la tarification et la structure des coûts de l’API
Format de réponse En savoir plus sur les structures de réponse de l’API
Référence des modèles Voir tous les modèles de données et schémas