Tokens API
Overviewโ
The Tokens API enables you to securely tokenize credit card information without handling sensitive card data on your servers. Tokens are single-use, encrypted references to card data that can be used to create charges.
What are Tokens?โ
Tokens are temporary, single-use representations of credit card information that:
- Expire after use - Each token can only be used once to create a charge or attach to a customer
- Protect card data - Your server never handles raw card details
- Enable PCI compliance - Reduces your PCI compliance scope significantly
- Validate immediately - Card details are validated during tokenization
Key Featuresโ
Security Firstโ
- Public key authentication - Use your public key (safe to expose in client-side code)
- Single-use tokens - Tokens cannot be reused after creating a charge
- No sensitive data storage - Card data never touches your servers
- PCI DSS compliant - Meets strictest security standards
Easy Integrationโ
- Client-side tokenization - Create tokens directly from browser/mobile app
- Omise.js library - Pre-built JavaScript library for easy integration
- Mobile SDKs - Native iOS and Android SDKs available
- Server-to-server - API available for server-side tokenization when needed
Flexibilityโ
- Works with all card types - Visa, Mastercard, JCB, etc.
- 3D Secure support - Automatic 3DS handling
- Card validation - Validates card number, CVV, expiration
- International support - Process cards from any country
How Tokens Workโ
Standard Flowโ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ
โ Client โ โ Omise.jsโ โ Your โ โ Omise โ
โ Browser โ โ Library โ โ Server โ โ API โ
โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ
โ โ โ โ
โ 1. Enter card โ โ โ
โโโโโโโโโโโโโโโโโโโ>โ โ โ
โ โ โ โ
โ โ 2. Create token โ โ
โ โ (with public key) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ>โ
โ โ โ โ
โ โ 3. Return token โ โ
โ โ<โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ โ โ
โ 4. Send token ID โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ>โ โ
โ โ โ โ
โ โ โ 5. Create charge โ
โ โ โ (with secret key)
โ โ โโโโโโโโโโโโโโโโโโโ>โ
โ โ โ โ
โ โ โ 6. Charge result โ
โ โ โ<โโโโโโโโโโโโโโโโโโโค
โ โ โ โ
โ 7. Show result โ โ โ
โ<โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โ โ
Implementation Stepsโ
- Client-side: Collect card details in your payment form
- Client-side: Use Omise.js to tokenize card data with your public key
- Client-side: Send token ID to your server (safe - it's single-use)
- Server-side: Create charge using token ID with your secret key
- Server-side: Return payment result to client
Token Lifecycleโ
Statesโ
| State | Description | Can Create Charge? |
|---|---|---|
| Active | Newly created, unused token | โ Yes |
| Used | Token used to create charge/customer | โ No - Error "used_token" |
| Expired | Token older than 30 minutes | โ No - Error "token_expired" |
State Transitionsโ
Tokens move through states based on the following triggers:
โโโโโโโโโโโ
โ Active โ โ Token created via Omise.js or API
โโโโโโฌโโโโโ
โ
โโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโ โโโโโโโโโโโ
โ Used โ โ Expired โ
โโโโโโโโโโโ โโโโโโโโโโโ
Transition Triggers:
| From State | To State | Trigger | Error Code |
|---|---|---|---|
| Active โ Used | Token used in POST /charges or POST /customers/:id/cards | - | |
| Active โ Expired | 30 minutes pass since creation | token_expired | |
| Used โ same | Attempt to reuse token | used_token | |
| Expired โ same | Attempt to use expired token | token_expired |
Examples of State Transitions:
// 1. Create token (Active state)
const token = await omise.tokens.create({
card: {
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2027,
security_code: '123',
name: 'JOHN DOE'
}
});
console.log(token.used); // false (Active)
// 2. Create charge (Active โ Used)
const charge = await omise.charges.create({
amount: 100000,
currency: 'thb',
card: token.id
});
// Token is now marked as Used
// 3. Attempt to reuse (Error: used_token)
try {
await omise.charges.create({
amount: 50000,
currency: 'thb',
card: token.id // Same token
});
} catch (error) {
console.error(error.code); // "used_token"
console.error(error.message); // "token was already used"
}
// 4. Token expires after 30 minutes (Active โ Expired)
// Automatic - no action needed
// If unused for 30+ minutes, token.used === false but API returns token_expired
Expiration Rulesโ
- Automatic expiration: 30 minutes after creation
- Single-use: Immediately marked as used after first charge/customer attachment
- No reuse: Cannot be reused even for same customer
- Irreversible: Used and expired tokens cannot be reactivated
API Endpointsโ
| Method | Endpoint | Description |
|---|---|---|
| POST | /tokens | Create a new token from card data |
| GET | /tokens/:id | Retrieve token information |
Quick Startโ
Using Omise.js (Recommended)โ
<!-- 1. Include Omise.js -->
<script src="https://cdn.omise.co/omise.js"></script>
<script>
// 2. Set your public key
Omise.setPublicKey('pkey_test_YOUR_PUBLIC_KEY');
// 3. Tokenize card
const cardData = {
name: 'JOHN DOE',
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2025,
security_code: '123'
};
Omise.createToken('card', cardData, (statusCode, response) => {
if (statusCode === 200) {
// Success - token created
const tokenId = response.id;
// 4. Send token to your server
fetch('/charge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: tokenId, amount: 100000 })
})
.then(res => res.json())
.then(data => {
console.log('Charge created:', data.id);
})
.catch(err => {
console.error('Charge failed:', err);
alert('Payment processing failed. Please try again.');
});
} else {
// Tokenization failed - handle specific errors
console.error('Tokenization failed:', response);
// Handle common error codes
switch (response.code) {
case 'invalid_card':
alert('Invalid card number. Please check and try again.');
break;
case 'invalid_expiration_date':
alert('Invalid expiration date. Please check and try again.');
break;
case 'invalid_security_code':
alert('Invalid CVV/security code. Please check and try again.');
break;
case 'network_error':
alert('Network error. Please check your connection and try again.');
break;
default:
alert('Payment failed: ' + response.message);
}
}
});
</script>
Server-side Processingโ
// Node.js example
const omise = require('omise')({
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
// Receive token from client
app.post('/charge', async (req, res) => {
const { token, amount } = req.body;
try {
// Create charge with token
const charge = await omise.charges.create({
amount: amount,
currency: 'thb',
card: token // Use token here
});
res.json({ success: true, charge: charge });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
Common Use Casesโ
Single Paymentโ
Create token โ Create charge โ Done
// Client: Tokenize
Omise.createToken('card', cardData, (status, response) => {
// Server: Charge
omise.charges.create({ card: response.id, amount: 100000 });
});
Save Card for Laterโ
Create token โ Attach to customer โ Charge customer
// Create customer with token
const customer = await omise.customers.create({
email: 'john@example.com',
card: tokenId
});
// Later: Charge customer's saved card
const charge = await omise.charges.create({
customer: customer.id,
amount: 100000
});
Multiple Cards per Customerโ
Create token โ Attach to existing customer โ Select card to charge
// Add card to customer
const card = await omise.customers.updateCard(customerId, {
card: tokenId
});
// Charge specific card
const charge = await omise.charges.create({
customer: customerId,
card: card.id,
amount: 100000
});
Security Best Practicesโ
โ Do Thisโ
- Use HTTPS for all pages with payment forms
- Use Omise.js for client-side tokenization
- Validate on server - Don't trust client-side validation alone
- Never log tokens in plain text
- Use public key client-side only
- Use secret key server-side only
- Implement CSP headers to prevent XSS attacks