93 lines
3.7 KiB
PHP
Executable File
93 lines
3.7 KiB
PHP
Executable File
<?php
|
||
|
||
?>
|
||
|
||
<!doctype html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Paiement Mobile Money</title>
|
||
<!-- 1) Import Seamless SDK -->
|
||
<script src="https://cdn.cinetpay.com/seamless/main.js" type="text/javascript"></script>
|
||
<style>
|
||
body { font-family: system-ui, sans-serif; margin: 2rem; }
|
||
.btn { padding:.8rem 1.2rem; border:0; border-radius:.5rem; cursor:pointer; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>Payer mon panier</h1>
|
||
|
||
<label>Montant (XOF)</label><br/>
|
||
<input id="amount" type="number" value="25000" min="5" step="5" /><br/><br/>
|
||
|
||
<label>Téléphone (E.164, ex: +2250700000000)</label><br/>
|
||
<input id="msisdn" type="tel" value="+2250700000000" /><br/><br/>
|
||
|
||
<button class="btn" id="payBtn">Payer par Mobile Money</button>
|
||
|
||
<script>
|
||
const APIKEY = "VOTRE_APIKEY"; // .env côté front si nécessaire, sinon donnez juste site_id ici et mettez apikey côté back
|
||
const SITE_ID = "VOTRE_SITE_ID";
|
||
const NOTIFY_URL = "https://votre-domaine.com/api/cinetpay/notify"; // webhook serveur
|
||
|
||
async function createOrder(amount) {
|
||
const r = await fetch("/api/cinetpay/new", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ amount_xof: amount })
|
||
});
|
||
if (!r.ok) throw new Error("init error");
|
||
return r.json(); // {order_ref:"...", amount_xof:...}
|
||
}
|
||
|
||
async function launchCheckout() {
|
||
const amount = parseInt(document.getElementById("amount").value, 10);
|
||
if (isNaN(amount) || amount % 5 !== 0) return alert("Montant multiple de 5 requis");
|
||
|
||
const msisdn = document.getElementById("msisdn").value.trim();
|
||
|
||
// 1) Créer / réserver la transaction côté serveur
|
||
const { order_ref } = await createOrder(amount);
|
||
|
||
// 2) Config Seamless
|
||
CinetPay.setConfig({
|
||
apikey: APIKEY,
|
||
site_id: SITE_ID,
|
||
mode: "PRODUCTION", // cf. doc; sandbox parfois indisponible
|
||
notify_url: NOTIFY_URL // URL webhook serveur
|
||
});
|
||
|
||
// 3) Ouvrir le guichet Seamless
|
||
CinetPay.getCheckout({
|
||
transaction_id: order_ref, // identique à la transaction serveur
|
||
amount: amount,
|
||
currency: "XOF",
|
||
channels: "MOBILE_MONEY", // forcer Mobile Money
|
||
description: "Paiement " + order_ref,
|
||
// Option pratique pour STK/USSD (si activé côté compte)
|
||
lock_phone_number: true,
|
||
customer_phone_number: msisdn,
|
||
// (champs carte: customer_name/surname/email/adresse... seulement si vous acceptez la carte)
|
||
});
|
||
|
||
// 4) Callback local (UX seulement). Pour l’*autorité*, fiez-vous au webhook + /v2/payment/check côté serveur.
|
||
CinetPay.waitResponse(async function (data) {
|
||
// data.status: "ACCEPTED" ou "REFUSED"
|
||
if (data.status === "ACCEPTED") {
|
||
alert("Paiement accepté. Vérification en cours…");
|
||
// (facultatif) ping un endpoint maison qui relit la DB
|
||
const s = await fetch(`/api/cinetpay/status?order_ref=${encodeURIComponent(order_ref)}`).then(r => r.json());
|
||
if (s.status === "SUCCESS") window.location.href = "/merci";
|
||
} else if (data.status === "REFUSED") {
|
||
alert("Paiement refusé.");
|
||
}
|
||
});
|
||
}
|
||
|
||
document.getElementById("payBtn").addEventListener("click", () => {
|
||
launchCheckout().catch(e => alert(e.message || "Erreur paiement"));
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|