メインコンテンツへスキップ
このページで

前提条件#

導入前に Deuna (Banco Pichincha) お支払いの際は、次のものが揃っていることを確認してください。

  • 有効 Deuna (Banco Pichincha) DEUNA 管理パネル内
  • を生成しました 注文トークン DEUNA API経由
  • を統合 DEUNA SDK あなたのプロジェクトで
  • をレビューしました 支払いウィジェットのドキュメント あなたのプラットフォームのために
  • ご希望を選択しました 支払いモード 管理パネルの(数値コードまたはQR)

支払いウィジェットの構成#

基本的な実装

支払いウィジェットを初期化します。 deuna_wallet プロセッサ:

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

すべてのオプションを含む完全な例

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

支払いモード#

2 つのモードを理解する

販売アカウントは次のように構成されています これらのモードの 1 つ 管理パネルで:

モード 1: 数値コード (3 分間のウィンドウ)

顧客が見ているもの:

  • 画面に表示される6桁の数字コード
  • 残り時間を表示するカウントダウンタイマー(0:00~3:00)
  • Deuna アプリを開いてコードを入力する手順

お客様の流れ:

  1. 6桁のコードをメモします
  2. Deunaアプリを開く
  3. 「コードで支払う」を選択します
  4. 6桁のコードを入力します
  5. アプリ内で支払いを確認する
  6. DEUNA は最終的な支払い状態を非同期で処理します

構成: 管理パネルの Deuna (Banco Pichincha) プロセッサ設定で設定します。

モード 2: QR コード (15 分間のウィンドウ)

顧客が見ているもの:

  • 画面上の動的な QR コード
  • 残り時間を表示するカウントダウンタイマー(0:00~15:00)
  • 続行するには 2 つのオプションがあります:
    • DeunaアプリのカメラでQRをスキャン
    • QRをクリックしてアプリを直接開きます

お客様の流れ:

  1. オプション A - スキャン:

    • Deuna アプリのカメラを開きます
    • QRコードをスキャンします
    • 支払いページが自動的に開きます
    • アプリ内で支払いを確認する
    • DEUNA は最終的な支払い状態を非同期で処理します
  2. オプション B - クリックします:

    • QRコードまたはボタンをクリックします
    • Deuna アプリを直接開きます
    • 支払い確認画面を表示します
    • 支払いを確認します
    • DEUNA は最終的な支払い状態を非同期で処理します

構成: 管理パネルの Deuna (Banco Pichincha) プロセッサ設定で設定します。

注: モード選択が発生します 初期セットアップ中に 1 回 管理者パネルで。後続のすべての注文では、構成されたモードが使用されます。モードを変更するには、DEUNA サポートにお問い合わせください。

支払い確認の処理#

Deuna (Banco Pichincha) は、個別のマーチャント Webhook ペイロードを定義していません。規格に準拠しています 非同期支払いステータス処理モデル.

ウィジェット コールバックを使用して顧客インターフェイスを更新し、元の注文を取得して、最終的な支払いステータスから履行の決定を行います。結果が未解決のままの場合は、制限された頻度で注文エンドポイントをポーリングします。

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

応答オブジェクト#

成功の応答

ご入金が確認できましたら、 onSuccess コールバックは以下を受け取ります:

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

エラー応答

支払いが失敗した場合、 onError コールバックは以下を受け取ります:

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

保留中の応答

ユーザーの確認を待っているとき、 onPending コールバックは以下を受け取ります:

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
}

期限切れの応答

コード/QRの有効期限が切れると、 onExpired コールバックは以下を受け取ります:

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

UI のベストプラクティス#

数値コードモードの場合

  • コードを目立つように表示する - 大きくて鮮明なフォント
  • カウントダウンタイマーを表示 - 毎秒更新
  • 明確な指示を表示します。
    • 「Deunaアプリを開いてください」
    • 「コードで支払うを選択」
    • 「この6桁のコードを入力してください」
    • 「支払いの確認」
  • 有効期限の状態を表示する - コードの有効期限が 3 分後に切れる場合
  • 再生成オプションを提供する - 「新しいコードを生成」ボタン

QRコードモードの場合

  • QRコードを目立つように表示する - 中央に配置され、スケーラブル
  • カウントダウンタイマーを表示 - 毎秒更新
  • 2 つの対話オプションを提供します。
    • Deuna アプリで QR をスキャン
    • QRをクリックしてアプリを直接開きます
  • 明確な指示を表示する
  • 有効期限の状態を表示する - 15分後にQRの有効期限が切れた場合
  • 再生成オプションを提供する - 「新しいコードを生成」ボタン

一般的なガイドライン

  • モーダル/画面を開いたままにする - 支払いが確認されるか期限が切れるまで、リダイレクトしたり閉じたりしないでください。
  • 他の支払い方法を無効にする - 待機中に別の方法を選択できないようにする
  • モバイル対応 - 小さな画面でも読みやすさを確保
  • アクセシビリティ - QR の代替テキスト、タイマーの明確な色のコントラストを含めます
  • ロード状態 - コード/QR の生成中にスピナーを表示する

一般的な実装パターン#

反応フックパターン

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