DuitNow Online Banking/Wallets (OBW)
Accept payments from Malaysian customers through their bank's online banking portal or digital wallet using DuitNow OBW.
Overviewโ
DuitNow OBW (Online Banking/Wallets) enables merchants to accept payments through customers' bank online banking portals and digital wallets. It uses a redirect-based flow where customers authenticate and authorize payments on their bank's secure platform.
Key Features:
- โ 18+ banks supported - All major Malaysian banks
- โ Secure bank authentication - Customers authorize on their bank's platform
- โ Redirect flow - Simple redirect integration
- โ Real-time confirmation - Instant payment verification
- โ 180-day refund window - Full and partial refunds supported
Contact support@omise.co to enable DuitNow OBW for your merchant account.
Supported Regionโ
| Region | Currency | Min Amount | Max Amount | API Version |
|---|---|---|---|---|
| Malaysia | MYR | RM1.00 | RM20,000.00 | 2017-11-02 |
Supported Banksโ
| Bank Code | Bank Name |
|---|---|
affin | Affin Bank |
alliance | Alliance Bank |
agro | AGRONet |
ambank | AmBank |
islam | Bank Islam |
muamalat | Bank Muamalat |
rakyat | Bank Rakyat |
bsn | BSN |
cimb | CIMB Clicks |
hongleong | Hong Leong Bank |
hsbc | HSBC |
kfh | KFH |
maybank2u | Maybank2U |
ocbc | OCBC |
publicbank | Public Bank |
rhb | RHB Bank |
sc | Standard Chartered |
uob | UOB |
How It Worksโ
Payment Flow:
- Customer selects DuitNow OBW and chooses their bank
- Merchant creates source with bank code
- Customer redirected to bank's online banking
- Customer logs in and confirms payment with OTP
- Customer returns to merchant site
- Webhook confirms payment status
Typical completion time: 1-3 minutes
Implementationโ
Step 1: Create Sourceโ
- cURL
- Node.js
- PHP
- Omise.js
curl https://api.omise.co/sources \
-u $OMISE_PUBLIC_KEY: \
-d "amount=150000" \
-d "currency=MYR" \
-d "type=duitnow_obw" \
-d "bank=maybank2u"
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const source = await omise.sources.create({
type: 'duitnow_obw',
amount: 150000, // MYR 1,500.00
currency: 'MYR',
bank: 'maybank2u' // Customer's selected bank
});
<?php
$source = OmiseSource::create([
'type' => 'duitnow_obw',
'amount' => 150000,
'currency' => 'MYR',
'bank' => 'maybank2u'
]);
?>
Omise.setPublicKey(omise_public_key);
Omise.createSource('duitnow_obw', {
amount: 150000,
currency: 'MYR',
bank: 'maybank2u'
}, function(statusCode, response) {
console.log(response);
});
Step 2: Create Chargeโ
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=150000" \
-d "currency=MYR" \
-d "return_uri=https://example.com/payment/complete" \
-d "source=src_test_xxx"
Combined Requestโ
Create source and charge in one request:
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=150000" \
-d "currency=MYR" \
-d "return_uri=https://example.com/payment/complete" \
-d "source[type]=duitnow_obw" \
-d "source[bank]=maybank2u"
Step 3: Redirect Customerโ
// Redirect to bank's online banking portal
window.location.href = charge.authorize_uri;
Step 4: Handle Webhookโ
app.post('/webhooks/omise', (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.status === 'successful') {
fulfillOrder(charge.metadata.order_id);
} else if (charge.status === 'failed') {
notifyCustomer(charge.metadata.order_id, charge.failure_message);
}
}
res.status(200).send('OK');
});
Bank Selection UIโ
Display a bank selection dropdown for customers:
<div class="bank-selection">
<label for="bank">Select your bank:</label>
<select id="bank" name="bank" required>
<option value="">-- Choose Bank --</option>
<option value="maybank2u">Maybank2U</option>
<option value="cimb">CIMB Clicks</option>
<option value="publicbank">Public Bank</option>
<option value="rhb">RHB Bank</option>
<option value="hongleong">Hong Leong Bank</option>
<option value="ambank">AmBank</option>
<option value="affin">Affin Bank</option>
<option value="alliance">Alliance Bank</option>
<option value="islam">Bank Islam</option>
<option value="muamalat">Bank Muamalat</option>
<option value="rakyat">Bank Rakyat</option>
<option value="bsn">BSN</option>
<option value="hsbc">HSBC</option>
<option value="ocbc">OCBC</option>
<option value="sc">Standard Chartered</option>
<option value="uob">UOB</option>
</select>
</div>
Charge Status Valuesโ
| Status | Description |
|---|---|
pending | Awaiting customer authorization at bank |
successful | Payment completed |
failed | Payment declined or processing error |
expired | Customer didn't complete within 7 days |
Failure Codesโ
| Code | Description |
|---|---|
payment_expired | Authorization window closed |
payment_rejected | Bank declined transaction |
failed_processing | General processing error |
invalid_account | No valid account for payment |
insufficient_fund | Insufficient balance or limit |
Refundsโ
DuitNow OBW supports full and partial refunds within 180 days of the transaction:
// Full or partial refund
const refund = await omise.charges.refund('chrg_test_xxx', {
amount: 50000 // Partial refund of MYR 500.00
});
Best Practicesโ
- Show bank logos - Display recognizable bank logos for selection
- Indicate processing - Show loading state during redirect
- Handle timeouts - Customer has 7 days to complete payment
- Webhook priority - Always use webhook for order fulfillment
- Mobile optimization - Bank portals work on mobile devices
FAQโ
What is DuitNow OBW?
DuitNow OBW (Online Banking/Wallets) is a payment method that allows Malaysian customers to pay directly through their bank's online banking portal. Customers select their bank, get redirected to log in, and authorize the payment with OTP verification.
What's the difference between DuitNow OBW and DuitNow QR?
DuitNow OBW: Customer is redirected to their bank's online banking portal to authorize payment. Better for desktop and web checkout flows.
DuitNow QR: Customer scans a QR code with any banking app or e-wallet. Better for in-store payments and mobile-first experiences.
Both are part of Malaysia's DuitNow payment infrastructure.
Which banks are supported?
DuitNow OBW supports 18+ Malaysian banks including Maybank, CIMB, Public Bank, RHB, Hong Leong, AmBank, Affin, Alliance, Bank Islam, Bank Muamalat, Bank Rakyat, BSN, HSBC, OCBC, Standard Chartered, and UOB.
How long does the customer have to complete payment?
Customers have up to 7 days to complete the payment after the charge is created. However, individual bank session timeouts may be shorter. If payment isn't completed, the charge status becomes expired.
Can I refund DuitNow OBW payments?
Yes, both full and partial refunds are supported within 180 days of the original transaction date.
Is DuitNow OBW better than FPX?
DuitNow OBW and FPX both enable online banking payments in Malaysia. DuitNow OBW is the newer standard under PayNet's DuitNow infrastructure. Both work similarly - choose based on your existing integration or PayNet/FPX availability for your merchant account.
Related Resourcesโ
- DuitNow QR - QR-based payments
- FPX - Alternative bank transfer
- Bank Transfers Overview - All bank transfer methods
- Webhooks - Webhook handling