Skip to main content

Bangkok Bank Mobile Banking (Bualuang mBanking)

Accept instant payments via Bualuang mBanking from Bangkok Bank, Thailand's largest bank by assets with 18+ million customers nationwide.

Payment Flow

Mobile Banking Payment Flow

Step-by-step mobile banking payment process:

❶ Select Bank - Customer chooses their bank at merchant checkout

❷ Redirect to bank - System redirects to bank's payment authorization page

❸ Open banking app - Deep link automatically launches the bank's mobile app

  • On iOS: Opens via Universal Links
  • On Android: Opens via App Links
  • Customer sees "Open in [Bank] App" prompt

❹ Authenticate - Customer logs into banking app (if not already logged in)

  • PIN entry (6 digits)
  • Fingerprint scan
  • Face ID recognition

❺ Review payment - Transaction details displayed in app:

  • Merchant name
  • Payment amount
  • Order reference
  • Account to debit from

❻ Authorize payment - Customer confirms the transaction

  • Enter additional PIN/OTP if required by bank
  • Tap "Confirm Payment" button

❼ Payment processed - Bank immediately transfers funds

❽ Confirmation - Success screen shown in app

  • Transaction reference number
  • Receipt available for download

❾ Return to merchant - Customer redirected back to merchant website

  • Automatic redirect or "Return to Merchant" button
  • Order confirmation page displayed

Typical completion time: 30-90 seconds

Overview

Bualuang mBanking is the mobile banking application from Bangkok Bank, Thailand's largest bank by total assets. Customers can make secure payments directly from their bank accounts using the mobile app with PIN or biometric authentication.

Key Features:

  • Largest bank - 18+ million customers, #1 in Thailand by assets
  • Fast confirmation - Near real-time payment verification (typically within seconds)
  • High limits - Up to ฿150,000 per transaction
  • Trusted institution - Established 1944, government-backed
  • 24/7 availability - Works anytime including holidays
  • Secure authentication - PIN, fingerprint, or facial recognition

Supported Regions

RegionCurrencyMin AmountMax AmountDaily Limit
ThailandTHB฿20.00฿150,000Varies by bank*

*Daily limits vary based on customer's bank account settings and are not specified by Omise

How It Works

Customer Experience:

  1. Customer selects "Bangkok Bank" at checkout
  2. Redirected to Bangkok Bank payment page
  3. Opens Bualuang mBanking app via deep link
  4. Reviews transaction details in app
  5. Authenticates with 6-digit PIN, fingerprint, or Face ID
  6. Confirms payment
  7. Returns to merchant website

Typical completion time: 1-3 minutes

Implementation

Step 1: Create Bangkok Bank Source

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

Response:

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

Step 2: Create Charge

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"

Step 3: Redirect Customer

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

// Validate amount
if (amount < 2000 || amount > 200000000) {
return res.status(400).json({
error: 'Amount must be between ฿20 and ฿2,000,000'
});
}

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

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

// Redirect to Bangkok Bank
res.redirect(charge.authorize_uri);

} catch (error) {
console.error('Bangkok Bank 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 === 'mobile_banking_bbl') {
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);
});

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/bangkok-bank', async (req, res) => {
try {
const { amount, order_id } = req.body;

// Validate amount
if (amount < 2000 || amount > 200000000) {
return res.status(400).json({
error: 'Amount must be between ฿20 and ฿2,000,000'
});
}

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

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

// Return authorization URL
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});

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

// 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 === 'mobile_banking_bbl') {
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);

Refund Support

No Refunds

Bangkok Bank mobile banking does NOT support refunds or voids through Omise. Once a payment is completed, it cannot be refunded via the API. You must process refunds manually via bank transfer if needed.

Common Issues & Troubleshooting

Issue: Customer doesn't have Bualuang mBanking app

Cause: Customer selected Bangkok Bank but doesn't have app installed

Solution:

function isMobile() {
return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
}

if (!isMobile()) {
alert('Bangkok Bank mobile banking requires the Bualuang mBanking app. Please use a mobile device or select another payment method.');
}

Issue: Payment expires

Cause: Customer didn't complete payment within time limit (15 minutes)

Solution:

// Show countdown timer
const EXPIRY_TIME = 15 * 60 * 1000; // 15 minutes

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

Issue: Daily limit exceeded

Error: Transaction rejected by bank

Solution:

  • Customer needs to adjust daily limit in Bualuang mBanking app settings
  • Split payment across multiple days
  • Use alternative payment method

Issue: App not opening

Cause: Deep link issue or app not updated

Solution:

function openBangkokBankApp(authorizeUri) {
window.location = authorizeUri;

// Fallback after 2 seconds
setTimeout(() => {
if (!document.hidden) {
showInstallAppMessage();
}
}, 2000);
}

Best Practices

1. Display Clear Instructions

<div class="bangkok-bank-instructions">
<h3>Pay with Bangkok Bank (Bualuang mBanking)</h3>
<ol>
<li>Ensure you have Bualuang mBanking app installed</li>
<li>You'll be redirected to open the app</li>
<li>Authenticate with your 6-digit PIN, fingerprint, or Face ID</li>
<li>Review and confirm the payment</li>
</ol>
<p><strong>Payment must be completed within 15 minutes</strong></p>
<a href="https://www.bangkokbank.com/en/Personal/Digital-Banking/Mobile-Banking">
Download Bualuang mBanking
</a>
</div>
function openBankingApp(authorizeUri) {
// Try to open app
window.location = authorizeUri;

// Check if app opened
setTimeout(() => {
if (document.hidden) {
// App opened successfully
return;
}
// Show instructions
showInstallInstructions();
}, 2000);
}

3. Set Timeout

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

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

4. Use Webhooks

// Webhook is more reliable than redirect callback
app.post('/webhooks/omise', handleWebhook);

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

5. Validate Amount

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

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

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

return null; // Valid
}

FAQ

What is Bualuang mBanking?

Bualuang mBanking is Bangkok Bank's official mobile banking application with 18+ million users. Customers can pay directly from their bank accounts using PIN, fingerprint, or facial recognition.

Do customers need a Bangkok Bank account?

Yes, customers must have an active Bangkok Bank account and the Bualuang mBanking app installed. The app is free on iOS and Android.

What are the transaction limits?
  • Per transaction: ฿20 to ฿2,000,000
  • Daily limit: Up to ฿5,000,000 (varies by account type and settings)

Customers can adjust limits in the app settings (subject to bank approval).

How long does settlement take?

Bangkok Bank mobile banking settlements typically occur within 1-2 business days. Check your Omise dashboard for specific settlement schedules.

Can I refund Bangkok Bank payments?

No, Bangkok Bank mobile banking does NOT support refunds or voids through Omise. Refunds must be processed manually via bank transfer if needed.

What if payment expires?

Payments expire after 15 minutes. Allow customers to retry with a new charge. Display a countdown timer to show remaining time.

Is Bangkok Bank available 24/7?

Yes, Bangkok Bank mobile banking is available 24/7 including weekends and holidays. However, settlement follows business day schedules.

Testing

Test Mode

Bangkok Bank Mobile Banking can be tested using your test API keys. In test mode:

Test Credentials:

  • Use test API keys (skey_test_xxx)
  • Currency: THB (Thai Baht)
  • No actual Bangkok Bank account required for testing

Test Flow:

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

Testing Implementation:

// Test Bangkok Bank Mobile Banking
const source = await omise.sources.create({
type: 'mobile_banking_bbl',
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('Test authorize URL:', charge.authorize_uri);

Test Scenarios:

  • Successful payment: Complete redirect flow and order processing
  • Failed payment: Test error handling
  • Amount limits: Test ฿20 minimum and maximum amounts
  • Mobile flow: Test deep-linking to Bualuang mBanking app
  • Timeout: Test abandoned payment scenarios
  • Return URI: Verify proper redirect after payment
  • Webhook delivery: Verify all webhook notifications

Important Notes:

  • Test mode doesn't connect to real Bangkok Bank servers
  • Use dashboard to simulate payment status changes
  • Test mobile app deep-linking
  • Verify webhook handling for all charge statuses
  • Test both successful and failed payment flows

For comprehensive testing guidelines, see the Testing Documentation.

Next Steps

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