Sources API
Overviewβ
The Sources API enables you to accept alternative payment methods beyond credit cards. Sources represent payment channels like PromptPay QR codes, mobile banking, internet banking, installment plans, and more.
What are Sources?β
Sources are payment method objects that represent:
- PromptPay QR codes - Real-time QR-based payments
- Mobile banking - In-app payment redirects (SCB Easy, Krungthai Next, etc.)
- Internet banking - Online bank transfers
- Convenience stores - Cash payments at 7-Eleven, FamilyMart, etc.
- Installment plans - Pay-in-installments options
- E-wallets - TrueMoney, Rabbit LINE Pay, etc.
Key Featuresβ
Wide Payment Method Supportβ
- QR Payments - PromptPay, Alipay, WeChat Pay
- Bank Transfers - Mobile and internet banking
- Installments - 0% interest installment plans
- Cash Payments - Convenience store payments
- E-wallets - Digital wallet integrations
Flexible Workflowsβ
- Redirect-based - Customer redirects to complete payment
- QR code display - Show QR code for customer to scan
- Webhook notifications - Real-time payment status updates
- Asynchronous processing - Payments complete outside your site
Regional Supportβ
- Thailand - PromptPay, SCB, Krungthai, BAY, BBL, etc.
- Malaysia - FPX, Boost, GrabPay, Touch 'n Go
- Singapore - PayNow, GrabPay
- International - Alipay, WeChat Pay
How Sources Workβ
Standard Flowβ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ
β Your β β Omise β β Payment β β Customerβ
β Server β β API β β Providerβ β β
ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ
β β β β
β 1. Create source β β β
βββββββββββββββ ββββ>β β β
β β β β
β 2. Return source β β β
β (with QR/URL) β β β
β<βββββββββββββββββββ€ β β
β β β β
β 3. Create charge β β β
βββββββββββββββββββ>β β β
β β β β
β 4. Return charge β β β
β (status:pending) β β
β<βββββββββββββββββββ€ β β
β β β β
β 5. Display QR β β β
β or redirect β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β
β β β β
β β β 6. Customer pays β
β β β<βββββββββββββββββββ€
β β β β
β β 7. Webhook notify β β
β<βββββββββββββββββββ€ β β
β β β β
β 8. Show success β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β
β β β β
Implementation Stepsβ
- Create source - Specify payment method type and amount
- Create charge - Use source ID to create charge (status: pending)
- Display payment UI - Show QR code or redirect customer
- Wait for webhook - Customer completes payment asynchronously
- Verify status - Check charge status via webhook or API
- Fulfill order - Process order after successful payment
Source Typesβ
QR-Based Paymentsβ
| Type | Description | Region |
|---|---|---|
| promptpay | Thailand's national QR payment | Thailand |
| alipay | China's leading e-wallet | International |
| wechat_pay | WeChat Pay QR | International |
| paynow | Singapore's QR payment | Singapore |
Mobile Bankingβ
| Type | Description | Region |
|---|---|---|
| mobile_banking_scb | SCB Easy app | Thailand |
| mobile_banking_kbank | K PLUS app | Thailand |
| mobile_banking_bbl | Bangkok Bank Mobile | Thailand |
| mobile_banking_bay | Krungsri Mobile | Thailand |
| mobile_banking_ktb | Krungthai NEXT app | Thailand |
Internet Bankingβ
| Type | Description | Region |
|---|---|---|
| internet_banking_scb | SCB online banking | Thailand |
| internet_banking_bbl | Bangkok Bank online | Thailand |
| internet_banking_bay | Krungsri online | Thailand |
| fpx | Malaysia's online banking | Malaysia |
Other Payment Methodsβ
| Type | Description | Region |
|---|---|---|
| truemoney | TrueMoney Wallet | Thailand |
| rabbit_linepay | Rabbit LINE Pay | Thailand |
| installment_bay | Krungsri installments | Thailand |
| installment_kbank | Kasikornbank installments | Thailand |
| econtext | Convenience store payments | Japan |
Source Lifecycleβ
Statesβ
| State | Description | Charge Status |
|---|---|---|
| pending | Source created, awaiting payment | pending |
| successful | Payment completed | successful |
| failed | Payment failed or declined | failed |
| expired | Payment window expired | expired |
Expiration Rulesβ
Different payment methods have different default expiration times:
The expiration times listed below are based on available documentation and may vary. For the most accurate and up-to-date expiration times for your specific payment methods, consult the individual payment method documentation or contact Omise support.
| Payment Method | Default Expiration | Custom Expiration |
|---|---|---|
| PromptPay | 24 hours | Customizable via expires_in |
| Mobile Banking (SCB/KBANK/BBL/BAY/KTB) | 15-30 minutes* | Customizable via expires_in |
| Internet Banking (SCB/BBL/BAY) | 15-30 minutes* | Customizable via expires_in |
| FPX (Malaysia) | 30 minutes* | Customizable via expires_in |
| PayNow (Singapore) | 15-30 minutes* | Customizable via expires_in |
| Alipay | 15-30 minutes* | Customizable via expires_in |
| WeChat Pay | 15-30 minutes* | Customizable via expires_in |
| TrueMoney Wallet | 15-30 minutes* | Customizable via expires_in |
| Rabbit LINE Pay | 15-30 minutes* | Customizable via expires_in |
| GrabPay | 15-30 minutes* | Customizable via expires_in |
| Boost | 15-30 minutes* | Customizable via expires_in |
| Touch 'n Go | 15-30 minutes* | Customizable via expires_in |
| Installment Plans (BAY/KBANK) | 24-48 hours* | Customizable via expires_in |
| Convenience Stores (Japan) | 7 days* | Customizable via expires_in |
*Verify with specific payment method documentation or Omise support for exact values.
Setting Custom Expiration:
const source = await omise.sources.create({
type: 'promptpay',
amount: 100000,
currency: 'thb',
expires_in: 1800 // 30 minutes (in seconds)
});
Best Practices:
- Check individual payment method documentation for recommended expiration times
- Shorter expiration (5-15 minutes) for QR payments to prevent stale QR codes
- Longer expiration (24-48 hours) for bank transfers to allow processing time
- Always handle
source.expiredwebhook events to update order status
API Endpointsβ
| Method | Endpoint | Description |
|---|---|---|
| POST | /sources | Create a new source |
| GET | /sources/:id | Retrieve source information |
Quick Startβ
PromptPay QR Payment Exampleβ
// 1. Create PromptPay source
const source = await omise.sources.create({
type: 'promptpay',
amount: 100000,
currency: 'thb'
});
// 2. Create charge with source
const charge = await omise.charges.create({
amount: 100000,
currency: 'thb',
source: source.id,
return_uri: 'https://example.com/payment/complete'
});
// 3. Display QR code to customer
const qrCodeUrl = charge.source.scannable_code.image.download_uri;
console.log('Show QR code:', qrCodeUrl);
// 4. Wait for webhook notification
// Webhook event: charge.complete
// Verify charge status changed to "successful"
Mobile Banking Exampleβ
// 1. Create mobile banking source
const source = await omise.sources.create({
type: 'mobile_banking_scb',
amount: 50000,
currency: 'thb'
});
// 2. Create charge
const charge = await omise.charges.create({
amount: 50000,
currency: 'thb',
source: source.id,
return_uri: 'https://example.com/payment/complete'
});
// 3. Redirect customer to authorize_uri
const redirectUrl = charge.authorize_uri;
// Redirect customer to this URL
window.location.href = redirectUrl;
// 4. Customer completes payment in banking app
// 5. Customer redirected back to return_uri
// 6. Webhook sent when payment completes
Payment Flowsβ
QR Code Flow (PromptPay, Alipay, WeChat Pay)β
- Create source β Create charge
- Display QR code to customer
- Customer scans with mobile app
- Customer confirms payment in app
- Webhook notification sent
- Update order status
Redirect Flow (Mobile Banking, Internet Banking)β
- Create source β Create charge
- Redirect customer to
authorize_uri - Customer completes payment
- Customer redirected to
return_uri - Webhook notification sent
- Verify payment status
Offline Flow (Convenience Stores)β
- Create source β Create charge
- Display payment code to customer
- Customer pays at convenience store
- Webhook notification sent (hours/days later)
- Fulfill order
Common Use Casesβ
Single Paymentβ
const source = await omise.sources.create({ type: 'promptpay', amount: 100000, currency: 'thb' });
const charge = await omise.charges.create({ amount: 100000, currency: 'thb', source: source.id });
Installment Paymentβ
const source = await omise.sources.create({
type: 'installment_kbank',
amount: 300000,
currency: 'thb',
installment_term: 6 // 6 months
});
const charge = await omise.charges.create({ amount: 300000, currency: 'thb', source: source.id });
Convenience Store Paymentβ
const source = await omise.sources.create({
type: 'econtext',
amount: 50000,
currency: 'jpy',
name: 'TARO YAMADA',
email: 'taro@example.com',
phone_number: '+81312345678'
});
const charge = await omise.charges.create({ amount: 50000, currency: 'jpy', source: source.id });
Best Practicesβ
β Do Thisβ
- Set return_uri for redirect-based payments
- Implement webhooks for asynchronous notifications
- Display clear instructions for each payment method
- Set appropriate expiration based on payment type
- Verify payment status via webhooks, not polling
- Handle timeouts gracefully (customer didn't complete)
- Test each payment method before going live
- Store source IDs for tracking and support
β Don't Do Thisβ
- Don't poll constantly (use webhooks)
- Don't assume immediate payment (they're async)
- Don't skip return_uri (customers need to come back)
- Don't ignore expiration (sources expire)
- Don't mix payment methods (one source = one payment type)
- Don't use sources with wrong currency (type-specific)
Security Considerationsβ
Webhook Verificationβ
Always verify webhook signatures to ensure authenticity:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const expectedSignature = hmac.digest('hex');
return signature === expectedSignature;
}
Status Verificationβ
Don't trust return_uri parameters alone. Always verify charge status:
// Customer returns from payment
app.get('/payment/complete', async (req, res) => {
const chargeId = req.query.charge_id;
// Verify actual charge status
const charge = await omise.charges.retrieve(chargeId);
if (charge.status === 'successful') {
// Payment confirmed, fulfill order
} else {
// Payment not complete, show error
}
});
Testingβ
Test Modeβ
All source types work in test mode with your test secret key.
Simulating Paymentsβ
In test mode, you can:
- Create sources and charges
- Receive webhooks
- Test redirect flows
- Generate test QR codes
Test Webhooksβ
Use webhook testing tools or ngrok for local development:
ngrok http 3000
# Set webhook URL in Omise Dashboard
Error Handlingβ
Common source errors:
| Error Code | Description | Solution |
|---|---|---|
invalid_source_type | Unsupported payment method | Check available types for your currency |
amount_too_low | Amount below minimum | Check minimum amount for payment type |
currency_not_supported | Wrong currency | Verify payment type supports currency |
expired_source | Source expired | Create new source |
API Referenceβ
- Create Source - POST /sources
- Retrieve Source - GET /sources/:id
Related Resourcesβ
Payment Method Guidesβ
Need help? Check our Payment Methods Guide or contact support@omise.co