Credit & Debit Card Payments
Accept Visa, Mastercard, JCB, American Express, and other major card brands with instant authorization and secure processing.
Overviewโ
Omise enables merchants to accept credit and debit card payments globally through a PCI-certified payment gateway using a REST API. Card payments offer instant authorization with settlement typically within 7 days (Thailand) or 21 days (Japan).
Supported Card Brandsโ
| Brand | Type | Regions |
|---|---|---|
| Visa | Credit & Debit | Thailand, Singapore, Malaysia, Japan |
| Mastercard | Credit & Debit | Thailand, Singapore, Malaysia, Japan |
| JCB | Credit & Debit | All regions (popular in Japan) |
| American Express | Credit | All regions |
| Diners Club | Credit | International |
| Discover | Credit | International |
| UnionPay | Credit & Debit | China and International |
Transaction Limits by Countryโ
| Country | Currency | Minimum | Maximum |
|---|---|---|---|
| Thailand | THB | เธฟ20.00 | เธฟ150,000.00 |
| Japan | JPY | ยฅ100 | ยฅ6,000,000 |
| Malaysia | MYR | RM1.00 | RM100,000.00 |
| Singapore | SGD | S$1.00 | S$20,000.00 |
Payment Flowโ
1. Client-Side Tokenizationโ
Use Omise.js to securely collect card details and create a token:
<!DOCTYPE html>
<html>
<head>
<title>Checkout</title>
<script src="https://cdn.omise.co/omise.js"></script>
</head>
<body>
<form id="checkout-form">
<input type="text" id="card-name" placeholder="Cardholder Name" />
<input type="text" id="card-number" placeholder="Card Number" />
<input type="text" id="card-expiry-month" placeholder="MM" />
<input type="text" id="card-expiry-year" placeholder="YYYY" />
<input type="text" id="card-cvv" placeholder="CVV" />
<button type="submit">Pay Now</button>
</form>
<script>
Omise.setPublicKey("pkey_test_YOUR_PUBLIC_KEY");
document.getElementById('checkout-form').addEventListener('submit', function(e) {
e.preventDefault();
Omise.createToken("card", {
name: document.getElementById('card-name').value,
number: document.getElementById('card-number').value,
expiration_month: document.getElementById('card-expiry-month').value,
expiration_year: document.getElementById('card-expiry-year').value,
security_code: document.getElementById('card-cvv').value
}, function(statusCode, response) {
if (statusCode === 200) {
// Token created successfully
// Send token to your server
fetch('/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: response.id })
});
} else {
// Handle error
alert(response.message);
}
});
});
</script>
</body>
</html>
2. Server-Side Charge Creationโ
Create a charge using the token on your server:
- cURL
- PHP
- Node.js
- Python
- Ruby
- Go
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10025" \
-d "currency=thb" \
-d "card=tokn_test_5rt6s9vah5lkvi1rh9c"
<?php
require_once 'vendor/autoload.php';
define('OMISE_PUBLIC_KEY', 'pkey_test_YOUR_KEY');
define('OMISE_SECRET_KEY', 'skey_test_YOUR_KEY');
$charge = OmiseCharge::create(array(
'amount' => 10025,
'currency' => 'thb',
'card' => $_POST['omiseToken']
));
if ($charge['status'] == 'successful') {
echo 'Payment successful!';
} else {
echo 'Payment failed: ' . $charge['failure_message'];
}
?>
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
const charge = await omise.charges.create({
amount: 10025,
currency: 'thb',
card: tokenId
});
if (charge.status === 'successful') {
console.log('Payment successful!');
} else {
console.log('Payment failed:', charge.failure_message);
}
import omise
omise.api_secret = 'skey_test_YOUR_SECRET_KEY'
charge = omise.Charge.create(
amount=10025,
currency='thb',
card='tokn_test_5rt6s9vah5lkvi1rh9c'
)
if charge.status == 'successful':
print('Payment successful!')
else:
print(f'Payment failed: {charge.failure_message}')
require 'omise'
Omise.api_key = 'skey_test_YOUR_SECRET_KEY'
charge = Omise::Charge.create({
amount: 10025,
currency: 'thb',
card: 'tokn_test_5rt6s9vah5lkvi1rh9c'
})
if charge.status == 'successful'
puts 'Payment successful!'
else
puts "Payment failed: #{charge.failure_message}"
end
package main
import (
"github.com/omise/omise-go"
"github.com/omise/omise-go/operations"
)
func main() {
client, _ := omise.NewClient("pkey_test_YOUR_KEY", "skey_test_YOUR_KEY")
charge, createCharge := &omise.Charge{}, &operations.CreateCharge{
Amount: 10025,
Currency: "thb",
Card: "tokn_test_5rt6s9vah5lkvi1rh9c",
}
if e := client.Do(charge, createCharge); e != nil {
panic(e)
}
}
Charge Status Valuesโ
| Status | Description |
|---|---|
pending | Awaiting payment authorization |
successful | Payment authorized and captured |
failed | Payment declined or failed |
expired | Authorization window expired |
reversed | Authorization was reversed |
Security Featuresโ
1. PCI DSS Complianceโ
- Omise is PCI DSS Level 1 certified
- Card data never touches your server
- Tokenization reduces compliance scope
2. 3D Secure Authenticationโ
- Add extra layer of security
- Reduce fraud and chargebacks
- Shift liability to card issuer
Learn more about 3D Secure โ
3. Address Verification (AVS)โ
- Verify billing address
- Improve authorization rates
- Recommended for international cards
4. CVV Verificationโ
- Verify card security code
- Confirm card possession
- Reduce fraud risk
Improving Authorization Ratesโ
Provide Complete Billing Informationโ
Omise.createToken("card", {
name: "John Doe",
number: "4242424242424242",
expiration_month: 12,
expiration_year: 2027,
security_code: "123",
// Billing address improves authorization
city: "Bangkok",
postal_code: "10110",
country: "TH"
}, callback);
Include Customer Contextโ
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10025" \
-d "currency=thb" \
-d "card=tokn_test_..." \
-d "description=Order #12345" \
-d "metadata[customer_email]=john@example.com" \
-d "metadata[customer_ip]=103.246.xxx.xxx"
Common Issues & Troubleshootingโ
Issue: Payment Declinedโ
Possible Causes:
- Insufficient funds
- Card expired or invalid
- Exceeded card limit
- Fraud check triggered
Solutions:
- Ask customer to check card details
- Try alternative payment method
- Contact card issuer for details
Issue: Token Already Usedโ
Cause: Tokens are single-use only
Solution:
- Generate new token for each charge
- Don't reuse tokens from previous transactions
Issue: Amount Too Low/Highโ
Cause: Transaction outside allowed limits
Solution:
- Check minimum/maximum amounts for your region
- Split large transactions if needed
Best Practicesโ
- Always Use HTTPS - Required for PCI compliance
- Implement Proper Error Handling - Show user-friendly error messages
- Provide Order Context - Include description and metadata
- Collect Billing Address - Improves authorization rates
- Use 3D Secure for High-Risk - Reduce fraud on expensive items
- Monitor Failed Payments - Identify patterns and issues
- Test Thoroughly - Use test cards before going live
FAQโ
What card brands do you support?
We support Visa, Mastercard, JCB, American Express, Diners Club, Discover, and UnionPay across all regions. Availability may vary by your merchant account location.
How long does settlement take?
Settlement periods vary by country:
- Thailand: 7 days holding period
- Japan: 21 days holding period
- Singapore/Malaysia: Check with support
After the holding period, funds become transferable to your bank account.
Can I accept international cards?
Yes, Omise supports international card acceptance. We recommend:
- Enabling Address Verification Service (AVS)
- Collecting complete billing information
- Using multi-currency charging when available
What happens if a payment fails?
Failed payments return a failed status with a failure_code and failure_message. Common failure codes include:
insufficient_fund- Not enough balancestolen_or_lost_card- Card reported stolenfailed_fraud_check- Fraud detection triggeredinvalid_security_code- Wrong CVV
Handle these gracefully and provide clear messages to customers.
Can I save cards for future payments?
Yes! Use the Customers API to save cards for recurring payments:
- Create a customer with card token
- Store customer ID in your database
- Charge the customer ID for future payments
Do you support manual capture (pre-authorization)?
Yes, you can authorize payments without immediately capturing funds. This is useful for:
- Confirming payment method before shipping
- Calculating final amount after service completion
- Hotel-style authorizations
Related Resourcesโ
- Collecting Card Information - Implementation guide
- 3D Secure - Enhanced security
- Saved Cards - Recurring payments
- Pre-Authorization - Manual capture
- Testing - Test card numbers
Next Stepsโ
- Set up Omise.js for tokenization
- Implement server-side charging
- Test with test cards
- Enable 3D Secure for added security
- Go live with your integration