Documentation API Intégration Frontend

Intégration Frontend

Integrate the payment button into any modern frontend framework. Always through your backend.

Principle

Frontend NEVER talks to GerminoPay directly Your frontend calls YOUR backend, which then securely calls GerminoPay with the secret key.

Vanilla JS

<button id="payBtn">Payer 5 000 F CFA</button>

<script>
document.getElementById('payBtn').addEventListener('click', async () => {
  try {
    const res = await fetch('/api/creer-paiement', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        montant: 5000,
        devise: 'XOF',
        reference: 'CMD-' + Date.now(),
      }),
    });
    const data = await res.json();
    if (data.payment_url) {
      window.location.href = data.payment_url;
    }
  } catch (err) {
    alert('Erreur : ' + err.message);
  }
});
</script>

React

PayButton.jsx
import { useState } from 'react';

export default function PayButton({ montant, devise = 'XOF', reference }) {
  const [loading, setLoading] = useState(false);

  const handlePay = async () => {
    setLoading(true);
    try {
      const res = await fetch('/api/creer-paiement', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ montant, devise, reference }),
      });
      const data = await res.json();
      if (data.payment_url) {
        window.location.href = data.payment_url;
      } else {
        alert('Erreur : ' + (data.error || 'Inconnu'));
      }
    } catch (err) {
      alert('Erreur réseau');
    } finally {
      setLoading(false);
    }
  };

  return (
    <button onClick={handlePay} disabled={loading}>
      {loading ? 'Chargement...' : `Payer ${montant.toLocaleString()} ${devise}`}
    </button>
  );
}

Vue 3

PayButton.vue
<template>
  <button @click="payer" :disabled="loading">
    {{ loading ? 'Chargement...' : `Payer ${montant.toLocaleString()} ${devise}` }}
  </button>
</template>

<script setup>
import { ref } from 'vue';

const props = defineProps({
  montant: Number,
  devise: { type: String, default: 'XOF' },
  reference: String,
});

const loading = ref(false);

async function payer() {
  loading.value = true;
  try {
    const res = await fetch('/api/creer-paiement', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        montant: props.montant,
        devise: props.devise,
        reference: props.reference,
      }),
    });
    const data = await res.json();
    if (data.payment_url) window.location.href = data.payment_url;
  } finally {
    loading.value = false;
  }
}
</script>

Angular

pay-button.component.ts
import { Component, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-pay-button',
  template: `
    <button (click)="payer()" [disabled]="loading">
      {{ loading ? 'Chargement...' : 'Payer ' + montant + ' ' + devise }}
    </button>
  `,
})
export class PayButtonComponent {
  @Input() montant!: number;
  @Input() devise = 'XOF';
  @Input() reference!: string;
  loading = false;

  constructor(private http: HttpClient) {}

  payer() {
    this.loading = true;
    this.http.post<any>('/api/creer-paiement', {
      montant: this.montant,
      devise: this.devise,
      reference: this.reference,
    }).subscribe({
      next: (data) => {
        if (data.payment_url) window.location.href = data.payment_url;
        this.loading = false;
      },
      error: () => { this.loading = false; },
    });
  }
}