Docs › Quickstarts › Angular (SSR)
BackendIntégrer NaabigaPay en Angular (SSR)
Le handler serveur (Express) détient la clé secrète et crée le lien, l'app appelle cette route puis redirige vers la page de paiement.
sk_live_…) ne vit que dans le handler serveur (server.ts), jamais dans un composant expédié au navigateur : le code des composants est téléchargé et lisible par le client. C'est le serveur SSR qui appelle NaabigaPay avec la clé.Le principe
- Le composant appelle la route serveur
/api/pay(servie par votreserver.ts). - Le serveur SSR appelle NaabigaPay avec la clé secrète et renvoie
{ url }. - Le composant redirige le navigateur vers cette
url, puis relit le statut au retour.
1.La route serveur : créer le lien
Ajoutez une route Express au serveur SSR d'Angular. Elle seule connaît la clé et appelle POST/v1/payment-links.
import express from 'express';
const NPAY = 'https://api.pay.naabiga.com/api/v1';
const SECRET = process.env['NPAY_SECRET']; // sk_live_... : reste sur le serveur SSR
// À appeler dans le bootstrap Express d'Angular, avant le rendu SSR.
export function ajouterRoutesPaiement(server: express.Express) {
server.use(express.json());
// L'app appelle CETTE route ; elle seule détient la clé secrète.
server.post('/api/pay', async (req, res) => {
const { commande, amount } = req.body;
const r = await fetch(`${NPAY}/payment-links`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${SECRET}`,
'Content-Type': 'application/json',
'Idempotency-Key': `cmd-${commande}`, // évite un double lien si retry
},
body: JSON.stringify({
amount, // entier, en FCFA
reference: commande, // votre numéro de commande
description: `Commande ${commande}`,
return_url: 'https://monsite.com/merci',
cancel_url: 'https://monsite.com/panier',
single_use: true,
}),
});
if (!r.ok) return res.status(502).json({ error: await r.text() });
const lien = await r.json();
res.json({ url: lien.url }); // l'app ouvre cette URL
});
}La réponse contient url (ex. https://pay.naabiga.com/link/9f3c…) : la page où le client paie. Pour un montant libre, remplacez amount par amount_min, amount_max et une description.
2.Le service : appeler la route serveur
Le service utilise HttpClient pour appeler votre route /api/pay (jamais NaabigaPay directement) et récupérer l'url.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class PaiementService {
constructor(private http: HttpClient) {}
// Appelle la route SSR /api/pay (c'est elle qui détient la clé secrète).
creerLien(commande: string, montant: number): Observable<{ url: string }> {
return this.http.post<{ url: string }>('/api/pay', { commande, amount: montant });
}
// Relit le statut chez VOUS ; votre backend fait foi (webhook signé).
statut(ref: string): Observable<{ statut: string }> {
return this.http.get<{ statut: string }>(`/api/commandes/${ref}/statut`);
}
}3.Le bouton : rediriger vers le paiement
Le clic ne s'exécute que dans le navigateur : window y est disponible. Le composant appelle le service, récupère l'url, puis redirige.
import { Component } from '@angular/core';
import { PaiementService } from './paiement.service';
@Component({
selector: 'app-bouton-payer',
standalone: true,
template: `
<button (click)="payer()" [disabled]="chargement">
{{ chargement ? 'Redirection…' : 'Payer' }}
</button>
`,
})
export class BoutonPayerComponent {
chargement = false;
constructor(private paiement: PaiementService) {}
payer() {
this.chargement = true;
// 1) Demander le lien à la route serveur.
this.paiement.creerLien('CMD-1042', 5000).subscribe(({ url }) => {
// 2) Ouvrir la page de paiement NaabigaPay.
window.location.href = url;
});
}
}Astuce. Ne créditez rien depuis l'app : le retour navigateur peut être manqué ou rejoué. Seul le webhook signé reçu par votre serveur (voir la doc backend) confirme le paiement ; l'app se contente de relire le statut chez vous.
Référence rapide
| Méthode | Endpoint | Rôle |
|---|---|---|
| POST | /v1/payment-links | Créer un lien de paiement |
| GET | /v1/payments/{reference} | Statut d'un paiement |
Base : https://api.pay.naabiga.com/api/v1 · Auth : Authorization: Bearer sk_…. Voir la documentation complète et le format des webhooks.