Guide des tests
Ce guide présente les bonnes pratiques pour tester votre intégration lomi. et garantir le bon fonctionnement des parcours de paiement en bac à sable et en production.
Configuration de l’environnement de test
Clé API de test
Utilisez toujours votre clé API de test (lomi_sk_test_...) pour le développement et les tests. Récupérez-la dans le Dashboard lomi., section Developers → API Keys. Configurez votre application pour l’utiliser, en général via une variable d’environnement.
import { LomiSDK } from '@lomi./sdk'; // Votre package SDK
const lomi = new LomiSDK({
apiKey: process.env.LOMI_TEST_API_KEY, // Clé TEST depuis l’environnement
baseUrl: 'https://sandbox.api.lomi.africa', // URL du bac à sable
});Secret webhook de test
Pour tester les webhooks en local ou en préproduction, créez un point de terminaison webhook distinct dans le Dashboard lomi. pointant vers votre URL de test (par ex. une URL ngrok). Utilisez le secret de signature (whsec_...) généré pour ce point de terminaison de test dans votre configuration de test (LOMI_TEST_WEBHOOK_SECRET).
Fichier de configuration de test
Centralisez les paramètres propres aux tests.
// test/config.ts
export const testConfig = {
merchantId: process.env.TEST_MERCHANT_ID, // Votre identifiant marchand de test
testWebhookUrl: process.env.TEST_WEBHOOK_URL, // URL ngrok ou serveur de test
webhookSecret: process.env.LOMI_TEST_WEBHOOK_SECRET,
defaultAmount: 100, // Montant minimal valide pour les tests
defaultCurrency: 'XOF',
};Tests d’intégration
Réalisez des tests automatisés contre l’API bac à sable lomi..
Tests du parcours de paiement
Testez la création et la récupération d’objets centraux comme les sessions de paiement (Checkout Sessions) ou les liens de paiement.
import { LomiSDK } from '@lomi./sdk';
import { testConfig } from '../config'; // Votre config de test
describe('Checkout Session Flow', () => {
let lomi: LomiSDK;
beforeAll(() => {
lomi = new LomiSDK({
apiKey: process.env.LOMI_TEST_API_KEY!,
baseUrl: 'https://sandbox.api.lomi.africa',
});
});
it('should create a checkout session successfully', async () => {
const sessionResponse = await lomi.checkoutSessions.createCheckoutSession({
merchant_id: testConfig.merchantId!,
amount: testConfig.defaultAmount,
currency_code: testConfig.defaultCurrency,
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
metadata: { test_order_id: `int_${Date.now()}` },
});
expect(sessionResponse.data.checkout_session_id).toMatch(/^cs_test_/);
expect(sessionResponse.data.status).toBe('pending');
expect(sessionResponse.data.url).toContain('sandbox.checkout.lomi.africa');
});
it('should retrieve an existing checkout session', async () => {
// Supposons qu’une session cs_test_known existe (étape précédente ou setup)
const knownSessionId = 'cs_test_xxxxxxxxxxxx';
const session =
await lomi.checkoutSessions.retrieveCheckoutSession(knownSessionId);
expect(session.data.checkout_session_id).toEqual(knownSessionId);
// Statut possible : pending, completed, expired, etc.
});
});Tests du gestionnaire de webhooks
Testez la vérification de signature et le traitement des événements en local, sans appeler l’API lomi. en direct.
import crypto from 'crypto';
// Importer votre fonction verifySignature
import { verifySignature } from '../../src/utils/security';
describe('Webhook Signature Verification', () => {
const testSecret = 'whsec_test_secret_string';
const testPayload = JSON.stringify({
id: 'evt_test',
event: 'PAYMENT_SUCCEEDED',
data: {},
});
const payloadBuffer = Buffer.from(testPayload, 'utf8');
it('should return true for a valid signature', () => {
const expectedSignature = crypto
.createHmac('sha256', testSecret)
.update(payloadBuffer)
.digest('hex');
const isValid = verifySignature(
payloadBuffer,
expectedSignature,
testSecret,
);
expect(isValid).toBe(true);
});
it('should return false for an invalid signature', () => {
const invalidSignature = 'invalid_signature_string';
const isValid = verifySignature(
payloadBuffer,
invalidSignature,
testSecret,
);
expect(isValid).toBe(false);
});
it('should return false if the secret is wrong', () => {
const expectedSignature = crypto
.createHmac('sha256', testSecret)
.update(payloadBuffer)
.digest('hex');
const wrongSecret = 'whsec_wrong_secret';
const isValid = verifySignature(
payloadBuffer,
expectedSignature,
wrongSecret,
);
expect(isValid).toBe(false);
});
});Tests de gestion d’erreurs
Vérifiez comment votre application réagit aux erreurs d’API lomi. spécifiques.
describe('API Error Handling', () => {
let lomi: LomiSDK;
beforeAll(() => {
/* setup lomi instance */
});
it('should handle invalid request errors (400)', async () => {
try {
await lomi.checkoutSessions.createCheckoutSession({
merchant_id: testConfig.merchantId!,
amount: -100, // Invalid amount
currency_code: 'XXX', // Invalid currency
success_url: 'invalid-url', // Invalid URL
cancel_url: 'invalid-url',
});
fail('Request should have failed');
} catch (error: any) {
expect(error.statusCode).toBe(400);
expect(error.message).toContain('Validation failed'); // Or specific lomi. error message
// Vous pouvez aussi inspecter error.details pour des erreurs de champs précises
}
});
it('should handle authentication errors (401)', async () => {
const invalidLomi = new LomiSDK({
apiKey: 'lomi_sk_test_invalidkey',
baseUrl: '...',
});
try {
await invalidLomi.providers.listProviders();
fail('Request should have failed');
} catch (error: any) {
expect(error.statusCode).toBe(401);
expect(error.message).toContain('Invalid API key');
}
});
});Tests de bout en bout (E2E)
Simulez un parcours utilisateur complet incluant le paiement.
Préparer l’environnement de test
Utilisez Playwright ou Cypress avec votre framework de tests. Le script de configuration doit :
- Démarrer votre application ;
- Démarrer un écouteur webhook (par ex.
ngroket un serveur léger, ou un helper dédié) ; - Garantir la présence des données de test dans le bac à sable lomi. (marchand de test, produits).
Simuler le parcours de paiement
Un script E2E fait typiquement :
- Parcourir l’application pour lancer un paiement ;
- Déclencher la création d’une session de paiement lomi. via votre backend ;
- Point délicat : interagir avec la page Checkout bac à sable lomi.. Souvent instable en E2E. Pistes :
- Utiliser les numéros ou méthodes de test du bac à sable qui réussissent ou échouent automatiquement ;
- Exposer un point de terminaison dans votre environnement de test qui simule le webhook qu’envoierait lomi. à la fin (contourner l’UI bac à sable) — souvent plus fiable pour l’automatisation ;
- Attendre et vérifier la réception du webhook attendu (
PAYMENT_SUCCEEDED) ; - Vérifier que l’état applicatif est correct (commande payée, service provisionné, etc.).
describe('E2E Payment Flow', () => {
it('should complete payment and update order status', async () => {
// 1. L’utilisateur lance le checkout dans l’UI (simulé par des actions de test)
const { orderId, lomiCheckoutSessionId } = await initiateCheckoutInApp();
// 2. Simuler le webhook de paiement réussi
// (plutôt que l’UI, appeler votre endpoint de simulation de test)
await simulateLomiWebhook(lomiCheckoutSessionId, 'PAYMENT_SUCCEEDED');
// 3. Attendre le traitement du webhook par l’app
await waitForOrderStatusUpdate(orderId, 'PAID');
// 4. Vérifier l’état final
const orderStatus = await getOrderStatusFromApp(orderId);
expect(orderStatus).toBe('PAID');
});
});Utilitaires de test
Helper d’écoute webhook
Créez une classe pour capturer et attendre des événements webhook pendant les tests.
import http from 'http';
import express from 'express';
interface RecordedEvent {
id: string;
type: string;
receivedAt: number;
payload: any;
}
export class TestWebhookListener {
private app = express();
private server: http.Server | null = null;
private receivedEvents: RecordedEvent[] = [];
private port = 9090; // Ou port dynamique
constructor() {
this.app.use(express.raw({ type: 'application/json' }));
this.app.post('/test-webhook', (req, res) => {
try {
// Validation basique — en PRODUCTION, vérification complète de signature !
const payload = JSON.parse(req.body.toString());
console.log(`Test listener received event: ${payload.event}`);
this.receivedEvents.push({
id: payload.id,
type: payload.event,
receivedAt: Date.now(),
payload,
});
res.status(200).json({ received: true });
} catch (e) {
console.error('Test listener error parsing body', e);
res.status(400).json({ error: 'Invalid payload' });
}
});
}
start() {
this.server = this.app.listen(this.port);
console.log(`Test webhook listener started on port ${this.port}`);
return `http://localhost:${this.port}/test-webhook`; // URL à configurer dans lomi.
}
stop() {
this.server?.close();
console.log('Test webhook listener stopped.');
}
async waitForEvent(
eventType: string,
timeoutMs = 10000,
): Promise<RecordedEvent> {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const found = this.receivedEvents.find((e) => e.type === eventType);
if (found) return found;
await new Promise((r) => setTimeout(r, 200)); // Intervalle de sondage
}
throw new Error(`Timeout waiting for webhook event type: ${eventType}`);
}
}Générateur de données de test
Produisez des données de test cohérentes.
export class TestDataFactory {
static createCheckoutData(overrides: Partial<any> = {}) {
return {
merchant_id: process.env.TEST_MERCHANT_ID!,
amount: 100,
currency_code: 'XOF',
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
metadata: { testId: `td_${Date.now()}` },
...overrides,
};
}
// Ajouter d’autres méthodes...
}Intégration CI/CD
Intégrez les tests automatiques dans votre pipeline (par ex. GitHub Actions).
# .github/workflows/test.yml
name: Run Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Run Unit & Integration Tests
run: npm test
env:
LOMI_TEST_API_KEY: ${{ secrets.LOMI_TEST_API_KEY }}
LOMI_TEST_WEBHOOK_SECRET: ${{ secrets.LOMI_TEST_WEBHOOK_SECRET }}
TEST_MERCHANT_ID: ${{ secrets.TEST_MERCHANT_ID }}
# Autres variables d’environnement de test nécessairesÉtapes suivantes
Bonnes pratiques de sécurité
Mettre en œuvre une sécurité solide est indispensable lorsque vous traitez des paiements et intégrez des API tierces comme lomi.. Suivez ces recommandations pour une intégration sécurisée.
CI/CD
Ce guide présente les bonnes pratiques pour intégrer lomi. à votre pipeline CI/CD, avec des déploiements fiables et des tests automatisés.