Pular para o conteúdo principal
Nesta página

Pré-requisitos#

Antes de implementar Carteira do aplicativo Deuna pagamentos, certifique-se de ter:

  • Ativado Carteira do aplicativo Deuna no painel de administração Deuna
  • Gerou um token de pedido através da API Deuna
  • Integrado o Deuna SDK no seu projeto
  • Revisou o Documentação do widget de pagamento para sua plataforma
  • Selecionou seu preferido modo de pagamento (Código Numérico ou QR) no Painel de Administração

Configuração do widget de pagamento#

Implementação Básica

Inicialize o widget de pagamento com o deuna_wallet processador:

JavaScript
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
    },
  },
});

Exemplo completo com todas as opções

JavaScript
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,
      });
    },
  },
});

Modos de pagamento#

Compreendendo os dois modos

Sua conta de comerciante está configurada com um desses modos no painel de administração:

Modo 1: Código Numérico (janela de 3 minutos)

O que o cliente vê:

  • Um código numérico de 6 dígitos exibido na tela
  • Temporizador de contagem regressiva mostrando o tempo restante (0:00-3:00)
  • Instruções para abrir o aplicativo Deuna e inserir o código

Fluxo de clientes:

  1. Anota o código de 6 dígitos
  2. Abre o aplicativo Deuna
  3. Seleciona "Pagar com Código"
  4. Insere o código de 6 dígitos
  5. Confirma o pagamento no aplicativo
  6. Pagamento confirmado imediatamente via webhook

Configuração: Definido no Painel de Administração nas configurações do processador Deuna App Wallet

Modo 2: Código QR (janela de 15 minutos)

O que o cliente vê:

  • Um código QR dinâmico na tela
  • Temporizador de contagem regressiva mostrando o tempo restante (0:00-15:00)
  • Duas opções para prosseguir:
    • Digitalize QR com a câmera Deuna App
    • Clique em QR para abrir o aplicativo diretamente

Fluxo de clientes:

  1. Opção A - Digitalizar:

    • Abre a câmera do aplicativo Deuna
    • Digitaliza o código QR
    • A página de pagamento abre automaticamente
    • Confirma o pagamento no aplicativo
    • Pagamento confirmado via webhook
  2. Opção B - Clique:

    • Clica no código QR ou botão
    • Abre o aplicativo Deuna diretamente
    • Mostra tela de confirmação de pagamento
    • Confirma o pagamento
    • Pagamento confirmado via webhook

Configuração: Definido no Painel de Administração nas configurações do processador Deuna App Wallet

Nota: A seleção do modo acontece uma vez durante a configuração inicial no painel de administração. Todos os pedidos subsequentes usarão o modo configurado. Entre em contato com o suporte da Deuna para alterar os modos.

Tratamento da confirmação de pagamento#

Confirmação baseada em webhook (primária)

A Deuna App Wallet envia uma notificação de webhook para o seu backend quando o cliente confirma o pagamento:

JavaScript
// 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 (secundário)

Se a entrega do webhook atrasar ou falhar, o sistema pesquisará o /order ponto final a cada 3 segundos:

JavaScript
// 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();
};

Objetos de resposta#

Resposta de sucesso

Quando o pagamento for confirmado, onSuccess retorno de chamada recebe:

JavaScript
{
  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
  }
}

Resposta de erro

Quando o pagamento falhar, onError retorno de chamada recebe:

JavaScript
{
  code: "PAYMENT_FAILED",
  message: "Unable to process payment",
  order_id: "order_abc123def456",
  details: {
    reason: "Insufficient funds in Deuna wallet"
  }
}

Resposta pendente

Ao aguardar a confirmação do usuário, onPending retorno de chamada recebe:

JavaScript
{
  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
}

Resposta expirada

Quando o código/QR expirar, onExpired retorno de chamada recebe:

JavaScript
{
  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"
}

Práticas recomendadas de interface do usuário#

Para modo de código numérico

  • Exiba o código com destaque - Fonte grande e clara
  • Mostrar contagem regressiva - Atualize a cada segundo
  • Exibir instruções claras:
    • "Abra o aplicativo Deuna"
    • "Selecione Pagar com Código"
    • "Insira este código de 6 dígitos"
    • "Confirmar pagamento"
  • Mostrar estado de expiração - Quando o código expira após 3 minutos
  • Fornece opção de regeneração - Botão "Gerar novo código"

Para modo de código QR

  • Exibir o código QR com destaque - Centrado, escalável
  • Mostrar contagem regressiva - Atualize a cada segundo
  • Forneça duas opções de interação:
    • Digitalize QR com o aplicativo Deuna
    • Clique em QR para abrir o aplicativo diretamente
  • Exibir instruções claras
  • Mostrar estado de expiração - Quando o QR expira após 15 minutos
  • Fornece opção de regeneração - Botão "Gerar novo código"

Diretrizes Gerais

  • Mantenha modal/tela aberta - Não redirecione ou feche até que o pagamento seja confirmado ou expire
  • Desative outros métodos de pagamento - Evite selecionar outro método enquanto espera
  • Responsivo móvel - Garanta a legibilidade em telas pequenas
  • Acessibilidade - Inclui texto alternativo para QR, contraste de cores claro para temporizadores
  • Carregando estados - Mostrar girador ao gerar código/QR

Padrões Comuns de Implementação#

Padrão de gancho de reação

JavaScript
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 };
};