メインコンテンツへスキップ

SCB Mobile Banking (SCB Easy)

タイ最古で3番目に大きな銀行であるSiam Commercial BankのSCB Easyモバイルアプリ経由で、1,400万人以上のアクティブユーザーから即時決済を受け付けます。

決済フロー

Mobile Banking Payment Flow

モバイルバンキング決済プロセスのステップバイステップ:

❶ 銀行を選択 - 顧客がマーチャントのチェックアウトで銀行を選択

❷ 銀行にリダイレクト - システムが銀行の決済承認ページにリダイレクト

❸ バンキングアプリを開く - ディープリンクが銀行のモバイルアプリを自動的に起動

  • iOS: Universal Links経由で開く
  • Android: App Links経由で開く
  • 顧客に「[銀行]アプリで開く」プロンプトが表示される

❹ 認証 - 顧客がバンキングアプリにログイン(まだログインしていない場合)

  • PINの入力(6桁)
  • 指紋スキャン
  • Face ID認識

❺ 決済を確認 - アプリに取引詳細が表示される:

  • マーチャント名
  • 決済金額
  • 注文参照
  • 引き落とし口座

❻ 決済を承認 - 顧客が取引を確認

  • 銀行が要求する場合は追加のPIN/OTPを入力
  • 「決済を確認」ボタンをタップ

❼ 決済処理 - 銀行が即座に資金を転送

❽ 確認 - アプリに成功画面が表示される

  • 取引参照番号
  • ダウンロード可能な領収書

❾ マーチャントに戻る - 顧客がマーチャントのウェブサイトにリダイレクトされる

  • 自動リダイレクトまたは「マーチャントに戻る」ボタン
  • 注文確認ページが表示される

一般的な完了時間: 30〜90秒

概要

SCB Easyは、タイの主要金融機関の1つであるSiam Commercial Bank(SCB)のモバイルバンキングアプリです。顧客は、PINまたは生体認証を使用してモバイルアプリから直接SCB銀行口座から安全に決済できます。

主な機能:

  • 迅速な確認 - ほぼリアルタイムの決済検証(通常数秒以内)
  • 1,400万人以上のユーザー - タイで大規模な顧客基盤
  • 高額制限 - 1取引あたり最大฿150,000
  • 信頼できる銀行 - タイ初の銀行(1906年設立)
  • 24時間365日利用可能 - いつでも利用可能
  • 安全な認証 - PIN、指紋、またはFace ID

対応地域

地域通貨最小金額最大金額1日の制限
タイTHB฿20.00฿150,000銀行により異なる*

*1日の制限は顧客の銀行口座設定に基づいて異なり、Omiseでは指定されていません

仕組み

顧客体験:

  1. 顧客がチェックアウトで「SCB Easy」を選択
  2. SCB決済承認ページにリダイレクト
  3. ディープリンク経由でSCB Easyアプリを開く
  4. 取引詳細を確認
  5. PIN、指紋、またはFace IDで認証
  6. 決済を確認
  7. マーチャントのウェブサイトに戻る

一般的な完了時間: 1〜3分

実装

ステップ1: SCBソースを作成

curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=mobile_banking_scb" \
-d "amount=100000" \
-d "currency=THB"

レスポンス:

{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "mobile_banking_scb",
"flow": "redirect",
"amount": 100000,
"currency": "THB"
}

ステップ2: チャージを作成

curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=100000" \
-d "currency=THB" \
-d "source=src_test_5rt6s9vah5lkvi1rh9c" \
-d "return_uri=https://yourdomain.com/payment/callback"

ステップ3: 顧客をリダイレクト

app.post('/checkout/scb', async (req, res) => {
try {
const { amount, order_id } = req.body;

// 金額制限を検証
if (amount < 2000 || amount > 200000000) {
return res.status(400).json({
error: '金額は฿20から฿2,000,000の間である必要があります'
});
}

// ソースを作成
const source = await omise.sources.create({
type: 'mobile_banking_scb',
amount: amount,
currency: 'THB'
});

// チャージを作成
const charge = await omise.charges.create({
amount: amount,
currency: 'THB',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id
}
});

// SCB Easyにリダイレクト
res.redirect(charge.authorize_uri);

} catch (error) {
console.error('SCB Easyエラー:', error);
res.status(500).json({ error: error.message });
}
});

ステップ4: 戻りを処理

app.get('/payment/callback', async (req, res) => {
try {
const chargeId = req.query.charge_id;
const charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful') {
// 決済成功
await processOrder(charge.metadata.order_id);
res.redirect('/payment-success');
} else if (charge.status === 'failed') {
// 決済失敗
res.redirect('/payment-failed?reason=' + charge.failure_message);
} else {
// まだ保留中
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});

ステップ5: Webhookを処理

app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete' && event.data.source.type === 'mobile_banking_scb') {
const charge = event.data;

if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
} else if (charge.status === 'failed') {
handleFailedPayment(charge.metadata.order_id);
}
}

res.sendStatus(200);
});

完全な実装例

// Express.jsサーバー
const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

const app = express();
app.use(express.json());

// チェックアウトページ
app.post('/checkout/scb', async (req, res) => {
try {
const { amount, order_id } = req.body;

// 金額を検証
if (amount < 2000 || amount > 200000000) {
return res.status(400).json({
error: '金額は฿20から฿2,000,000の間である必要があります'
});
}

// ソースを作成
const source = await omise.sources.create({
type: 'mobile_banking_scb',
amount: amount,
currency: 'THB'
});

// チャージを作成
const charge = await omise.charges.create({
amount: amount,
currency: 'THB',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
payment_method: 'scb_easy'
}
});

// 承認URLを返す
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});

} catch (error) {
console.error('SCB Easyエラー:', error);
res.status(500).json({ error: error.message });
}
});

// コールバックハンドラー
app.get('/payment/callback', async (req, res) => {
try {
const chargeId = req.query.charge_id;
const charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful') {
res.redirect(`/order-success?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?charge=${chargeId}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});

// Webhookハンドラー
app.post('/webhooks/omise', (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

if (charge.source.type === 'mobile_banking_scb') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmationEmail(charge.metadata.customer_email);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
}
}
}

res.sendStatus(200);
});

app.listen(3000);

返金サポート

SCB Easyは180日以内の全額返金のみをサポートしています:

// 全額返金のみ
const refund = await omise.charges.refund('chrg_test_...', {
amount: 100000 // 全額である必要があります
});
一部返金不可

SCB Easyは一部返金をサポートしていません。180日以内の全額返金のみが許可されています。

よくある問題とトラブルシューティング

問題: 顧客がSCB Easyアプリを持っていない

原因: 顧客がSCBを選択したがアプリがインストールされていない

解決策:

  • 明確な手順を表示
  • アプリダウンロードリンクを提供
  • 代替決済方法を提供
function isMobile() {
return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
}

if (!isMobile()) {
alert('SCB Easyにはモバイルアプリが必要です。モバイルデバイスを使用するか、別の決済方法を選択してください。');
}

問題: 決済が期限切れになる

原因: 顧客が制限時間内(15分)に決済を完了しなかった

解決策:

// カウントダウンタイマーを表示
const EXPIRY_TIME = 15 * 60 * 1000;

setTimeout(() => {
if (!paymentConfirmed) {
showExpiryMessage();
allowRetry();
}
}, EXPIRY_TIME);

問題: 1日の制限を超過

エラー: 銀行によって取引が拒否される

解決策:

  • 顧客がSCB Easyアプリで1日の制限を調整できます
  • 複数の日に決済を分割
  • 代替決済方法を使用

問題: 顧客がアプリを閉じた

原因: return_uriが呼び出されない

解決策:

  • Webhook処理を実装(より信頼性が高い)
  • 注文ステータス確認ページを提供
  • メール/SMS確認を送信

ベストプラクティス

1. 明確な手順を表示

<div class="scb-instructions">
<h3>SCB Easyで支払う</h3>
<ol>
<li>SCB Easyアプリがインストールされていることを確認してください</li>
<li>アプリを開くためにリダイレクトされます</li>
<li>PIN、指紋、またはFace IDで認証</li>
<li>決済を確認してください</li>
</ol>
<p><strong>決済は15分以内に完了する必要があります</strong></p>
<a href="https://www.scb.co.th/en/personal-banking/digital-banking/scb-easy.html">
SCB Easyをダウンロード
</a>
</div>

2. ディープリンクを処理

function openSCBApp(authorizeUri) {
// モバイルアプリを開こうとする
window.location = authorizeUri;

// アプリがインストールされていない場合のフォールバック
setTimeout(() => {
if (document.hidden) {
// アプリが正常に開かれた
return;
}
// アプリインストール手順を表示
showInstallAppMessage();
}, 2000);
}

3. タイムアウトを設定

// 15分の決済ウィンドウ
const PAYMENT_TIMEOUT = 15 * 60 * 1000;

setTimeout(() => {
if (!paymentConfirmed) {
showTimeoutMessage();
allowRetry();
}
}, PAYMENT_TIMEOUT);

4. Webhookを使用

// Webhookはコールバックよりも信頼性が高い
app.post('/webhooks/omise', handleWebhook);
app.get('/payment/callback', handleCallback);

5. 金額を検証

function validateSCBAmount(amount) {
const MIN = 2000; // ฿20.00
const MAX = 200000000; // ฿2,000,000.00

if (amount < MIN) {
return `最小金額は฿${MIN / 100}です`;
}

if (amount > MAX) {
return `最大金額は฿${MAX / 100}です`;
}

return null; // 有効
}

FAQ

SCB Easyとは何ですか?

SCB Easyは、タイのSiam Commercial Bankのモバイルバンキングアプリで、1,400万人以上のユーザーがいます。顧客はPINまたは生体認証を使用してSCB銀行口座から直接支払うことができます。

顧客はSCB口座が必要ですか?

はい、顧客はアクティブなSCB銀行口座とSCB Easyアプリがインストールされている必要があります。アプリはiOSとAndroidで無料です。

取引制限は何ですか?
  • 1取引あたり: ฿20から฿2,000,000
  • 1日の制限: 最大฿5,000,000(顧客設定により異なる)

顧客はSCB Easyアプリで1日の制限を調整できます。

決済にはどのくらい時間がかかりますか?

SCB Easyの決済は通常1〜2営業日以内に行われます。具体的な決済スケジュールについては、Omiseダッシュボードをご確認ください。

SCB Easyの決済を返金できますか?

はい、ただし全額返金のみが180日以内にサポートされています。一部返金は利用できません。

決済が期限切れになったらどうなりますか?

決済は15分後に期限切れになります。顧客が新しいチャージで再試行できるようにします。残り時間を表示するカウントダウンタイマーを表示します。

SCB Easyは24時間365日利用できますか?

はい、SCB Easyは週末や休日を含めて24時間365日利用できます。ただし、決済は営業日のスケジュールに従います。

テスト

テストモード

SCB Mobile BankingはテストAPIキーを使用してテストできます。テストモードでは:

テスト認証情報:

  • テストAPIキーを使用(skey_test_xxx)
  • 通貨: THB(タイバーツ)
  • テストに実際のSCB口座は不要

テストフロー:

  1. テストAPIキーでソースとチャージを作成
  2. 顧客をテストauthorize_uriにリダイレクト
  3. テストページがSCBモバイルバンキング承認をシミュレート
  4. Omiseダッシュボードアクションを使用してチャージを成功/失敗としてマーク
  5. WebhookとReturn_uri処理を検証

テスト実装:

// SCB Mobile Bankingをテスト
const source = await omise.sources.create({
type: 'mobile_banking_scb',
amount: 50000, // ฿500.00
currency: 'THB'
});

const charge = await omise.charges.create({
amount: 50000,
currency: 'THB',
source: source.id,
return_uri: 'https://example.com/callback'
});

console.log('テスト承認URL:', charge.authorize_uri);

テストシナリオ:

  • 決済成功: リダイレクトフローと注文処理を完了
  • 決済失敗: エラー処理をテスト
  • 金額制限: ฿20の最小値と最大値をテスト
  • モバイルフロー: SCB Easyアプリへのディープリンクをテスト
  • タイムアウト: 放棄された決済シナリオをテスト
  • Return URI: 決済後の適切なリダイレクトを検証
  • Webhook配信: すべてのWebhook通知を検証

重要な注意事項:

  • テストモードは実際のSCBサーバーに接続しません
  • ダッシュボードを使用して決済ステータスの変更をシミュレート
  • モバイルアプリのディープリンクをテスト
  • すべてのチャージステータスのWebhook処理を検証
  • 成功と失敗の両方の決済フローをテスト

包括的なテストガイドラインについては、テストドキュメントを参照してください。

関連リソース

次のステップ

  1. SCBソースを作成
  2. リダイレクトフローを実装
  3. Webhook処理を設定
  4. 決済フローをテスト
  5. 本番環境に移行