Skip to main content

Boost

Accept payments from 9+ million Boost users in Malaysia, the country's leading homegrown digital wallet with deep merchant penetration and strong local brand recognition.

Overview​

Boost is Malaysia's largest homegrown digital wallet with over 9 million users and 180,000+ merchant touchpoints. Founded as a joint venture between Axiata Group and RHB Bank, Boost has become the most widely accepted e-wallet in Malaysia, particularly strong among young professionals and urban consumers.

Key Features:

  • ✅ 9+ million users - Malaysia's most popular domestic e-wallet
  • ✅ 180,000+ merchants - Widest acceptance network in Malaysia
  • ✅ Instant confirmation - Real-time payment processing
  • ✅ QR & App payments - Multiple payment methods supported
  • ✅ Rewards program - Cashback and loyalty points
  • ✅ 24/7 availability - Works anytime including holidays

Supported Regions​

RegionCurrencyMin AmountMax AmountDaily Limit
MalaysiaMYRRM1.00RM10,000RM30,000*

*Daily limits may vary based on customer's verification level

Verification Levels​

LevelDaily LimitMonthly LimitRequirements
Basic (Unverified)RM1,500RM3,000Phone number only
VerifiedRM30,000RM100,000IC/Passport verification

How It Works​

Customer Experience:

  1. Customer selects "Boost" at checkout
  2. Redirected to Boost payment page
  3. Opens Boost app (deep link on mobile)
  4. Reviews transaction details
  5. Authenticates with 6-digit PIN or biometric
  6. Confirms payment
  7. Earns cashback/rewards (if eligible)
  8. Returns to merchant website

Typical completion time: 1-2 minutes

Payment Flow Examples​

Mobile Payment Flow - Boost App:

Mobile Payment Flow - Boost App

When customer is already logged into Boost app:

  • âķ Select Boost - Customer chooses Boost at checkout
  • ❷ Redirect to Boost - Deep link opens Boost app automatically
  • âļ Review payment - Transaction details displayed in app
  • âđ Verify merchant - Merchant name and amount shown
  • ❚ Authenticate - Enter 6-digit PIN or use biometric (fingerprint/Face ID)
  • âŧ Complete - Payment processed, cashback/rewards earned, return to merchant

Mobile Payment Flow - Sign In Method:

Mobile Payment Flow - Sign In Method

Alternative flow for customers not logged into Boost app:

  • âķ Select Boost - Customer initiates Boost payment
  • ❷ Enter mobile number - Input Boost-registered phone number
  • âļ OTP sent - Receive 6-digit verification code via SMS
  • âđ Enter OTP - Customer enters OTP to authenticate
  • ❚ Review & confirm - Payment details shown, authenticate with PIN
  • âŧ Payment success - Transaction complete, rewards credited

Desktop Payment Flow:

Desktop Payment Flow

QR code flow for desktop browsers:

  • âķ Initiate payment - Customer clicks "Pay with Boost"
  • ❷ Generate QR - System creates unique Boost QR code
  • âļ Display QR - QR code shown on desktop screen
  • âđ Open Boost app - Customer launches Boost on mobile device
  • ❚ Scan QR - Use in-app scanner to capture QR code
  • âŧ Review details - Payment information displayed in app
  • ❞ Confirm & complete - Authenticate with PIN/biometric, payment processed

Implementation​

Step 1: Create Boost Source​

curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=boost" \
-d "amount=10000" \
-d "currency=MYR"

Response:

{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "boost",
"flow": "redirect",
"amount": 10000,
"currency": "MYR"
}

Step 2: Create Charge​

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"

Step 3: Redirect Customer​

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

// Validate amount (RM1 - RM10,000)
if (amount < 100 || amount > 1000000) {
return res.status(400).json({
error: 'Amount must be between RM1 and RM10,000'
});
}

// Create source
const source = await omise.sources.create({
type: 'boost',
amount: amount,
currency: 'MYR'
});

// Create charge
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
}
});

// Redirect to Boost
res.redirect(charge.authorize_uri);

} catch (error) {
console.error('Boost error:', error);
res.status(500).json({ error: error.message });
}
});

Step 4: Handle Return​

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

Step 5: Handle 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);
});

Complete Implementation Example​

// Express.js server
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;

// Validate amount (RM1 - RM10,000)
if (amount < 100 || amount > 1000000) {
return res.status(400).json({
error: 'Amount must be between RM1 and RM10,000'
});
}

// Calculate estimated cashback (if merchant offers it)
const estimatedCashback = calculateCashback(amount);

// Create source
const source = await omise.sources.create({
type: 'boost',
amount: amount,
currency: 'MYR'
});

// Create charge
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
}
});

// Return authorization 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 });
}
});

// Calculate cashback (example implementation)
function calculateCashback(amount) {
// Example: 1% cashback up to RM10
const cashbackRate = 0.01;
const cashback = amount * cashbackRate;
return Math.min(cashback, 1000); // Max RM10 cashback
}

// Callback handler
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 handler
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);

// Log successful payment
console.log(`Boost payment successful: ${charge.id}`);
} else {
updateOrderStatus(charge.metadata.order_id, 'failed');
console.log(`Boost payment failed: ${charge.id}`);
}
}
}

res.sendStatus(200);
});

// Helper functions
async function updateOrderStatus(orderId, status) {
await db.orders.update({ id: orderId }, { status: status });
}

async function sendConfirmation(email) {
// Send email confirmation
}

app.listen(3000);

Refund Support​

Boost supports full refunds only within 30 days:

// Full refund only (no partial refunds)
const refund = await omise.charges.refund('chrg_test_...', {
amount: 10000 // Must be full amount
});
Refund Limitations
  • Full refunds only - Partial refunds are not supported
  • 30-day window - Refunds must be initiated within 30 days
  • Cashback reversal - Any cashback earned will be reversed

Common Issues & Troubleshooting​

Issue: Boost app not installed​

Cause: Customer doesn't have Boost app installed

Solution:

function detectBoostApp() {
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

if (isMobile) {
return `
<div class="boost-app-check">
<p>Boost app is required for payment.</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>
`;
}
}

Issue: Insufficient balance​

Cause: Customer's Boost wallet balance too low

Solution:

<div class="balance-instructions">
<h3>Insufficient Boost Balance</h3>
<p>Your Boost wallet balance is too low for this transaction.</p>

<h4>How to top up:</h4>
<ul>
<li>ðŸĶ <strong>Online Banking</strong> - Link your bank account</li>
<li>ðŸ’ģ <strong>Debit/Credit Card</strong> - Instant top-up</li>
<li>🏊 <strong>7-Eleven</strong> - Cash top-up at counter</li>
<li>🏧 <strong>Maybank ATM</strong> - Select "Boost Top Up"</li>
<li>ðŸ‘Ĩ <strong>Boost Transfer</strong> - Receive from friends</li>
</ul>

<p>After topping up, return here to complete payment.</p>
</div>

Issue: Daily limit exceeded​

Cause: Customer reached their daily transaction limit

Solution:

function handleLimitExceeded(verificationLevel) {
if (verificationLevel === 'basic') {
return {
error: 'Daily limit exceeded',
message: 'Unverified accounts have a RM1,500 daily limit.',
solution: 'Verify your account to increase limit to RM30,000/day',
instructions: [
'Open Boost app',
'Go to Profile > Verify Account',
'Submit IC/Passport verification',
'Wait for approval (usually 1-2 hours)'
]
};
} else {
return {
error: 'Daily limit exceeded',
message: 'You have reached your RM30,000 daily limit.',
solution: 'Try again tomorrow or use an alternative payment method'
};
}
}

Issue: Account verification pending​

Cause: Customer started verification but not yet approved

Solution:

function showVerificationPending() {
return `
<div class="verification-pending">
<h3>Account Verification Pending</h3>
<p>Your Boost account verification is in progress.</p>
<p>Verification typically takes 1-2 hours during business hours.</p>
<p>Meanwhile, you can:</p>
<ul>
<li>Use your current limit (RM1,500/day)</li>
<li>Choose an alternative payment method</li>
<li>Split your purchase into smaller transactions</li>
</ul>
</div>
`;
}

Issue: Payment timeout​

Cause: Customer didn't complete payment within time limit

Solution:

// 10-minute payment window
const PAYMENT_TIMEOUT = 10 * 60 * 1000;

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

function allowRetry() {
document.getElementById('retry-button').onclick = () => {
// Create new payment
window.location.href = '/checkout';
};
}

Best Practices​

1. Display Boost Benefits​

<div class="boost-benefits">
<img src="/images/boost-logo.svg" alt="Boost" height="40">
<h3>Pay with Boost</h3>
<ul class="benefits-list">
<li>✓ Instant payment confirmation</li>
<li>✓ Earn cashback and rewards</li>
<li>✓ Secure PIN/biometric authentication</li>
<li>✓ No transaction fees</li>
<li>✓ Malaysia's #1 e-wallet</li>
</ul>
<p class="cashback-note">
💰 <strong>Earn up to RM{{cashback}}</strong> cashback on this purchase
</p>
</div>

2. Provide Clear Instructions​

<div class="boost-instructions">
<h3>How to pay with Boost</h3>
<ol class="payment-steps">
<li>
<strong>Click "Pay with Boost"</strong>
<p>You'll be redirected to Boost payment page</p>
</li>
<li>
<strong>Open Boost app</strong>
<p>The app will open automatically on mobile</p>
</li>
<li>
<strong>Authenticate</strong>
<p>Use your 6-digit PIN or biometric</p>
</li>
<li>
<strong>Confirm payment</strong>
<p>Review and confirm the transaction</p>
</li>
</ol>
<p class="requirements">
<strong>Requirements:</strong> Boost app installed with sufficient balance
</p>
</div>

3. Handle Verification Levels​

function checkVerificationLevel(amount) {
const BASIC_LIMIT = 150000; // RM1,500
const VERIFIED_LIMIT = 1000000; // RM10,000

if (amount > VERIFIED_LIMIT) {
return {
error: 'Amount exceeds maximum limit (RM10,000)'
};
}

if (amount > BASIC_LIMIT) {
return {
warning: 'This transaction requires a verified Boost account',
message: 'Please verify your account or reduce amount to RM1,500 or less'
};
}

return { ok: true };
}

4. Validate Amount Limits​

function validateBoostAmount(amount) {
const MIN = 100; // RM1.00
const MAX = 1000000; // RM10,000.00

if (amount < MIN) {
return `Minimum amount is RM${MIN / 100}`;
}

if (amount > MAX) {
return `Maximum amount is RM${MAX / 100}`;
}

return null; // Valid
}

5. Mobile Optimization​

function optimizeForMobile() {
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

if (isMobile) {
// Larger touch targets
document.querySelectorAll('.payment-button').forEach(btn => {
btn.style.minHeight = '50px';
btn.style.fontSize = '18px';
});

// Show app-based flow
showAppFlowInstructions();
} else {
// Show QR code option for desktop
showQRCodeOption();
}
}

6. Use Webhooks Reliably​

// Webhook is primary notification method
app.post('/webhooks/omise', handleWebhook);

// Callback is backup for UI updates
app.get('/payment/callback', handleCallback);

// Never rely solely on callback for order fulfillment

FAQ​

What is Boost?

Boost is Malaysia's largest homegrown digital wallet with over 9 million users. It's a mobile payment app that allows users to make payments, transfer money, top up phone credit, and earn cashback rewards. Boost is widely accepted at 180,000+ merchant locations across Malaysia.

Do customers need a Malaysian bank account?

Yes, customers typically need a Malaysian bank account or credit/debit card to top up their Boost wallet. However, alternative top-up methods like cash at 7-Eleven or receiving transfers from other Boost users are also available.

What are the transaction limits?

Limits depend on verification level:

  • Unverified: RM1,500/day, RM3,000/month
  • Verified (IC/Passport): RM30,000/day, RM100,000/month
  • Per transaction: Up to RM10,000
How do customers top up their Boost wallet?

Customers can top up through:

  • Online banking (FPX)
  • Credit or debit card
  • Cash at 7-Eleven counters
  • Maybank ATM machines
  • Transfer from other Boost users
  • Various partner locations
Can I refund Boost payments?

Yes, but with limitations:

  • Full refunds only - Partial refunds not supported
  • 30-day window - Must refund within 30 days of transaction
  • Cashback reversal - Any cashback earned by customer will be reversed
How long does settlement take?

Boost payments typically settle within 2-3 business days after the transaction. Check your Omise dashboard for specific settlement schedules and dates.

Is Boost available 24/7?

Yes, Boost payments can be processed 24/7 including weekends and holidays. However, settlement to your merchant account follows business day schedules.

What happens if customer's account is unverified?

Unverified accounts have lower limits (RM1,500/day, RM3,000/month). For larger transactions, customers need to verify their account by submitting IC or passport verification through the Boost app. Verification typically takes 1-2 hours during business hours.

Testing​

Test Mode​

Boost can be tested using your test API keys. In test mode:

Test Credentials:

  • Use test API keys (skey_test_xxx)
  • Currency: MYR (Malaysian Ringgit)
  • No actual Boost account needed for testing

Test Flow:

  1. Create source and charge with test API keys
  2. Customer redirects to test authorize_uri
  3. Test page simulates Boost authorization flow
  4. Use Omise Dashboard Actions to mark charge as successful/failed
  5. Verify webhook and return_uri handling

Testing Implementation:

// Test Boost payment
const source = await omise.sources.create({
type: 'boost',
amount: 10000, // RM100.00
currency: 'MYR'
});

const charge = await omise.charges.create({
amount: 10000,
currency: 'MYR',
source: source.id,
return_uri: 'https://example.com/callback',
metadata: {
order_id: 'TEST-001'
}
});

console.log('Test authorize URL:', charge.authorize_uri);

// Use dashboard to simulate payment success/failure

Test Scenarios:

  • Successful payment: Verify order completion workflow
  • Failed payment: Test error handling and retry logic
  • Amount limits: Test min (RM1) and max (RM1,500) amounts
  • Insufficient balance: Simulate low wallet balance scenario
  • Unverified account: Test with limits for unverified accounts
  • Mobile flow: Test app deep-linking and redirects
  • Timeout: Test abandoned payment handling

Important Notes:

  • Test mode doesn't connect to real Boost servers
  • Use Omise Dashboard to mark charges as successful/failed
  • Test mobile-specific flows (app switching)
  • Verify webhook delivery for all status changes
  • Test amount validation and limit enforcement

For comprehensive testing guidelines, see the Testing Documentation.

Next Steps​

  1. Create Boost source
  2. Implement redirect flow
  3. Set up webhook handling
  4. Test payment flow
  5. Go live