Portafoglio app DEUNA via Widget
In questa pagina
Prerequisiti#
Prima di implementare Portafoglio Deuna App pagamenti, assicurarsi di avere:
- Abilitato Portafoglio Deuna App nel pannello di amministrazione Deuna
- Generato un ordine di token tramite l'API Deuna
- Integrato Deuna SDK nel tuo progetto
- Recensione Pagamento documentazione Widget per la tua piattaforma
- Selezionato il tuo preferito modalità di pagamento (Codice numerico o QR) nel pannello di amministrazione
Configurazione Widget di pagamento#
Attuazione di base
Inizializzare il Widget di pagamento con il deuna_wallet processore:
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
},
},
});Esempio completo con tutte le opzioni
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,
});
},
},
});Modalità di pagamento#
Comprendere le due modalità
Il tuo account di commerciante è configurato con una di queste modalità nel pannello di amministrazione:
Modalità 1: Codice numerico (3-finestra intatta)
Cosa vede il cliente:
- Un codice numerico a 6 cifre visualizzato sullo schermo
- Timer conto alla rovescia che mostra tempo rimanente (0:00-3:00)
- Istruzioni per aprire Deuna App e inserire il codice
Flusso del cliente:
- Note il codice a 6 cifre
- Apre Deuna App
- Seleziona "Paga con codice"
- Inserisci il codice a 6 cifre
- Conferma il pagamento in app
- Pagamento confermato immediatamente tramite webhook
Configurazione: Impostare nel pannello di amministrazione sotto le impostazioni del processore di Deuna App Wallet
Modalità 2: Codice QR (15-Minute Window)
Cosa vede il cliente:
- Un codice QR dinamico sullo schermo
- Timer conto alla rovescia che mostra tempo rimanente (0:00-15:00)
- Due opzioni per procedere:
- Scansione QR con fotocamera Deuna App
- Fare clic su QR per aprire l'app direttamente
Flusso del cliente:
-
Opzione A - Scansione:
- Apre la fotocamera Deuna App
- Scansiona il codice QR
- La pagina di pagamento si apre automaticamente
- Conferma il pagamento in app
- Pagamento confermato tramite webhook
-
Opzione B - Cliccare su:
- Clic QR code o pulsante
- Apre Deuna App direttamente
- Mostra la schermata di conferma del pagamento
- Conferma del pagamento
- Pagamento confermato tramite webhook
Configurazione: Impostare nel pannello di amministrazione sotto le impostazioni del processore di Deuna App Wallet
Nota: Selezione della modalità avviene una volta durante la configurazione iniziale nel pannello di amministrazione. Tutti gli ordini successivi utilizzeranno la modalità configurata. Contatta il supporto Deuna per cambiare le modalità.
Gestione della conferma di pagamento#
Confermazione basata su Webhook (Primaria)
Il Portafoglio Deuna App invia una notifica webhook al tuo backend quando il cliente conferma il pagamento:
// 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 });
});Polling Fallback (Secondo)
Se la consegna webhook è ritardata o non riesce, il sistema sonda i /order endpoint ogni 3 secondi:
// 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();
};Oggetti di risposta#
Risposta di successo
Quando il pagamento è confermato, onSuccess callback riceve:
{
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
}
}Risposta di errore
Quando il pagamento non viene eseguito, onError callback riceve:
{
code: "PAYMENT_FAILED",
message: "Unable to process payment",
order_id: "order_abc123def456",
details: {
reason: "Insufficient funds in Deuna wallet"
}
}Risposta in attesa
Quando si attende la conferma dell'utente, onPending callback riceve:
{
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
}Risposta scaduta
Quando il codice/QR scade, onExpired callback riceve:
{
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"
}Migliori pratiche dell'interfaccia utente#
Per la modalità Codice Numerico
- Visualizzare il codice in modo prominente - Grande, chiaro carattere
- Mostra il timer conto alla rovescia - Aggiornamento ogni secondo
- Visualizzare le istruzioni chiare:
- "Aprire l'App Deuna"
- "Seleziona la paga con il codice"
- "Inserire questo codice a 6 cifre"
- "Conferma pagamento"
- Mostra lo stato di scadenza - Quando il codice scade dopo 3 minuti
- Fornire l'opzione rigenerante - "Generare nuovo codice" pulsante
Per la modalità QR Code
- Visualizzare il codice QR in modo prominente - Centro, scalabile
- Mostra il timer conto alla rovescia - Aggiornamento ogni secondo
- Fornire due opzioni di interazione:
- Scansione QR con Deuna App
- Fare clic su QR per aprire l'app direttamente
- Visualizzare le istruzioni chiare
- Mostra lo stato di scadenza - Quando il QR scade dopo 15 minuti
- Fornire l'opzione rigenerante - "Generare nuovo codice" pulsante
Linee guida generali
- Tenere aperto modal/schermo - Non reindirizzare o chiudere fino a quando il pagamento non è confermato o scaduto
- Disattivare altri metodi di pagamento - Prevenire di selezionare un altro metodo durante l'attesa
- Riattiva mobile - Assicurare la leggibilità su piccoli schermi
- Accessibilità - Includere il testo alt per QR, contrasto di colore chiaro per i timer
- Stati di caricamento - Mostrare il girante mentre genera il codice/QR
Modelli comuni di attuazione#
Modello di gancio reagito
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 };
};