Portefeuille d'application DEUNA via widget
Sur cette page
Conditions préalables#
Avant de mettre en œuvre Portefeuille d'applications Deuna paiements, assurez-vous d’avoir :
- Activé Portefeuille d'applications Deuna dans le panneau d'administration de Deuna
- Généré un jeton de commande via l'API Deuna
- Intégré le SDK Deuna dans votre projet
- Examiné le Documentation du widget de paiement pour votre plateforme
- Sélectionnez votre préféré mode de paiement (Code numérique ou QR) dans le panneau d'administration
Configuration du widget de paiement#
Implémentation de base
Initialisez le widget de paiement avec le deuna_wallet processeur :
DeunaSDK.initPaymentWidget({
orderToken: '',
paymentMethods: [
{
paymentMethod: 'voucher',
processors: ['deuna_wallet'],
},
],
callbacks: {
onSuccess: (data) => {
console.log('Payment successful:', data);
// Redirect to success page
},
onError: (error) => {
console.log('Payment failed:', error);
// Show error message to user
},
onPending: (data) => {
console.log('Payment pending confirmation:', data);
// Show waiting screen
},
},
});Exemple complet avec toutes les options
DeunaSDK.initPaymentWidget({
orderToken: '',
paymentMethods: [
{
paymentMethod: 'voucher',
processors: ['deuna_wallet'],
metadata: {
// Optional: Pass additional data
orderId: 'your-internal-order-id',
},
},
],
callbacks: {
onSuccess: (response) => {
console.log('Payment confirmed:', {
orderId: response.order_id,
orderToken: response.order_token,
status: response.status,
amount: response.amount,
currency: response.currency,
});
// Verify payment on your backend
fetch('/api/verify-payment', {
method: 'POST',
body: JSON.stringify({
orderToken: response.order_token,
orderId: response.order_id,
}),
})
.then(res => res.json())
.then(data => {
if (data.verified) {
window.location.href = '/order-confirmation';
}
});
},
onError: (error) => {
console.error('Payment error:', {
code: error.code,
message: error.message,
});
// Show user-friendly error message
showErrorModal({
title: 'Payment Failed',
message: 'Unable to process your payment. Please try again.',
});
},
onPending: (response) => {
console.log('Payment pending user confirmation:', {
orderId: response.order_id,
expiresAt: response.expires_at,
});
},
onExpired: (response) => {
console.log('Payment code/QR expired:', {
orderId: response.order_id,
expiredAt: response.expired_at,
});
},
},
});Modes de paiement#
Comprendre les deux modes
Votre compte marchand est configuré avec un de ces modes dans le panneau d'administration :
Mode 1 : Code numérique (fenêtre de 3 minutes)
Ce que voit le client :
- Un code numérique à 6 chiffres affiché à l'écran
- Compte à rebours indiquant le temps restant (0:00-3:00)
- Instructions pour ouvrir l'application Deuna et saisir le code
Flux client :
- Note le code à 6 chiffres
- Ouvre l'application Deuna
- Sélectionne « Payer avec code »
- Saisit le code à 6 chiffres
- Confirme le paiement dans l'application
- Paiement confirmé immédiatement via webhook
Configuration : Défini dans le panneau d'administration sous les paramètres du processeur Deuna App Wallet
Mode 2 : code QR (fenêtre de 15 minutes)
Ce que voit le client :
- Un code QR dynamique à l'écran
- Compte à rebours indiquant le temps restant (0:00-15:00)
- Deux options pour procéder :
- Scannez QR avec la caméra de l'application Deuna
- Cliquez sur QR pour ouvrir l'application directement
Flux client :
-
Option A – Numériser :
- Ouvre la caméra de l'application Deuna
- Scanne le code QR
- La page de paiement s'ouvre automatiquement
- Confirme le paiement dans l'application
- Paiement confirmé via webhook
-
Option B - Cliquez :
- Clique sur le code QR ou sur le bouton
- Ouvre directement l'application Deuna
- Affiche l'écran de confirmation du paiement
- Confirme le paiement
- Paiement confirmé via webhook
Configuration : Défini dans le panneau d'administration sous les paramètres du processeur Deuna App Wallet
Remarque : La sélection du mode se produit une fois lors de la configuration initiale dans le panneau d'administration. Toutes les commandes ultérieures utiliseront le mode configuré. Contactez l'assistance Deuna pour changer de mode.
Traitement de la confirmation de paiement#
Confirmation basée sur un webhook (primaire)
Le Deuna App Wallet envoie une notification webhook à votre backend lorsque le client confirme le paiement :
// Your backend webhook endpoint
app.post('/webhooks/deuna-wallet', (req, res) => {
const { order_id, order_token, status, amount, currency } = req.body;
// Verify webhook signature (recommended)
const isValid = verifyWebhookSignature(req);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Handle confirmation
if (status === 'confirmed') {
// Update your database
updateOrder(order_id, {
status: 'paid',
paidAt: new Date(),
amount: amount,
currency: currency,
});
// Send confirmation email to customer
sendConfirmationEmail(order_id);
}
// Acknowledge receipt
res.json({ success: true });
});Repli d'interrogation (secondaire)
Si la livraison du webhook est retardée ou échoue, le système interroge le /order point final toutes les 3 secondes :
// Client-side polling (handled automatically by SDK)
// But you can also implement it manually if needed
const pollOrderStatus = async (orderToken) => {
const maxAttempts = 60; // 3 minutes for numeric code
let attempts = 0;
while (attempts < maxAttempts) {
try {
const response = await fetch(`/api/order/${orderToken}`);
const order = await response.json();
if (order.status === 'confirmed') {
handlePaymentSuccess(order);
return;
}
if (order.status === 'expired') {
handlePaymentExpired(order);
return;
}
// Wait 3 seconds before polling again
await new Promise(resolve => setTimeout(resolve, 3000));
attempts++;
} catch (error) {
console.error('Polling error:', error);
}
}
handlePaymentExpired();
};Objets de réponse#
Réponse réussie
Lorsque le paiement est confirmé, onSuccess le rappel reçoit :
{
order_id: "order_abc123def456",
order_token: "token_xyz789",
status: "confirmed",
payment_method: "deuna_wallet",
amount: 99.99,
currency: "USD",
timestamp: "2024-03-20T14:30:45Z",
metadata: {
// Any metadata passed during initialization
}
}Réponse à l'erreur
Lorsque le paiement échoue, onError le rappel reçoit :
{
code: "PAYMENT_FAILED",
message: "Unable to process payment",
order_id: "order_abc123def456",
details: {
reason: "Insufficient funds in Deuna wallet"
}
}En attente de réponse
En attendant la confirmation de l'utilisateur, onPending le rappel reçoit :
{
order_id: "order_abc123def456",
order_token: "token_xyz789",
status: "pending",
payment_method: "deuna_wallet",
code_or_qr: "123456", // For numeric code mode
expires_at: "2024-03-20T14:33:45Z",
expires_in_seconds: 180
}Réponse expirée
Lorsque le code/QR expire, onExpired le rappel reçoit :
{
order_id: "order_abc123def456",
order_token: "token_xyz789",
status: "expired",
payment_method: "deuna_wallet",
expired_at: "2024-03-20T14:33:45Z",
message: "Code has expired"
}Meilleures pratiques de l'interface utilisateur#
Pour le mode code numérique
- Afficher le code bien en évidence - Grande police claire
- Afficher le compte à rebours - Mettre à jour toutes les secondes
- Afficher des instructions claires :
- "Ouvrez l'application Deuna"
- "Sélectionnez Payer avec le code"
- "Entrez ce code à 6 chiffres"
- "Confirmer le paiement"
- Afficher l'état d'expiration - Lorsque le code expire après 3 minutes
- Fournir une option de régénération - Bouton "Générer un nouveau code"
Pour le mode code QR
- Afficher le code QR bien en évidence - Centré, évolutif
- Afficher le compte à rebours - Mettre à jour toutes les secondes
- Proposez deux options d'interaction :
- Scanner QR avec l'application Deuna
- Cliquez sur QR pour ouvrir l'application directement
- Afficher des instructions claires
- Afficher l'état d'expiration - Lorsque le QR expire après 15 minutes
- Fournir une option de régénération - Bouton "Générer un nouveau code"
Directives générales
- Gardez le modal/l'écran ouvert - Ne pas rediriger ou fermer jusqu'à ce que le paiement soit confirmé ou expiré
- Désactivez les autres méthodes de paiement - Empêcher de sélectionner une autre méthode en attendant
- Adapté aux mobiles - Assurer la lisibilité sur les petits écrans
- Accessibilité - Inclure un texte alternatif pour QR, un contraste de couleurs clair pour les minuteries
- États de chargement - Afficher le spinner lors de la génération du code/QR
Modèles de mise en œuvre courants#
Modèle de crochet de réaction
import { useEffect, useState } from 'react';
export const useDeunaWalletPayment = (orderToken) => {
const [status, setStatus] = useState('idle'); // idle | pending | success | error | expired
const [expiresAt, setExpiresAt] = useState(null);
useEffect(() => {
if (!orderToken) return;
DeunaSDK.initPaymentWidget({
orderToken,
paymentMethods: [
{
paymentMethod: 'voucher',
processors: ['deuna_wallet'],
},
],
callbacks: {
onPending: (data) => {
setStatus('pending');
setExpiresAt(data.expires_at);
},
onSuccess: (data) => {
setStatus('success');
},
onError: (error) => {
setStatus('error');
},
onExpired: () => {
setStatus('expired');
},
},
});
}, [orderToken]);
const regenerate = () => {
setStatus('idle');
window.location.reload();
};
return { status, expiresAt, regenerate };
};