Ghiduri practice
Încasează o comandă cu Monedo Checkout
Un exemplu server-side complet pentru plăți unice, cu redirect, confirmare și retry sigur.
1. Pregătește comanda și integrarea
Exemplul de mai jos folosește SDK-ul Payments și metoda de captură automată. Ai nevoie de o cheie Sandbox activă, permisiuni pentru creare plăți și sesiuni checkout, o comandă salvată și URL-uri de retur înregistrate. returnOrigin vine din configurația serverului, nu dintr-un parametru furnizat de client. Pentru un marketplace, order.merchantId este comerciantul autorizat al comenzii; pentru încasarea proprie a unei instalări directe nu îl adăuga arbitrar.
- order.id: identificator stabil din baza ta de date.
- order.totalMinor: întreg în subdiviziunile monedei; 4900 înseamnă 49,00 RON.
- order.currency: moneda comenzii, de exemplu ron.
- Nu reutiliza aceeași cheie de idempotency dacă schimbi suma sau parametrii.
2. Creează plata și sesiunea
Funcția acceptă dependențe explicit și poate fi utilizată într-un handler autentificat. Salvează paymentId și sessionId într-o tranzacție locală înainte să trimiți url către browser. Cheile rămân stabile la reluarea aceleiași operații. Dacă un request expiră, citește resursa cunoscută ori reia exact requestul, nu crea o altă comandă.
import { MonedoPayments } from '@monedo/payments';
// Call from your authenticated backend. Load the order and total from your database,
// not from the browser. Persist order.id -> payment.id -> session.id before redirect.
export async function createOrderCheckout({ apiKey, order, returnOrigin, fetch }) {
const monedo = new MonedoPayments({ apiKey, fetch });
const payment = await monedo.payments.create({
amount: order.totalMinor,
currency: order.currency,
external_reference: order.id,
description: `Order ${order.id}`,
...(order.merchantId ? { merchant: order.merchantId } : {}),
}, { idempotencyKey: `order_${order.id}_payment_v1` });
const session = await monedo.checkoutSessions.create({
payment_intent: payment.id,
title: `Order ${order.id}`,
success_url: `${returnOrigin}/payment/return`,
cancel_url: `${returnOrigin}/payment/cancel`,
}, { idempotencyKey: `order_${order.id}_checkout_v1` });
if (!session.checkout_url) throw new Error('Checkout URL unavailable; retrieve the session before retrying');
return { paymentId: payment.id, sessionId: session.id, url: session.checkout_url };
}
// Redirect to the returned Monedo URL. Do not mark the order paid here.
// On return, retrieve the saved payment on the server and verify status === 'succeeded'.
// A verified webhook is also required when the customer does not return.
3. Confirmă pe server, nu din URL
Redirecționează clientul către session.checkout_url exact cum este returnat. La întoarcere, găsește plata din asocierea locală a comenzii, verifică apartenența la utilizatorul curent și citește payments.retrieve(paymentId). Livrează numai când status este succeeded. authorized înseamnă sumă autorizată, nu capturată; processing înseamnă să aștepți și să reverifici. Păstrează o stare de confirmare în curs în interfață în loc să afișezi succes sau eșec prematur.
4. Acoperă abandonul și revenirea
- Clientul poate plăti și apoi închide pagina. Webhookul verificat trebuie să finalizeze comanda și fără redirect.
- Expirarea sesiunii nu este echivalentă cu anularea unei plăți deja confirmate. Recitește plata înainte de a oferi un nou checkout.
- Livrează o singură dată: protejează schimbarea locală în paid și jobul de fulfillment cu o tranzacție și o cheie unică.
- Nu afișa cheia secretă sau client_secret în URL-ul de suport și nu le scrie în loguri.
- Disponibilitatea portofelelor digitale depinde de dispozitiv, browser, monedă și configurarea contului; nu promite aceeași metodă tuturor clienților.