Boost
マレーシアの900万人以上のBoostユーザーから支払いを受け付けます。国内最大の自国製デジタルウォレットで、深い加盟店浸透と強力なローカルブランド認知度を持っています。
概要
Boostは、900万人以上のユーザーと18万以上の加盟店タッチポイントを持つマレーシア最大の自国製デジタルウォレットです。Axiata GroupとRHB Bankの合弁事業として設立されたBoostは、マレーシアで最も広く受け入れられているe-walletとなり、特に若い専門家や都市部の消費者の間で強力です。
主な機能:
- ✅ 900万人以上のユーザー - マレーシアで最も人気のある国内e-wallet
- ✅ 18万以上の加盟店 - マレーシアで最も広い受け入れネットワーク
- ✅ 即時確認 - リアルタイム決済処理
- ✅ QR & アプリ決済 - 複数の決済方法をサポート
- ✅ 報酬プログラム - キャッシュバックとロイヤルティポイント
- ✅ 24時間年中無休 - 休日を含めていつでも動作
サポート地域
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Malaysia | MYR | RM1.00 | RM4,999.00 | 2017-11-02 |
認証レベル
| レベル | 1日の上限 | 月間上限 | 必要事項 |
|---|---|---|---|
| ベーシック(未認証) | RM1,500 | RM3,000 | 電話番号のみ |
| 認証済み | RM30,000 | RM100,000 | IC/パスポート認証 |
仕組み
顧客体験:
- 顧客がチェックアウトで「Boost」を選択
- Boost決済ページにリダイレクト
- Boostアプリを開く(モバイルでのdeep link)
- 取引詳細を確認
- 6桁のPINまたは生体認証で認証
- 決済を確認
- キャッシュバック/報酬を獲得(対象の場合)
- 加盟店ウェブサイトに戻る
通常の完了時間: 1〜2分
決済フローの例
モバイル決済フロー - Boostアプリ:

顧客がすでにBoostアプリにログインしている場合:
- ❶ Boostを選択 - 顧客がチェックアウトでBoostを選択
- ❷ Boostにリダイレクト - deep linkが自動的にBoostアプリを開く
- ❸ 決済を確認 - アプリに取引詳細が表示される
- ❹ 加盟店を確認 - 加盟店名と金額が表示される
- ❺ 認証 - 6桁のPINを入力または生体認証(指紋/Face ID)を使用
- ❻ 完了 - 決済が処理され、キャッシュバック/報酬が獲得され、加盟店に戻る
モバイル決済フロー - サインイン方法:

Boostアプリにログインしていない顧客の代替フロー:
- ❶ Boostを選択 - 顧客がBoost決済を開始
- ❷ 携帯番号を入力 - Boostに登録された電話番号を入力
- ❸ OTP送信 - SMSで6桁の認証コードを受信
- ❹ OTPを入力 - 顧客がOTPを入力して認証
- ❺ 確認 & 確定 - 決済詳細が表示され、PINで認証
- ❻ 決済成功 - 取引完了、報酬がクレジット
デスクトップ決済フロー:

デスクトップブラウザ用のQR codeフロー:
- ❶ 決済を開始 - 顧客が「Boostで支払う」をクリック
- ❷ QRを生成 - システムが固有のBoost QR codeを作成
- ❸ QRを表示 - デスクトップ画面にQR codeが表示される
- ❹ Boostアプリを開く - 顧客がモバイルデバイスでBoostを起動
- ❺ QRをスキャン - アプリ内スキャナーを使用してQR codeをキャプチャ
- ❻ 詳細を確認 - アプリに決済情報が表示される
- ❼ 確認 & 完了 - PIN/生体認証で認証、決 済が処理される
実装
ステップ1: Boostソースを作成
- cURL
- Node.js
- PHP
- Python
- Ruby
- Go
- Java
- C#
curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=boost" \
-d "amount=10000" \
-d "currency=MYR"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'boost',
amount: 10000, // MYR 100.00
currency: 'MYR'
});
<?php
$source = OmiseSource::create(array(
'type' => 'boost',
'amount' => 10000,
'currency' => 'MYR'
));
?>
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
source = omise.Source.create(
type='boost',
amount=10000,
currency='MYR'
)
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
source = Omise::Source.create({
type: 'boost',
amount: 10000,
currency: 'MYR'
})
source, err := client.Sources().Create(&operations.CreateSource{
Type: "boost",
Amount: 10000,
Currency: "MYR",
})
Source source = client.sources().create(new Source.CreateParams()
.type("boost")
.amount(10000L)
.currency("MYR"));
var source = await client.Sources.Create(new CreateSourceRequest
{
Type = "boost",
Amount = 10000,
Currency = "MYR"
});
レスポンス:
{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "boost",
"flow": "redirect",
"amount": 10000,
"currency": "MYR"
}
ステップ2: 課金を作成
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10000" \
-d "currency=MYR" \
-d "source=src_test_5rt6s9vah5lkvi1rh9c" \
-d "return_uri=https://yourdomain.com/payment/callback"
ステップ3: 顧客をリダイレクト
app.post('/checkout/boost', async (req, res) => {
try {
const { amount, order_id, customer_email } = req.body;
// 金額を検証(RM1 - RM10,000)
if (amount < 100 || amount > 1000000) {
return res.status(400).json({
error: 'Amount must be between RM1 and RM10,000'
});
}
// ソースを作成
const source = await omise.sources.create({
type: 'boost',
amount: amount,
currency: 'MYR'
});
// 課金を作成
const charge = await omise.charges.create({
amount: amount,
currency: 'MYR',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_email: customer_email
}
});
// Boostにリダイレクト
res.redirect(charge.authorize_uri);
} catch (error) {
console.error('Boost 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');
} 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 === 'boost') {
const charge = event.data;
if (charge.status === 'successful') {
processOrder(charge.metadata.order_id);
sendConfirmationEmail(charge.metadata.customer_email);
} 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/boost', async (req, res) => {
try {
const { amount, order_id, customer_email, customer_phone } = req.body;
// 金額を検証(RM1 - RM10,000)
if (amount < 100 || amount > 1000000) {
return res.status(400).json({
error: 'Amount must be between RM1 and RM10,000'
});
}
// 推定キャッシュバックを計算(加盟店が提供する場合)
const estimatedCashback = calculateCashback(amount);
// ソースを作成
const source = await omise.sources.create({
type: 'boost',
amount: amount,
currency: 'MYR'
});
// 課金を作成
const charge = await omise.charges.create({
amount: amount,
currency: 'MYR',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_email: customer_email,
customer_phone: customer_phone,
payment_method: 'boost',
estimated_cashback: estimatedCashback
}
});
// 承認URLを返す
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id,
estimated_cashback: estimatedCashback
});
} catch (error) {
console.error('Boost error:', error);
res.status(500).json({ error: error.message });
}
});
// キャッシュバックを計算(実装例)
function calculateCashback(amount) {
// 例: 最大RM10まで1%のキャッシュバック
const cashbackRate = 0.01;
const cashback = amount * cashbackRate;
return Math.min(cashback, 1000); // 最大RM10のキャッシュバック
}
// コールバックハンドラー
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 === 'boost') {
if (charge.status === 'successful') {
updateOrderStatus(charge.metadata.order_id, 'paid');
sendConfirmation(charge.metadata.customer_email);
// 決済 成功をログに記録
console.log(`Boost payment successful: ${charge.id}`);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
console.log(`Boost payment failed: ${charge.id}`);
}
}
}
res.sendStatus(200);
});
// ヘルパー関数
async function updateOrderStatus(orderId, status) {
await db.orders.update({ id: orderId }, { status: status });
}
async function sendConfirmation(email) {
// メール確認を送信
}
app.listen(3000);
返金サポート
Boostは30日以内の全額返金のみをサポートしています:
// 全額返金のみ(部分返金は不可)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 10000 // 全額である必要があります
});
返金の制限
- 全額返金のみ - 部分返金はサポートされていません
- 30日間の期間 - 返金は30日以内に開始する必要があります
- キャッシュバックの取り消し - 獲得されたキャッシュバックは取り消されます
よくある問題とトラブルシューティング
問題: Boostアプリがインストールされていない
原因: 顧客がBoostアプリをインストールしていない
解決策:
function detectBoostApp() {
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
if (isMobile) {
return `
<div class="boost-app-check">
<p>決済にはBoostアプリが必要です。</p>
<div class="download-links">
<a href="https://play.google.com/store/apps/details?id=com.myboost.boostapp">
<img src="/images/google-play-badge.png" alt="Get it on Google Play">
</a>
<a href="https://apps.apple.com/app/boost-pay/id1097459653">
<img src="/images/app-store-badge.png" alt="Download on App Store">
</a>
</div>
</div>
`;
}
}
問題: 残高不足
原因: 顧客のBoostウォレット残高が少なすぎる
解決策:
<div class="balance-instructions">
<h3>Boost残高不足</h3>
<p>Boostウォレット残高がこの取引には少なすぎます。</p>
<h4>トップアップ方法:</h4>
<ul>
<li>🏦 <strong>オンラインバンキング</strong> - 銀行口座をリンク</li>
<li>💳 <strong>デビット/クレジットカード</strong> - 即座にトップアップ</li>
<li>🏪 <strong>セブン-イレブン</strong> - カウンターで現金トップアップ</li>
<li>🏧 <strong>Maybank ATM</strong> - 「Boost Top Up」を選択</li>
<li>👥 <strong>Boost転送</strong> - 友達から受け取る</li>
</ul>
<p>トップアップ後、ここに戻って決済を完了してください。</p>
</div>
問題: 1日の上限を超過
原因: 顧客が1日の取引上限に達した
解決策:
function handleLimitExceeded(verificationLevel) {
if (verificationLevel === 'basic') {
return {
error: 'Daily limit exceeded',
message: '未認証アカウント には1日RM1,500の上限があります。',
solution: '1日RM30,000に上限を増やすためにアカウントを認証してください',
instructions: [
'Boostアプリを開く',
'プロフィール > アカウントを認証に移動',
'IC/パスポート認証を提出',
'承認を待つ(通常1〜2時間)'
]
};
} else {
return {
error: 'Daily limit exceeded',
message: '1日RM30,000の上限に達しました。',
solution: '明日再試行するか、別の決済方法を使用してください'
};
}
}
問題: アカウント認証保留中
原因: 顧客が認証を開始したがまだ承認されていない
解決策:
function showVerificationPending() {
return `
<div class="verification-pending">
<h3>アカウント認証保留中</h3>
<p>Boostアカウント認証が進行中です。</p>
<p>認証は通常、営業時間中に1〜2時間かかります。</p>
<p>その間、以下ができます:</p>
<ul>
<li>現在の上限を使用(1日RM1,500)</li>
<li>別の決済方法を選択</li>
<li>購入を小さな取引に分割</li>
</ul>
</div>
`;
}
問題: 決済タイムアウト
原因: 顧客が時間制限内に決済を完了しなかった
解決策:
// 10分の決済期間
const PAYMENT_TIMEOUT = 10 * 60 * 1000;
setTimeout(() => {
if (!paymentConfirmed) {
showTimeoutMessage();
allowRetry();
}
}, PAYMENT_TIMEOUT);
function allowRetry() {
document.getElementById('retry-button').onclick = () => {
// 新しい決済を作成
window.location.href = '/checkout';
};
}