Alipay+
単一のAlipay+統合により、アジア太平洋地域で13億人以上の登録アカウントを持つ12以上のパートナーウォレットからの支払いを受け付けます。
概要
Alipay+は、アジア太平洋地域の複数の電子ウォレットを接続するAnt Groupのクロスボーダーデジタル決済およびマーケティングソリューションです。1つの統合で、GCash(フィリピン)、KakaoPay(韓国) 、Touch 'n Go eWallet(マレーシア)、その他多くの地域ウォレットからの支払いを受け付けることができます。
主な機能:
- ✅ 大規模なリーチ - 合計13億人以上の登録アカウントを持つ12以上のパートナーウォレット*
- ✅ 単一統合 - 複数のウォレット用の1つのAPI
- ✅ クロスボーダー - 観光客や国際顧客からの支払いを受け付け
- ✅ 高速確認 - ほぼリアルタイムの支払い検証(通常数秒以内)
- ✅ マルチ通貨 - 17以上の通貨をサポート
- ✅ マーケティングツール - プロモーションおよびロイヤルティ機能
地域別サポートウォレット
Alipay+は、以下のデジタルウォレットに接続します:
タイ:
- Alipay CN
- Alipay HK
- KakaoPay
- GCash
- TrueMoney
シンガポール:
- Alipay CN
- Alipay HK
- KakaoPay
- Touch 'n Go
サポートされている地域
| 地域 | 通貨 | 最小金額 | 最大金額 | APIバージョン |
|---|---|---|---|---|
| タイ | THB | ฿20.00 | ฿150,000.00 | 2017-11-02 |
| シンガポール | SGD | $1.00 | $20,000.00 | 2017-11-02 |
仕組み
支払いフロー:
- 顧客がチェックアウト時にウォレットを選択
- マーチャントがOmiseでAlipay+ソースを作成
- 顧客にQRコードが表示されるか、ウォレットにリダイレクト
- 顧客がQRをスキャンまたはウォレットアプリを開く
- 顧客がウォレットで支払いを確認
- Alipay+ネットワークを通じて支払いが処理
- マーチャントが即座に確認を受け取る
通常の完了時間: 1-2分
実装
ステップ1: Alipay+ソースの作成
- cURL
- Node.js
- PHP
- Python
- Ruby
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=alipay_plus" \
-d "amount=50000" \
-d "currency=THB"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'alipay_plus',
amount: 50000, // ฿500.00
currency: 'THB'
});
console.log('Alipay+ source:', source.id);
console.log('QR code:', source.scannable_code.image.download_uri);
<?php
$source = OmiseSource::create(array(
'type' => 'alipay_plus',
'amount' => 50000,
'currency' => 'THB'
));
echo "QR Code: " . $source['scannable_code']['image']['download_uri'];
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='alipay_plus',
amount=50000,
currency='THB'
)
print(f"QR Code: {source.scannable_code['image']['download_uri']}")
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
source = Omise::Source.create({
type: 'alipay_plus',
amount: 50000,
currency: 'THB'
})
puts "QR Code: #{source.scannable_code.image.download_uri}"
レスポンス:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "alipay_plus",
"flow": "redirect",
"amount": 50000,
"currency": "THB",
"scannable_code": {
"type": "qr",
"image": {
"download_uri": "https://api.omise.co/...",
"object": "document"
}
}
}
ステップ2: QRコード表示またはリダイレクト
オプションA: QRコード(店舗内/デスクトップ)
app.post('/checkout/alipay-plus', async (req, res) => {
try {
const { amount, currency } = req.body;
// ソースを作成
const source = await omise.sources.create({
type: 'alipay_plus',
amount: amount,
currency: currency
});
// 課金を作成
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`
});
// QRコードを表示
res.render('payment-qr', {
qr_code_url: source.scannable_code.image.download_uri,
charge_id: charge.id
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
QRコード表示テンプレート:
<div class="alipay-plus-payment">
<h2>Alipay+でスキャンして支払う</h2>
<img src="{{ qr_code_url }}" alt="Alipay+ QR Code" class="qr-code">
<div class="supported-wallets">
<p>以下のウォレットでスキャンできます:</p>
<div class="wallet-logos">
<img src="/icons/gcash.png" alt="GCash">
<img src="/icons/kakaopay.png" alt="KakaoPay">
<img src="/icons/tng.png" alt="Touch 'n Go">
<img src="/icons/truemoney.png" alt="TrueMoney">
<img src="/icons/alipay-hk.png" alt="AlipayHK">
</div>
</div>
<div class="instructions">
<ol>
<li>ウォレットアプリを開く</li>
<li>「スキャン」または「支払い」をタップ</li>
<li>上記のQRコードをスキャン</li>
<li>支払いを確認</li>
</ol>
</div>
<div id="payment-status">
<p>支払い待機中...</p>
<div class="spinner"></div>
</div>
</div>
<script>
// 支払いステータスをポーリング
const chargeId = '{{ charge_id }}';
const pollInterval = setInterval(async () => {
const response = await fetch(`/api/charges/${chargeId}/status`);
const data = await response.json();
if (data.status === 'successful') {
clearInterval(pollInterval);
window.location = '/payment-success';
} else if (data.status === 'failed') {
clearInterval(pollInterval);
window.location = '/payment-failed';
}
}, 3000); // 3秒ごとにチェック
// 10分後にタイムアウト
setTimeout(() => {
clearInterval(pollInterval);
document.getElementById('payment-status').innerHTML =
'<p>支払いタイムアウト。もう一度お試しください。</p>';
}, 600000);
</script>
オプションB: リダイレクト(モバイル)
app.post('/checkout/alipay-plus-mobile', async (req, res) => {
try {
const { amount, currency } = req.body;
const source = await omise.sources.create({
type: 'alipay_plus',
amount: amount,
currency: currency
});
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`
});
// Alipay+ページにリダイレクト
res.redirect(charge.authorize_uri);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
ステップ3: 支払いコールバックの処理
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 fulfillOrder(charge.metadata.order_id);
res.redirect('/payment-success');
} else if (charge.status === 'failed') {
res.redirect('/payment-failed');
} else {
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});
ステップ4: Webhookの処理
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.source.type === 'alipay_plus') {
if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
await sendConfirmation(charge.metadata.customer_email);
}
}
}
res.sendStatus(200);
});
完全な実装例
const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});
const app = express();
app.use(express.json());
// 通貨設定
const SUPPORTED_CURRENCIES = ['THB', 'MYR', 'SGD', 'PHP', 'KRW', 'HKD'];
const CURRENCY_LIMITS = {
THB: { min: 2000, max: 1000000 },
MYR: { min: 500, max: 500000 },
SGD: { min: 100, max: 100000 },
PHP: { min: 5000, max: 1000000 },
KRW: { min: 100000, max: 10000000 },
HKD: { min: 100, max: 100000 }
};
// Alipay+支払いを作成
app.post('/checkout/alipay-plus', async (req, res) => {
try {
const { amount, currency, order_id, customer_email } = req.body;
// 通貨を検証
if (!SUPPORTED_CURRENCIES.includes(currency)) {
return res.status(400).json({
error: `通貨${currency}はAlipay+でサポートされていません`
});
}
// 金額を検証
const limits = CURRENCY_LIMITS[currency];
if (amount < limits.min || amount > limits.max) {
return res.status(400).json({
error: `金額は${limits.min}から${limits.max} ${currency}の間である必要があります`
});
}
// ソースを作成
const source = await omise.sources.create({
type: 'alipay_plus',
amount: amount,
currency: currency
});
// 課金を作成
const charge = await omise.charges.create({
amount: amount,
currency: currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_email: customer_email,
payment_method: 'alipay_plus'
}
});
// QRコードと認証URIを返す
res.json({
charge_id: charge.id,
qr_code_url: source.scannable_code.image.download_uri,
authorize_uri: charge.authorize_uri,
expires_at: new Date(Date.now() + 10 * 60 * 1000).toISOString()
});
} catch (error) {
console.error('Alipay+ error:', error);
res.status(500).json({ error: error.message });
}
});
// 課金ステータスを 確認(ポーリング用)
app.get('/api/charges/:chargeId/status', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.params.chargeId);
res.json({
status: charge.status,
paid: charge.paid,
failure_message: charge.failure_message
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 支払いコールバック
app.get('/payment/callback', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.query.charge_id);
if (charge.status === 'successful') {
res.redirect(`/order-confirmation?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?reason=${charge.failure_message}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});
// Webhookハンドラー
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;
if (event.key === 'charge.complete' && event.data.source.type === 'alipay_plus') {
const charge = event.data;
if (charge.status === 'successful') {
await fulfillOrder(charge.metadata.order_id);
await sendReceipt(charge.metadata.customer_email, charge);
}
}
res.sendStatus(200);
});
app.listen(3000);
返金サポート
Alipay+は180日以内の全額および一部返金をサポートしています:
// 全額返金
const fullRefund = await omise.charges.refund('chrg_test_...', {
amount: 50000
});
// 一部返金
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 25000 // 半額返金
});
console.log('Refund status:', fullRefund.status);
返金処理時間
返金はパートナーウォレットに応じて、3〜7営業日以内に顧客の元 のウォレットに処理されます。
返金ポリシー
返金期間とポリシーは変更される場合があります。Omise APIドキュメントまたはマーチャントダッシュボードで常に現在の返金機能を確認してください。
よくある問題とトラブルシューティング
問題: QRコードがスキャンできない
原因: 顧客が非互換のウォレットアプリを使用
解決策:
// サポートされているウォレットを目立つように表示
const supportedWallets = [
'GCash', 'KakaoPay', 'Touch \'n Go',
'TrueMoney', 'AlipayHK', 'Rabbit LINE Pay'
];
// メッセージを表示
showMessage(`以下でスキャンしてください: ${supportedWallets.join(', ')}`);