embed.js affiche le widget de paiement dans une modale sur votre site, sans rediriger le client.
embed.js ouvre le checkout IzichangePay dans une modale (iframe) directement sur votre page, au lieu de rediriger le client vers la page de paiement hébergée. Le client paie sans quitter votre site ; à la fin, le bouton de sortie devient simplement « Fermer » et la modale se referme.
Le payment intent est toujours créé côté serveur avec votre clé secrète. embed.js ne fait qu’afficher un intent déjà créé : aucune clé n’est exposée au navigateur.
Démo live — IziShop
Boutique e-commerce de démonstration qui intègre embed.js en conditions réelles (Tron testnet, paiement en TRX / USDT). Ajoutez un article au panier puis lancez le paiement : la modale de checkout s’ouvre sans quitter la page, exactement comme décrit dans ce guide.
Trois façons d’intégrer, du plus simple au plus flexible :
Méthode
Backend requis ?
Montant
Pour qui
1. Bouton sans code (lien Produit)
❌ Non
Fixe (défini au dashboard)
Sites no-code, montant connu
2. Bouton géré par le SDK (IziPay.Button)
✅ Oui
Dynamique (panier)
Boutiques, montant calculé
3. Ouverture programmée (IziPay.open)
✅ Oui
Dynamique
Contrôle total du déclenchement
Dans tous les cas, la clé secrète sk_… ne quitte jamais le serveur. Le navigateur ne manipule qu’un identifiant public : le publicId de l’intent ou le slug du produit. La confirmation fait toujours foi via le webhook signépayment_intent.completed.
Choisissez la forme (pill · rounded · soft), la couleur (teal · sombre · bleue) et la taille (sm · normal · lg · xl), prévisualisez en direct, puis copiez le code HTML ou JS. Le bouton utilise toujours la police de marque (Typold) et votre logo.
Pour un montant fixe, aucun serveur n’est nécessaire. Créez un produit dans le dashboard (Vente → Produits) : vous obtenez un lien https://checkout.pay.izichange.com/pay/product/<slug>. Le montant est figé côté IzichangePay — le client ne peut pas le modifier.Collez le loader, puis un bouton portant l’attribut data-izipay-url :
<script src="https://checkout.pay.izichange.com/embed.js"></script><button data-izipay-url="https://checkout.pay.izichange.com/pay/product/<slug>"> Payer avec IzichangePay</button>
embed.js câble automatiquement tout élément [data-izipay-url] (ou [data-izipay-intent]) : au clic, la modale s’ouvre. Pas une ligne de JavaScript.
Attribut
Rôle
data-izipay-url
Lien de checkout / produit à ouvrir.
data-izipay-intent
publicId d’un PaymentIntent (alternative à l’URL).
data-izipay-locale
Langue du widget (fr, en).
data-izipay-success-url
Page vers laquelle rediriger une fois le paiement confirmé et la modale fermée.
data-izipay-container
Sélecteur CSS pour monter le widget en ligne au lieu d’une modale.
Pour réagir au résultat, écoutez les CustomEvents émis sur le bouton :
<button id="pay" data-izipay-url="https://checkout.pay.izichange.com/pay/product/<slug>"> Payer avec IzichangePay</button><script> document.getElementById('pay').addEventListener('izipay:success', function (e) { console.log('Payé', e.detail); // { intentId, amount, assetCode, network } }); // également émis : izipay:expired, izipay:failed, izipay:error, izipay:close</script>
izipay:success est un signal d’interface. Ne livrez jamais la commande dessus seul : la source de vérité reste le webhookpayment_intent.completed traité côté serveur.
Méthode 2 — Bouton géré par le SDK (montant dynamique)
Pour un montant calculé (panier), le bouton appelle votre serveur au clic — le modèle des Smart Buttons PayPal. embed.js dessine le bouton ; votre serveur crée l’intent avec la clé secrète et renvoie son publicId ; la modale s’ouvre.Côté navigateur :
<script src="https://checkout.pay.izichange.com/embed.js"></script><div id="pay-container"></div><script> IziPay.Button({ // Appelé au clic. Renvoie le publicId de l'intent (ou un objet // { id | publicId | url }). N'exposez JAMAIS la clé secrète ici. createIntent: function () { return fetch('/api/create-intent', { method: 'POST' }) .then(function (r) { return r.json(); }) .then(function (d) { return d.publicId; }); }, label: 'Payer avec IzichangePay', locale: 'fr', onSuccess: function (d) { /* signal UI — la vérité reste le webhook */ }, onClose: function () { /* modale fermée */ }, onError: function (e) { console.error(e); } }).render('#pay-container');</script>
Côté serveur (Node + SDK) — la clé secrète reste ici :
// POST /api/create-intentapp.post('/api/create-intent', async (req, res) => { const intent = await izipay.paymentIntents.create({ requestedCurrencyType: 'fiat', currencyRequested: 'XOF', amountRequested: panierTotalXOF, // montant calculé côté serveur merchantReference: 'order_4821', }); res.json({ publicId: intent.id }); // seul l'identifiant public part au navigateur});
Option de IziPay.Button({...})
Type
Rôle
createIntent
() => Promise<string | { id|publicId|url }>
Appelle votre serveur ; renvoie l’intent.
url / intentId
string
Alternative statique à createIntent.
label
string
Texte affiché avant le logo (défaut « Payer avec »).
logo
boolean
Affiche le logo IzichangePay complet dans le bouton (défaut true). false pour masquer.
shape
'pill' | 'rounded' | 'soft'
Forme des angles (défaut rounded). Aplat de marque, sans ombre, police Typold.
Comme pour le flux par redirection, créez un payment intent et récupérez sa réponse (qui contient id et paymentUrl). Renvoyez paymentUrl (ou id) à votre page.
// Votre backend — clé secrète, jamais exposée au clientconst intent = await izipay.paymentIntents.create({ requestedCurrencyType: 'fiat', currencyRequested: 'XOF', amountRequested: 5000, merchantReference: 'order_4821',});// → renvoyez intent.paymentUrl (ou intent.id) au front
<script src="https://checkout.pay.izichange.com/embed.js"></script><script> document.querySelector('#pay').addEventListener('click', function () { IziPay.open({ url: intentPaymentUrl, // intent.paymentUrl renvoyé par votre serveur // ou : intentId: 'pi_xxx', // alternative : le publicId de l'intent onSuccess: function (data) { // { intentId, amount, assetCode, network } // Paiement confirmé. Mettez à jour votre commande ici. console.log('Payé', data); }, onExpired: function () { /* l'intent a expiré */ }, onFailed: function () { /* paiement échoué */ }, onError: function () { /* erreur inattendue */ }, onClose: function () { /* le client a fermé la modale */ }, }); });</script>
N’utilisez jamaisonSuccess seul pour livrer la commande : c’est un signal d’interface. La source de vérité reste votre webhookpayment_intent.completed (signé), traité côté serveur. Voir Webhooks.
Le widget n’envoie ses messages qu’à l’origine exacte de votre page (jamais *) : le navigateur ne les délivre qu’à votre site.
embed.js n’accepte en retour que les messages provenant de l’origine du widget IzichangePay.
Le checkout autorise l’embarquement par iframe (frame-ancestors) car c’est sa fonction ; aucune action de paiement n’est déclenchée sans envoi crypto explicite du client.