A complete MonCash checkout flow in Node.js: create, redirect, verify
posée 4 months ago231 vuesen
0
I've read the MonCash docs, but I'm confused about how the pieces connect. Can someone show the whole flow end to end: creating the payment, sending the customer to MonCash, and confirming the payment afterwards?
Environnement :Node.js 20Express
Diagnostic IA
Généré par IA. Ce n'est pas une réponse — la communauté ci-dessous le confirme ou le corrige. Vérifiez toujours avant de vous y fier.
posée 4 months ago
Marie Louis 2.2k
1 réponse
3
✓✓ Réponse acceptée
Three server-side steps, with the customer's browser in the middle:
[your server] CreatePayment ──► payment token
[browser] redirect to MonCash page ──► customer enters phone + PIN on MonCash
[MonCash] redirects to your return URL (?transactionId=…)
[your server] RetrieveTransactionPayment ──► verify amount + status ──► fulfil
// 1. Create the payment (server)
app.post("/checkout/:orderId", async (req, res) => {
const order = await db.order.findUniqueOrThrow({ where: { id: req.params.orderId } });
const token = await moncashToken(); // cached token, see the token-expiry question
const r = await fetch(MONCASH.api + "/v1/CreatePayment", {
method: "POST",
headers: { Authorization: "Bearer " + token, "Content-Type": "application/json" },
body: JSON.stringify({ amount: order.totalHtg, orderId: order.id }),
});
if (!r.ok) return res.status(502).send("MonCash unavailable, please retry");
const { payment_token } = await r.json();
// 2. Send the customer to MonCash
res.redirect(MONCASH.gateway + "/Payment/Redirect?token=" + encodeURIComponent(payment_token.token));
});
// 3. Return URL, configured in the MonCash merchant portal
app.get("/moncash/return", async (req, res) => {
const transactionId = String(req.query.transactionId ?? "");
const token = await moncashToken();
const r = await fetch(MONCASH.api + "/v1/RetrieveTransactionPayment", {
method: "POST",
headers: { Authorization: "Bearer " + token, "Content-Type": "application/json" },
body: JSON.stringify({ transactionId }),
});
const { payment } = await r.json();
const order = await db.order.findUnique({ where: { id: payment?.reference } });
const paid = payment?.message === "successful" && order && Number(payment.cost) === order.totalHtg;
if (!paid) return res.redirect("/orders/payment-failed");
await markPaidOnce(order.id, payment.transaction_id); // idempotent
res.redirect("/orders/" + order.id + "/thank-you");
});
The rules that matter:
- Never trust the return URL alone. Anyone can type
?transactionId=into a browser. Always re-fetch the payment from the API. - Compare the amount with your order. Don't just check that "a payment" exists.
referenceis theorderIdyou sent. Use it to find the order.- Make fulfilment idempotent: a refresh of the return page must not ship twice.
Connectez-vous pour dire si ça a marché.
answered 4 months ago
David Charles 2.9k
Sign in and verify your email to post an answer.