NaabigaPay · Angular (SSR)
QuickstartsDocs

DocsQuickstarts › Angular (SSR)

Backend

Inté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.

À lire en premier. Même avec le rendu côté serveur, la clé secrète (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

  1. Le composant appelle la route serveur /api/pay (servie par votre server.ts).
  2. Le serveur SSR appelle NaabigaPay avec la clé secrète et renvoie { url }.
  3. 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.

server.ts
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.

paiement.service.ts
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.

bouton-payer.component.ts
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éthodeEndpointRôle
POST/v1/payment-linksCré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.