Rabbit LINE Pay
タイで1,000万人以上のLINEユーザーから支払いを受け付けます。Rabbit LINE Payは、Rabbitカードの特典と人気のLINEメッセージングプラットフォームを組み合わせたデジタルウォレットです。
概要
ユーザー統計
ユーザー数は概算であり、公開されている情報に基づいています。実際のアクティブユーザー数は異なる場合があります。
Rabbit LINE Payは、LINE(日本のメッセージングの巨人)とBTSグループ(タイのRabbitカードの運営会社)の提携により誕生したデジタル決済サービスです。タイのLINEユーザーは、LINEアプリを通じて支払いを行い、Rabbit Rewardsポイントを獲得できるため、バンコクの公共交通機関利用者や若い専門家の間で特に人気があります。
主な機能:
- ✅ 1,000万人以上のユーザー - タイのLINEユーザーの中で大きなリーチ
- ✅ Rabbit Rewards - お客様はすべての取引でポイントを獲得
- ✅ LINE統合 - メッセージングアプリ内でシームレスな決済
- ✅ BTSエコシステム - バンコクの大量輸送システムとの統合
- ✅ 即時確認 - リアルタイム決済処理
- ✅ 銀行口座不要 - コンビニでトップアップ可能
サポート地域
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Thailand | THB | ฿20.00 | ฿150,000.00 | 2017-11-02 |
認証レベル
| レベル | 1日の上限 | トップアップ方法 | 必要事項 |
|---|---|---|---|
| ベーシック | ฿150,000 | クレジットカード、銀行振込 | 電話番号 |
| 認証済み | ฿150,000 | + コンビニ、Rabbitカード | ID認証 |
仕組み
顧客体験:
- 顧客がチェックアウトで「Rabbit LINE Pay」を選択
- LINEアプリにリダイレクト(デスクトップの場合はLINE web)
- LINE内で取引詳細を確認
- LINEパスワードまたは生体認証で認証
- 決済を確認
- Rabbit Rewardsポイントを獲得
- 加盟店ウェブサイトに戻る
通常の完了時間: 1〜3分
決済フローの例
QRスキャン決済フロー:

デスクトッ プQRコードスキャン方法:
- ❶ Rabbit LINE Payを選択 - 顧客が決済オプションを選択
- ❷ QRコードが生成される - システムが固有の決済QRを作成
- ❸ LINEアプリを開く - 顧客がモバイルデバイスでLINEを起動
- ❹ QRをスキャン - LINEの内蔵QRスキャナーを使用してコードをキャプチャ
- ❺ 決済詳細 - LINEアプリに取引情報が表示される
- ❻ パスコードを入力 - LINE Payパスコードで認証
- ❼ 決済を確認 - タップして取引を承認
- ❽ Rabbitポイントを獲得 - 特典が自動的にクレジット
- ❾ 完了 - 決済成功、加盟店に戻る
ログインフロー - ステップ1:

Webベースの認証(パート1):
- ❶ Rabbit LINE Payを選択 - 顧客がチェックアウトで選択
- ❷ LINEにリダイレクト - LINE Pay認証ページに移動
- ❸ ログインプロンプト - LINEアカウント認証情報を入力
- ❹ メール/電話 - 登録済みのLINEメールまたは電話番号を入力
- ❺ パスワード - LINEアカウントパスワードを入力
- ❻ 2FA認証 - 有効な場合は二要素認証を完了
ログインフロー - ステップ2:

アプリ内承認(パート2):
- ❼ LINEアプリが開く - LINEアプリケーションに自動リダイレクト
- ❽ 決済を確認 - 加盟店名、金額、獲得するRabbitポイント
- ❾ 決済ソースを選択 - リンクされたカードまたはLINE Pay残高を選択
- ❿ 認証 - パスコードまたは生体認証で確認
- ⓫ 決済処理 - 資金が控除され、Rabbit Rewardsがクレジット
- ⓬ 成功 - LINE内で確認、加盟店サイトに戻る
実装
ステップ1: Rabbit LINE Payソースを作成
- cURL
- Node.js
- PHP
- Python
- Ruby
- Go
- Java
- C#
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=rabbit_linepay" \
-d "amount=100000" \
-d "currency=THB"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'rabbit_linepay',
amount: 100000, // THB 1,000.00
currency: 'THB'
});
<?php
$source = OmiseSource::create(array(
'type' => 'rabbit_linepay',
'amount' => 100000,
'currency' => 'THB'
));
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='rabbit_linepay',
amount=100000,
currency='THB'
)
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
source = Omise::Source.create({
type: 'rabbit_linepay',
amount: 100000,
currency: 'THB'
})
source, err := client.Sources().Create(&operations.CreateSource{
Type: "rabbit_linepay",
Amount: 100000,
Currency: "THB",
})
Source source = client.sources().create(new Source.CreateParams()
.type("rabbit_linepay")
.amount(100000L)
.currency("THB"));
var source = await client.Sources.Create(new CreateSourceRequest
{
Type = "rabbit_linepay",
Amount = 100000,
Currency = "THB"
});
レスポンス:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "rabbit_linepay",
"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/rabbit-linepay', async (req, res) => {
try {
const { amount, order_id, customer_email } = req.body;
// 金額を検証
if (amount < 100 || amount > 5000000) {
return res.status(400).json({
error: 'Amount must be between ฿1 and ฿50,000'
});
}
// ソースを作成
const source = await omise.sources.create({
type: 'rabbit_linepay',
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,
customer_email: customer_email
}
});
// Rabbit LINE Payにリダイレクト
res.redirect(charge.authorize_uri);
} catch (error) {
console.error('Rabbit LINE Pay error:', 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?rewards=earned');
} 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 === 'rabbit_linepay') {
const charge = event.data;
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
sendConfirmationEmail(charge.metadata.customer_email);
// Rabbit Rewardsの獲得をログに記録(利用可能な場合)
console.log(`Payment successful. Customer earned Rabbit Rewards.`);
} 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/rabbit-linepay', async (req, res) => {
try {
const { amount, order_id, customer_email, customer_name } = req.body;
// 金額を検証(฿1 - ฿50,000)
if (amount < 100 || amount > 5000000) {
return res.status(400).json({
error: 'Amount must be between ฿1 and ฿50,000'
});
}
// 推定Rabbit Rewardsポイントを計算(例: 金額の1%)
const estimatedPoints = Math.floor(amount / 100);
// ソースを作成
const source = await omise.sources.create({
type: 'rabbit_linepay',
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,
customer_email: customer_email,
customer_name: customer_name,
payment_method: 'rabbit_linepay',
estimated_rewards: estimatedPoints
}
});
// 承認URLを返す
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id,
estimated_rewards: estimatedPoints
});
} catch (error) {
console.error('Rabbit LINE Pay error:', 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') {
const rewards = charge.metadata.estimated_rewards || 0;
res.redirect(`/order-success?order=${charge.metadata.order_id}&rewards=${rewards}`);
} 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 === 'rabbit_linepay') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmation(charge.metadata.customer_email, {
amount: charge.amount,
rewards: charge.metadata.estimated_rewards
});
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
}
}
}
res.sendStatus(200);
});
// ヘルパー関数
async function updateOrderStatus(orderId, status) {
await db.orders.update({ id: orderId }, { status: status });
}
async function sendConfirmation(email, details) {
// 決済確認とRabbit Rewards情報をメールで送信
// 実装はメールサービスに依存
}
app.listen(3000);
返金サポート
Rabbit LINE Payは30日以内の全額返金のみをサポートしています:
// 全額返金のみ(部分返金は不可)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 100000 // 全額である必要があります
});
返金の制限
- 全額返金のみ - 部分返金はサポートされていません
- 30日間の期間 - 返金は30日以内にリクエストする必要があります
- Rabbit Rewards - 獲得されたポイントは返金時に自動的に控除されます
よくある問題とトラブルシューティング
問題: LINEアプリがインストールされていない
原因: 顧客がデバイスにLINEアプリを持っていない
解決策:
function checkLINEApp() {
const userAgent = navigator.userAgent;
const isMobile = /Android|iPhone|iPad|iPod/i.test(userAgent);
if (isMobile) {
return `
<div class="line-check">
<p>この決済方法にはLINEアプリが必要です。</p>
<p>LINEがインストールされていることを確認してください:</p>
<a href="https://line.me/download">LINEをダウンロード</a>
</div>
`;
}
return ''; // デスクトップユーザーはLINE webを使用
}
問題: 残高不足
原因: 顧客のRabbit LINE Pay残高が少なすぎる
解決策:
<div class="payment-instructions">
<h3>決済を完了する前に:</h3>
<ol>
<li>LINEアプリでRabbit LINE Pay残高を確認してください</li>
<li>必要に応じて残高をトップアップ:
<ul>
<li>セブン-イレブン、ファミリーマート(コンビニ)</li>
<li>クレジット/デビットカード</li>
<li>銀行振込</li>
<li>BTS駅でRabbitカードにトップアップ</li>
</ul>
</li>
<li>ここに戻って決済を完了</li>
</ol>
<p><strong>決済金額: ฿{{amount}}</strong></p>
</div>
問題: 1日の上限を超過
原因: 顧客が1日の取引上限に達した
解決策:
function handleLimitExceeded() {
return {
error: 'Daily limit exceeded',
message: 'Rabbit LINE Payの1日の上限に達しました。',
suggestions: [
'明日まで待ってこの取引を完了してください',
'より高い上限のために認証済みアカウントにアップグレード',
'別の決済方法を使用'
],
alternativeMethods: [
'credit_card',
'promptpay',
'truemoney'
]
};
}
問題: 決済期限切れ
原因: 顧客が時間制限内に決済を完了しなかった
解決策:
// 10分の決済タイムアウト
const PAYMENT_TIMEOUT = 10 * 60 * 1000;
setTimeout(() => {
if (!paymentConfirmed) {
showMessage('決済セッションが期限切れになりました。もう一度お試しください。');
enableRetryButton();
}
}, PAYMENT_TIMEOUT);
function enableRetryButton() {
const retryBtn = document.getElementById('retry-payment');
retryBtn.disabled = false;
retryBtn.onclick = () => {
window.location.href = '/checkout';
};
}
問題: Rabbit Rewardsが表示されない
原因: 特典の計算または表示の問題
解決策:
// Rabbit Rewardsを計算して表示
function displayRewardsEstimate(amount) {
// 通常のレート: ฿100ごとに1ポイント
const points = Math.floor(amount / 10000); // satang単位の金額
return `
<div class="rewards-estimate">
<img src="/images/rabbit-icon.svg" alt="Rabbit Rewards" width="24">
<p>約<strong>${points} Rabbit Rewardsポイント</strong>を獲得</p>
<p class="small">ポイントは決済成功後にクレジットされます</p>
</div>
`;
}
ベストプラクティス
1. Rabbit Rewardsの利点を表示
<div class="rabbit-linepay-benefits">
<h3>Rabbit LINE Payで支払う</h3>
<ul class="benefits-list">
<li>✓ すべての購入でRabbit Rewardsポイントを獲得</li>
<li>✓ BTS/MRTの乗車にポイントを使用</li>
<li>✓ LINEアプリで高速決済</li>
<li>✓ LINE認証で安全</li>
</ul>
<p class="rewards-note">
<img src="/images/rabbit-icon.svg" width="20">
<strong>{{points}}ポイントを獲得</strong>この購入で
</p>
</div>