How Omise Works
Understanding the core concepts of Omise will help you build a secure, efficient payment integration. Learn about tokens, charges, sources, and the payment flow.
Overviewโ
Omise is a PCI-certified payment gateway that enables businesses to accept payments securely without handling sensitive card data directly. By using a token-based architecture, Omise keeps card information out of your servers, reducing your PCI compliance burden while maintaining security.
Core Conceptsโ
1. Payment Gateway Architectureโ
Omise sits between your application and payment processors, handling:
- Tokenization: Converting sensitive data into secure tokens
- Authorization: Validating and authorizing payments
- Settlement: Moving funds from customers to your account
- Reconciliation: Tracking and reporting on all transactions
2. The Two-Server Modelโ
Omise uses two separate API endpoints for security:
Vault Server (vault.omise.co)โ
- Purpose: Handles sensitive cardholder data
- Used with: Public keys
- Operations: Create tokens and sources
- Security: Isolates card data from main API
API Server (api.omise.co)โ
- Purpose: Handles all other operations
- Used with: Secret keys
- Operations: Create charges, refunds, transfers, etc.
- Security: Never receives raw card data
This separation ensures that sensitive card data never touches your servers or the main API, significantly reducing your PCI compliance requirements.
3. API Keysโ
Omise uses three types of API keys:
| Key Type | Format | Use Case | Safe for Client? |
|---|---|---|---|
| Public Key | pkey_test_... | Tokenization | โ Yes |
| Secret Key | skey_test_... | All operations | โ No (server only) |
| Chain Key | ck_test_... | Sub-merchants | โ No (server only) |
Learn more about authentication โ
4. Payment Objectsโ
Tokensโ
A token represents a payment method (usually a card) and can be used once to create a charge.
Properties:
- Single-use only
- Valid for 30 minutes after creation
- Contains tokenized card information
- Created with public key
Example:
{
"object": "token",
"id": "tokn_test_5xp6ca4dtzx5cskm9mk",
"used": false,
"card": {
"brand": "Visa",
"last_digits": "4242",
"expiration_month": 12,
"expiration_year": 2027
}
}
Chargesโ
A charge represents a payment request to a customer's payment method.
Properties:
- Created with a token, source, or customer card
- Can be authorized (captured later) or captured immediately
- Supports metadata for custom tracking
- Generates a transaction when successful
Example:
{
"object": "charge",
"id": "chrg_test_5xp6ccfmecft4zxrb7p",
"amount": 100000,
"currency": "thb",
"status": "successful",
"paid": true,
"authorized": true,
"captured": true
}
Charge Statuses:
pending- Awaiting payment (for async methods)successful- Payment completedfailed- Payment declined or failedexpired- Payment window expired (async methods)
Sourcesโ
A source represents alternative payment methods like PromptPay, mobile banking, or QR codes.
Properties:
- Created for specific payment methods
- Can be single-use or reusable
- Often includes payment instructions (QR code, bank details)
- Requires customer action to complete
Example:
{
"object": "source",
"id": "src_test_5xp6ccfmecft4zxrb7p",
"type": "promptpay",
"flow": "redirect",
"amount": 100000,
"currency": "thb",
"scannable_code": {
"image": {
"download_uri": "https://...",
"type": "qr_code"
}
}
}
Customersโ
A customer object stores payment methods for recurring charges.
Properties:
- Can store multiple cards
- Enables subscription billing
- Supports metadata for custom tracking
- Cards attached to customers can be charged repeatedly
Example:
{
"object": "customer",
"id": "cust_test_5xp6ccfmecft4zxrb7p",
"email": "customer@example.com",
"description": "John Doe",
"cards": {
"total": 1,
"data": [...]
}
}
Payment Flowโ
Standard Card Payment Flowโ
Here's how a typical card payment works:
Step-by-Step:
- Customer enters card details on your checkout page
- Browser sends card data to Omise Vault (using public key)
- Omise returns a token representing the card
- Browser sends token to your server (not card data!)
- Your server creates a charge using secret key + token
- Omise processes payment with the bank
- Bank authorizes (or declines) the payment
- Omise returns result to your server
- Your server updates order and shows confirmation
Alternative Payment Method Flowโ
For methods like PromptPay or mobile banking:
Key Differences:
- Create a source instead of a token
- Customer completes payment outside your app
- You receive a webhook when payment completes
- Payment may expire if not completed in time
Data Flow & Securityโ
What Stays Secureโ
Security Principles:
- โ Card data goes directly to Omise Vault (never your server)
- โ Tokens are single-use and time-limited
- โ Secret keys stay on your server
- โ All communication over HTTPS
- โ PCI-compliant infrastructure
What You Storeโ
You should store:
- โ Charge IDs
- โ Customer IDs
- โ Order information
- โ Metadata
- โ Card numbers
- โ CVV codes
- โ Full card details
Environmentsโ
Test Modeโ
- Simulated transactions
- No real money
- Test cards and payment methods
- Separate dashboard
- API keys with
_test_prefix
Live Modeโ
- Real transactions
- Real money processed
- Real cards and payment methods
- Production dashboard
- API keys without
_test_prefix
Learn about Test vs Live Mode โ
Money Flowโ
Settlement Processโ
Hold Periods:
- Thailand: 7 days
- Japan: 21 days
- Singapore: 7 days
- Malaysia: 7 days
- Test Mode: Instant (for testing)
Hold periods may vary based on your merchant agreement and account history. Check your dashboard or contact support for your specific settlement schedule.
Why Hold Periods?
- Protection against chargebacks
- Time for refunds to process
- Industry standard practice
Feesโ
Omise charges fees on successful transactions:
- Deducted from the charge amount
- Varies by payment method
- Visible in dashboard and API
- No setup or monthly fees
Advanced Conceptsโ
Pre-authorization (Auth & Capture)โ
Authorize payment now, capture later:
// Step 1: Authorize only
omise.charges.create({
amount: 100000,
currency: 'thb',
card: token,
capture: false // Don't capture yet
});
// Step 2: Capture later (within 7 days)
omise.charges.capture('chrg_test_123');
Use Cases:
- Hotel reservations
- Car rentals
- Custom shipping calculations
3D Secure Authenticationโ
Additional security layer for cards:
- Customer authenticates with their bank
- Reduces fraud and chargebacks
- Required for some card types
- Liability shift to issuer
Webhooksโ
Real-time notifications for events:
- Charge completed
- Charge failed
- Refund created
- Transfer completed
Common Patternsโ
One-Time Paymentโ
// 1. Create token (client-side)
Omise.createToken('card', cardData, (status, response) => {
// 2. Send token to server
fetch('/charge', {
method: 'POST',
body: JSON.stringify({ token: response.id })
});
});
// 3. Create charge (server-side)
omise.charges.create({
amount: 100000,
currency: 'thb',
card: req.body.token
});
Recurring Paymentsโ
// 1. Create customer with card
const customer = await omise.customers.create({
email: 'customer@example.com',
card: token
});
// 2. Charge customer later (no token needed)
await omise.charges.create({
amount: 100000,
currency: 'thb',
customer: customer.id
});
Alternative Payment Methodsโ
// 1. Create source
const source = await omise.sources.create({
type: 'promptpay',
amount: 100000,
currency: 'thb'
});
// 2. Show QR code to customer
displayQR(source.scannable_code.image.download_uri);
// 3. Wait for webhook notification
// Webhook will fire when customer pays
FAQโ
What's the difference between a token and a charge?
A token is a secure representation of a payment method (like a card). It's created on the client-side and sent to your server.
A charge is an actual payment request. It's created on your server using a token, and it processes money from the customer to you.
Think of it as: Token = Payment Method, Charge = Payment Request
Why can't I use tokens multiple times?
Tokens are single-use for security reasons. If tokens could be reused, a compromised token could result in multiple unauthorized charges.
For recurring payments, create a Customer object and attach the card to it. Then you can charge the customer multiple times without creating new tokens.
What happens if a charge fails?
Failed charges return an error with details about why the payment failed:
- Insufficient funds
- Invalid card number
- Card declined by issuer
- Expired card
The charge object will have status: "failed" and include a failure_code and failure_message explaining the reason.
How do I know when an async payment completes?
For alternative payment methods (PromptPay, mobile banking, etc.), use webhooks to receive notifications when payments complete.
Set up a webhook endpoint on your server, then configure it in your Omise dashboard. Omise will POST event data to your endpoint when payment status changes.
Can I partially capture a pre-authorized charge?
Yes! You can capture less than the authorized amount:
// Authorized เธฟ1,000
omise.charges.create({
amount: 100000,
currency: 'thb',
card: token,
capture: false
});
// Capture only เธฟ500
omise.charges.capture('chrg_123', {
capture_amount: 50000
});
The uncaptured amount is automatically released.
What's the difference between sources and tokens?
- Tokens: Used for card payments, created on client-side, single-use
- Sources: Used for alternative payment methods (PromptPay, QR, banking), can include payment instructions, may require customer action
Both represent payment methods, but sources handle more complex payment flows.
Visual Summaryโ
The Complete Payment Ecosystemโ
Related Resourcesโ
- Quickstart Guide - Build your first integration
- Authentication - Understanding API keys
- Payment Methods - Explore all payment options
- Security Best Practices - Keep your integration secure
Ready to build? Start with our Quickstart Guide or explore all payment methods.