Guide de dépannage
Problèmes courants et solutions lors de l'intégration avec l'API ChinqIT Verify.
Note : Préférez les endpoints API v2 (POST /api/v2/notify, POST /api/v2/code, POST /api/v2/check, GET /api/v2/notify/:messageId). Les anciens endpoints v1 sont dépréciés et les réponses incluent un objet deprecation et l'en-tête Deprecation: true.
🔍 Étapes générales de dépannage
- Vérifier la clé API : Assurez-vous que votre clé API est correcte et active
- Vérifier le format de la requête : Vérifiez que le corps de votre requête correspond à la spécification de l'API
- Examiner les messages d'erreur : Consultez la réponse d'erreur pour des détails spécifiques
- Tester la connectivité : Assurez-vous que votre application peut accéder à
https://sms.chinqit.com(v2 :https://sms.chinqit.com/api/v2/notifypour l'envoi)
🔐 Problèmes d'authentification
401 Unauthorized - Clé API manquante
Symptômes :
- Code d'état 401
- Message d'erreur "API key is required"
Solutions :
-
Vérifier le nom de l'en-tête
# Doit être exactement : X-API-Key (sensible à la casse)
curl -H "X-API-Key: your-key" https://sms.chinqit.com/messages/send -
Vérifier le format de l'en-tête
// Correct
headers: {
'X-API-Key': 'your-api-key'
}
// Incorrect - trait d'union manquant
headers: {
'X_API_Key': 'your-api-key'
} -
Vérifier que la clé API est incluse
- Vérifiez que votre clé API est envoyée dans chaque requête
- Assurez-vous qu'aucun middleware ne supprime l'en-tête
403 Forbidden - Clé API invalide
Symptômes :
- Code d'état 403
- Message d'erreur "Invalid API key"
Solutions :
-
Vérifier la clé API
- Contactez le support ChinqIT Verify pour confirmer que votre clé API est active
- Vérifiez les fautes de frappe ou les espaces supplémentaires dans votre clé API
- Assurez-vous d'utiliser la clé API correcte pour votre environnement
-
Vérifier le format de la clé API
# Assurez-vous qu'il n'y a pas d'espaces ou de caractères supplémentaires
# Correct : "abc123xyz"
# Incorrect : " abc123xyz " ou "abc123xyz\n" -
Régénérer la clé API
- Si votre clé API a été compromise ou révoquée, demandez-en une nouvelle auprès de ChinqIT Verify
📝 Erreurs de validation
400 Bad Request - Erreur de validation
Symptômes :
- Code d'état 400
- Message "Validation failed" avec détails de l'erreur
Erreurs de validation courantes :
Champ obligatoire manquant :
{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["phoneNumber"],
"message": "Required"
}
]
}
Format de numéro de téléphone invalide :
{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["phoneNumber"],
"message": "Invalid phone number format"
}
]
}
Solutions :
-
Vérifier le corps de la requête
// Format correct pour l'envoi de SMS
{
"phoneNumber": "+1234567890",
"message": "Your message here"
}
// Format correct pour l'envoi d'OTP
{
"phoneNumber": "+1234567890",
"language": "en",
"channel": "sms"
} -
Vérifier le format du numéro de téléphone
- Doit inclure l'indicatif du pays avec le préfixe
+ - Exemples :
+1234567890,+33123456789 - Pas d'espaces ou de caractères spéciaux sauf
+
- Doit inclure l'indicatif du pays avec le préfixe
-
Vérifier le contenu du message
- Le message doit contenir au moins 1 caractère
- L'OTP doit contenir exactement 6 chiffres
-
Vérifier la valeur du canal
- Pour l'OTP :
channeldoit être"sms"ou"whatsapp"(en minuscules) - Par défaut
"sms"si omis
- Pour l'OTP :
📊 Limitation de débit
429 Too Many Requests
Symptômes :
- Code d'état 429
- Message d'erreur "Rate limit exceeded"
Limites de débit :
- Envoi d'OTP : 3 requêtes par minute, 10 par heure, 20 par jour (par numéro de téléphone par clé API)
Solutions :
-
Implémenter un délai d'attente exponentiel
async function sendOTPWithRetry(
phoneNumber,
language,
channel,
maxRetries = 3,
) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client.sendOTP(phoneNumber, language, channel);
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
// Attendre avec délai exponentiel
const waitTime = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise((resolve) => setTimeout(resolve, waitTime));
continue;
}
throw error;
}
}
} -
Respecter les limites de débit
- Suivez la fréquence de vos requêtes
- Implémentez une limitation de débit côté client
- Attendez avant de réessayer après des erreurs 429
-
Utiliser différents numéros de téléphone
- Les limites de débit sont par numéro de téléphone
- Si vous testez, utilisez différents numéros de téléphone pour éviter d'atteindre les limites
📱 Problèmes de canal WhatsApp
502 Bad Gateway - Erreur du fournisseur WhatsApp
Symptômes :
- Code d'état 502
- Message d'erreur "WhatsApp OTP send failed"
- Détails de l'erreur de l'API WhatsApp
Solutions :
-
Vérifier le format du numéro de téléphone
- WhatsApp requiert les numéros de téléphone au format E.164 avec l'indicatif du pays
- Exemple :
+1234567890(pas1234567890)
-
Implémenter un repli vers SMS
async function sendOTPWithFallback(phoneNumber, language) {
try {
// Essayer WhatsApp en premier
return await client.sendOTP(phoneNumber, language, "whatsapp");
} catch (error) {
if (error.status === 502) {
// Repli vers SMS si WhatsApp échoue
console.log("WhatsApp failed, falling back to SMS");
return await client.sendOTP(phoneNumber, language, "sms");
}
throw error;
}
} -
Gérer les erreurs du fournisseur avec élégance
- Les erreurs du fournisseur WhatsApp sont temporaires
- Implémentez une logique de nouvelle tentative avec repli vers SMS
- Enregistrez les erreurs pour la surveillance
-
Vérifier la disponibilité du service WhatsApp
- Contactez le support ChinqIT Verify si le canal WhatsApp échoue constamment
- Vérifiez si le service WhatsApp est temporairement indisponible
🔄 Problèmes d'intégration courants
Messages non envoyés
Symptômes :
- La requête réussit mais le message n'est pas reçu
- Pas d'erreur mais pas de confirmation de livraison
Solutions :
-
Vérifier le numéro de téléphone
- Assurez-vous que le numéro de téléphone est correct et actif
- Vérifiez que l'indicatif du pays est correct
- Vérifiez que le destinataire peut recevoir des SMS
-
Vérifier le contenu du message
- Assurez-vous que le message n'est pas vide
- Vérifiez que les caractères spéciaux sont correctement encodés
- Vérifiez la longueur du message (les limites SMS standard s'appliquent)
-
Gérer le traitement asynchrone
- Les messages sont mis en file d'attente et traités de manière asynchrone
- L'API retourne immédiatement après la mise en file d'attente
- La livraison peut prendre quelques secondes à quelques minutes
Échec de la vérification OTP
Symptômes :
- L'OTP est envoyé avec succès mais la vérification échoue
- Erreurs "Invalid OTP" ou "OTP not found"
Solutions :
-
Vérifier l'expiration de l'OTP
- Les OTP expirent après 10 minutes
- Assurez-vous que l'utilisateur entre l'OTP rapidement
- Demandez un nouvel OTP s'il est expiré
-
Vérifier le format de l'OTP
- L'OTP doit contenir exactement 6 chiffres
- Pas d'espaces ou de caractères spéciaux
- Exemple :
"123456"(pas"123 456"ou"123-456")
-
Vérifier la limite de tentatives
- Maximum 3 tentatives de vérification par OTP
- Après 3 échecs, l'OTP est invalidé
- Demandez un nouvel OTP si la limite de tentatives est dépassée
-
Faire correspondre le canal
- Si l'OTP a été envoyé via WhatsApp, vérifiez avec
channel: "whatsapp" - Si l'OTP a été envoyé via SMS, vérifiez avec
channel: "sms"(ou omettez, par défaut SMS)
- Si l'OTP a été envoyé via WhatsApp, vérifiez avec
-
Gérer la sensibilité à la casse
- Le numéro de téléphone doit correspondre exactement (y compris le préfixe
+) - Assurez-vous que le format du numéro de téléphone est cohérent entre l'envoi et la vérification
- Le numéro de téléphone doit correspondre exactement (y compris le préfixe
🌐 Problèmes réseau
Délai de connexion dépassé
Symptômes :
- Expiration de la requête
- Erreurs réseau
Solutions :
-
Vérifier la connexion Internet
- Vérifiez que votre application a accès à Internet
- Testez la connectivité à
https://sms.chinqit.com
-
Implémenter la gestion des délais d'attente
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // Délai de 10 secondes
try {
const response = await fetch("https://sms.chinqit.com/messages/send", {
signal: controller.signal,
// ... autres options
});
clearTimeout(timeoutId);
} catch (error) {
if (error.name === "AbortError") {
console.error("Request timeout");
}
} -
Logique de nouvelle tentative
- Implémentez une logique de nouvelle tentative pour les erreurs réseau transitoires
- Utilisez un délai d'attente exponentiel
- Ne réessayez pas sur les erreurs 4xx (erreurs client)
Erreurs SSL/TLS
Symptômes :
- Erreurs de certificat SSL
- Échecs de négociation TLS
Solutions :
-
Vérifier HTTPS
- Utilisez toujours
https://sms.chinqit.com(pashttp://) - Assurez-vous que votre environnement supporte TLS 1.2+
- Utilisez toujours
-
Vérifier le certificat
- Assurez-vous que l'horloge système est correcte
- Mettez à jour les certificats CA si nécessaire
- Contactez ChinqIT Verify si les problèmes de certificat persistent
🐛 Conseils de débogage
Activer la journalisation des requêtes
JavaScript :
async function sendMessage(phoneNumber, message) {
console.log("Sending message:", { phoneNumber, message });
try {
const response = await fetch("https://sms.chinqit.com/messages/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.API_KEY,
},
body: JSON.stringify({ phoneNumber, message }),
});
console.log("Response status:", response.status);
const data = await response.json();
console.log("Response data:", data);
return data;
} catch (error) {
console.error("Error:", error);
throw error;
}
}
Python :
import requests
import logging
logging.basicConfig(level=logging.DEBUG)
def send_message(phone_number, message):
url = 'https://sms.chinqit.com/messages/send'
headers = {
'Content-Type': 'application/json',
'X-API-Key': os.getenv('API_KEY')
}
data = {
'phoneNumber': phone_number,
'message': message
}
logging.debug(f'Sending request: {data}')
response = requests.post(url, json=data, headers=headers)
logging.debug(f'Response status: {response.status_code}')
logging.debug(f'Response data: {response.json()}')
return response.json()
Tester la connectivité de l'API
# Tester la connectivité de base
curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phoneNumber": "+1234567890", "message": "Test"}'
🚨 Stratégies de gestion des échecs de livraison OTP
Comprendre les scénarios d'échec de livraison
Les OTP peuvent échouer à être livrés pour plusieurs raisons :
- Problèmes réseau temporaires : Congestion réseau, maintenance
- Problèmes de fournisseur SMS : Indisponibilité du fournisseur
- Numéros invalides ou injoignables : Numéro hors service, roaming
- Limites de débit : Trop de messages envoyés
- Blocage par l'opérateur : Filtrage anti-spam
Stratégie 1 : Logique de nouvelle tentative avec backoff exponentiel
Implémentez une logique de nouvelle tentative pour les erreurs temporaires (5xx) :
class OTPService {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = "https://sms.chinqit.com/api/v2";
}
async sendOTPWithRetry(
phoneNumber,
language = "fr",
channel = "sms",
maxRetries = 3,
) {
let lastError;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const response = await this.sendOTP(phoneNumber, language, channel);
if (response.success) {
return response;
}
// Si c'est une erreur 5xx ou réseau, retenter
if (this.isRetryableError(response)) {
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Backoff exponentiel
await this.sleep(delay);
continue;
}
}
return response; // Erreur non retry-able
} catch (error) {
lastError = error;
// Erreurs réseau ou 5xx sont retry-ables
if (this.isRetryableNetworkError(error) && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
await this.sleep(delay);
continue;
}
throw error;
}
}
throw lastError;
}
isRetryableError(response) {
// Erreurs temporaires du serveur
return response.status >= 500 && response.status < 600;
}
isRetryableNetworkError(error) {
return (
error.code === "ECONNRESET" ||
error.code === "ETIMEDOUT" ||
error.code === "ENOTFOUND"
);
}
async sendOTP(phoneNumber, language, channel) {
const response = await fetch(`${this.baseURL}/code`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": this.apiKey,
},
body: JSON.stringify({
phoneNumber,
language,
channel,
}),
});
return response.json();
}
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
// Utilisation
const otpService = new OTPService("YOUR_API_KEY");
try {
const result = await otpService.sendOTPWithRetry("+22238089336", "fr", "sms");
console.log("OTP envoyé avec succès:", result.messageId);
} catch (error) {
console.error("Échec définitif de l'envoi OTP:", error.message);
}
Stratégie 2 : Repli entre canaux (SMS ↔ WhatsApp)
Si un canal échoue, basculez automatiquement vers l'autre :
async function sendOTPWithChannelFallback(
phoneNumber,
language = "fr",
primaryChannel = "sms",
) {
const channels =
primaryChannel === "sms" ? ["sms", "whatsapp"] : ["whatsapp", "sms"];
for (const channel of channels) {
try {
console.log(`Tentative d'envoi OTP via ${channel}...`);
const response = await fetch("https://sms.chinqit.com/api/v2/code", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber,
language,
channel,
}),
});
const result = await response.json();
if (result.success) {
console.log(`OTP envoyé avec succès via ${channel}`);
return {
...result,
channelUsed: channel,
};
}
// Si échec définitif (pas d'erreur temporaire), essayer l'autre canal
if (!isTemporaryFailure(result)) {
console.log(
`${channel} a échoué définitivement, essai de l'autre canal...`,
);
continue;
}
// Erreur temporaire, ne pas essayer l'autre canal immédiatement
throw new Error(
`${channel} temporairement indisponible: ${result.message}`,
);
} catch (error) {
console.error(`Erreur avec ${channel}:`, error.message);
// Continuer vers l'autre canal seulement si c'est le premier essai
if (channel === channels[0]) {
continue;
}
throw error;
}
}
throw new Error("Les deux canaux ont échoué");
}
function isTemporaryFailure(result) {
// Considérer comme temporaire les erreurs 5xx ou certains messages spécifiques
return (
result.status >= 500 ||
result.message?.includes("temporarily unavailable") ||
result.message?.includes("service unavailable")
);
}
// Utilisation
try {
const result = await sendOTPWithChannelFallback("+22238089336", "fr", "sms");
console.log(`OTP envoyé via ${result.channelUsed}:`, result.messageId);
} catch (error) {
console.error("Échec sur les deux canaux:", error.message);
}
Stratégie 3 : Repli vers saisie manuelle d'OTP
Quand la livraison automatique échoue, permettez la saisie manuelle :
class OTPVerificationManager {
constructor() {
this.deliveryAttempts = 0;
this.maxDeliveryAttempts = 2;
this.manualEntryEnabled = false;
}
async requestOTP(phoneNumber, language = "fr") {
this.deliveryAttempts = 0;
this.manualEntryEnabled = false;
// Essayer la livraison automatique d'abord
while (this.deliveryAttempts < this.maxDeliveryAttempts) {
try {
this.deliveryAttempts++;
console.log(
`Tentative de livraison ${this.deliveryAttempts}/${this.maxDeliveryAttempts}`,
);
const result = await this.attemptDelivery(phoneNumber, language);
if (result.success) {
return {
success: true,
method: "automatic",
messageId: result.messageId,
channel: result.channelUsed,
expiresIn: result.expiresIn,
};
}
// Si échec et c'était la dernière tentative, activer la saisie manuelle
if (this.deliveryAttempts >= this.maxDeliveryAttempts) {
console.log(
"Livraison automatique échouée, activation de la saisie manuelle",
);
this.manualEntryEnabled = true;
return {
success: false,
method: "manual_required",
reason: "delivery_failed",
message: "Veuillez saisir manuellement le code OTP reçu",
};
}
// Attendre avant la prochaine tentative
await this.sleep(2000);
} catch (error) {
console.error(
`Tentative ${this.deliveryAttempts} échouée:`,
error.message,
);
if (this.deliveryAttempts >= this.maxDeliveryAttempts) {
this.manualEntryEnabled = true;
return {
success: false,
method: "manual_required",
reason: "delivery_error",
message:
"Erreur de livraison, veuillez saisir manuellement le code OTP",
};
}
await this.sleep(2000);
}
}
}
async attemptDelivery(phoneNumber, language) {
// Utiliser la logique de fallback canal précédente
return await sendOTPWithChannelFallback(phoneNumber, language);
}
async verifyOTP(phoneNumber, otp, channel = null) {
try {
const response = await fetch("https://sms.chinqit.com/api/v2/check", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber,
otp,
...(channel && { channel }),
}),
});
const result = await response.json();
return result;
} catch (error) {
throw new Error(`Erreur de vérification: ${error.message}`);
}
}
isManualEntryEnabled() {
return this.manualEntryEnabled;
}
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
// Exemple d'utilisation dans une interface utilisateur
async function handleOTPRequest(phoneNumber) {
const manager = new OTPVerificationManager();
// Afficher un indicateur de chargement
showLoadingSpinner();
try {
const result = await manager.requestOTP(phoneNumber);
hideLoadingSpinner();
if (result.success) {
// Livraison automatique réussie
showSuccessMessage(`Code envoyé via ${result.channel}`);
showOTPInputField();
} else if (result.method === "manual_required") {
// Activer le mode saisie manuelle
showManualEntryMode();
showInfoMessage(result.message);
// Optionnellement, permettre à l'utilisateur de demander un nouveau code
showResendButton();
}
} catch (error) {
hideLoadingSpinner();
showErrorMessage("Erreur lors de l'envoi du code. Veuillez réessayer.");
}
}
async function handleOTPVerification(phoneNumber, otp) {
const manager = new OTPVerificationManager();
try {
const result = await manager.verifyOTP(phoneNumber, otp);
if (result.success) {
showSuccessMessage("Vérification réussie !");
proceedToNextStep();
} else {
if (result.retriesLeft > 0) {
showErrorMessage(
`Code incorrect. ${result.retriesLeft} tentatives restantes.`,
);
} else {
showErrorMessage("Code incorrect. Demandez un nouveau code.");
showResendButton();
}
}
} catch (error) {
showErrorMessage("Erreur de vérification. Veuillez réessayer.");
}
}
Stratégie 4 : Gestion des quotas et limites de débit
Surveillez et gérez les limites d'envoi :
class OTPRateLimiter {
constructor(maxRequestsPerMinute = 10, maxRequestsPerHour = 50) {
this.requests = [];
this.maxPerMinute = maxRequestsPerMinute;
this.maxPerHour = maxRequestsPerHour;
}
canSend(phoneNumber) {
const now = Date.now();
const oneMinuteAgo = now - 60000;
const oneHourAgo = now - 3600000;
// Nettoyer les anciennes requêtes
this.requests = this.requests.filter((req) => req.timestamp > oneHourAgo);
// Compter les requêtes pour ce numéro
const recentRequests = this.requests.filter(
(req) => req.phoneNumber === phoneNumber && req.timestamp > oneMinuteAgo,
);
const hourlyRequests = this.requests.filter(
(req) => req.phoneNumber === phoneNumber && req.timestamp > oneHourAgo,
);
return (
recentRequests.length < this.maxPerMinute &&
hourlyRequests.length < this.maxPerHour
);
}
recordRequest(phoneNumber) {
this.requests.push({
phoneNumber,
timestamp: Date.now(),
});
}
getTimeUntilNextAllowed(phoneNumber) {
if (this.canSend(phoneNumber)) {
return 0;
}
const now = Date.now();
const recentRequests = this.requests
.filter((req) => req.phoneNumber === phoneNumber)
.sort((a, b) => b.timestamp - a.timestamp);
if (recentRequests.length >= this.maxPerMinute) {
const oldestRecent = recentRequests[this.maxPerMinute - 1];
return Math.max(0, 60000 - (now - oldestRecent.timestamp));
}
return 0;
}
}
// Intégration avec le service OTP
async function sendOTPWithRateLimit(phoneNumber, language) {
const rateLimiter = new OTPRateLimiter();
if (!rateLimiter.canSend(phoneNumber)) {
const waitTime = rateLimiter.getTimeUntilNextAllowed(phoneNumber);
throw new Error(
`Trop de requêtes. Réessayez dans ${Math.ceil(waitTime / 1000)} secondes.`,
);
}
try {
const result = await sendOTPWithChannelFallback(phoneNumber, language);
rateLimiter.recordRequest(phoneNumber);
return result;
} catch (error) {
// Ne pas compter les échecs réseau comme des requêtes réussies
throw error;
}
}
Bonnes pratiques pour l'expérience utilisateur
- Communication claire : Informez l'utilisateur du canal utilisé et du délai d'expiration
- Indicateurs visuels : Montrez le progrès des tentatives de livraison
- Options de secours : Toujours offrir la possibilité de saisir manuellement l'OTP
- Messages d'erreur utiles : Expliquez pourquoi la livraison a échoué et que faire ensuite
- Bouton "Renvoyer" : Permettez facilement de demander un nouveau code
- Support multi-canal : Préférez automatiquement le canal le plus fiable pour l'utilisateur
Surveillance et métriques
Suivez les taux de succès de livraison pour optimiser votre stratégie :
class OTPMetrics {
constructor() {
this.metrics = {
totalRequests: 0,
successfulDeliveries: 0,
failedDeliveries: 0,
channelUsage: { sms: 0, whatsapp: 0 },
fallbackUsage: 0,
manualEntryUsage: 0,
averageDeliveryTime: 0,
};
}
recordAttempt(channel, success, deliveryTime = null) {
this.metrics.totalRequests++;
if (success) {
this.metrics.successfulDeliveries++;
} else {
this.metrics.failedDeliveries++;
}
this.metrics.channelUsage[channel] =
(this.metrics.channelUsage[channel] || 0) + 1;
if (deliveryTime) {
this.metrics.averageDeliveryTime =
(this.metrics.averageDeliveryTime + deliveryTime) / 2;
}
}
recordFallback() {
this.metrics.fallbackUsage++;
}
recordManualEntry() {
this.metrics.manualEntryUsage++;
}
getSuccessRate() {
return this.metrics.totalRequests > 0
? (this.metrics.successfulDeliveries / this.metrics.totalRequests) * 100
: 0;
}
getChannelPreference() {
const smsRate = this.metrics.channelUsage.sms || 0;
const whatsappRate = this.metrics.channelUsage.whatsapp || 0;
const total = smsRate + whatsappRate;
return total > 0
? {
sms: (smsRate / total) * 100,
whatsapp: (whatsappRate / total) * 100,
}
: { sms: 0, whatsapp: 0 };
}
logMetrics() {
console.log("OTP Delivery Metrics:");
console.log(`- Total requests: ${this.metrics.totalRequests}`);
console.log(`- Success rate: ${this.getSuccessRate().toFixed(2)}%`);
console.log(`- Channel usage:`, this.getChannelPreference());
console.log(`- Fallback usage: ${this.metrics.fallbackUsage}`);
console.log(`- Manual entry usage: ${this.metrics.manualEntryUsage}`);
console.log(
`- Avg delivery time: ${this.metrics.averageDeliveryTime.toFixed(2)}ms`,
);
}
}
// Utilisation
const metrics = new OTPMetrics();
// Après chaque tentative de livraison
metrics.recordAttempt("sms", true, 2500);
metrics.recordFallback();
metrics.recordManualEntry();
// Afficher les métriques périodiquement
setInterval(() => metrics.logMetrics(), 3600000); // Toutes les heures
🆘 Vous avez toujours des problèmes ?
-
Consultez la documentation :
- Référence API - API actuelle | Référence API v1 (Dépréciée) - Endpoints legacy
- Guide d'utilisation de l'API - Exemples de code
-
Examinez les réponses d'erreur :
- Vérifiez le champ
messagepour des détails d'erreur spécifiques - Consultez le tableau
errorspour les problèmes de validation - Notez le code d'état HTTP
- Vérifiez le champ
-
Solutions courantes :
- Vérifiez que la clé API est correcte et active
- Vérifiez que le format de la requête correspond à la spécification de l'API
- Assurez-vous que les numéros de téléphone sont au format E.164
- Implémentez une gestion appropriée des erreurs et une logique de nouvelle tentative
- Contactez le support ChinqIT Verify pour les problèmes persistants
Besoin d'aide supplémentaire ? Contactez le support ChinqIT Verify avec :
- Votre clé API (masquée)
- Message d'erreur et code d'état
- Détails de la requête (sans données sensibles)
- Étapes pour reproduire le problème