Skip to main content
Version: 2019-05-29 (Current)

API Versioning

Manage API version changes gracefully and maintain backward compatibility. Learn about Omise's versioning strategy, how to specify versions, and best practices for upgrades.

Overviewโ€‹

Omise uses date-based API versioning to introduce improvements without breaking existing integrations. Each version is named by its release date (YYYY-MM-DD format). You can control which API version your integration uses to ensure stability and plan upgrades on your schedule.

Quick Start
  • Current Version: 2019-05-29
  • Use Omise-Version header to specify version
  • No header = account's default version
  • Versions never change - your integration stays stable
  • Plan upgrades when new features are needed

Current API Versionโ€‹

Latest Version: 2019-05-29โ€‹

Released: May 29, 2019

This is the current stable version of the Omise API. All new integrations should use this version.

curl https://api.omise.co/charges \
-u skey_test_...: \
-H "Omise-Version: 2019-05-29"

How Versioning Worksโ€‹

Version Formatโ€‹

Omise API versions use date-based naming:

YYYY-MM-DD

Examples:

  • 2019-05-29 - May 29, 2019 release
  • 2017-11-02 - November 2, 2017 release
  • 2015-11-17 - November 17, 2015 release

Specifying API Versionโ€‹

You can specify the API version in two ways:

Use the Omise-Version header:

curl https://api.omise.co/charges \
-u skey_test_...: \
-H "Omise-Version: 2019-05-29" \
-X POST \
-d "amount=100000" \
-d "currency=thb"

Benefits:

  • โœ… Explicit version control per request
  • โœ… Easy to test new versions
  • โœ… Can use different versions for different operations
  • โœ… Overrides account default

2. Account Default Versionโ€‹

Set a default version in your Dashboard:

  1. Log in to Omise Dashboard
  2. Go to Settings โ†’ API Version
  3. Select version
  4. Save

All requests without Omise-Version header use this version.


Version Behaviorโ€‹

How Versions Workโ€‹

  1. Versions are immutable - A version's behavior never changes
  2. New versions introduce changes - Breaking changes only in new versions
  3. You control upgrades - Explicitly opt-in to new versions
  4. Old versions supported - Legacy versions remain available

Example Timelineโ€‹

2015-11-17 โ†’ Your integration built
โ†“
2017-11-02 โ†’ New version released
โ†“ (Your integration still uses 2015-11-17)
โ†“
2019-05-29 โ†’ New version released
โ†“ (Your integration still uses 2015-11-17)
โ†“
Today โ†’ You upgrade to 2019-05-29
โ†“ (Opt-in when ready)

Specifying Version in Codeโ€‹

Rubyโ€‹

require 'omise'

Omise.api_key = ENV['OMISE_SECRET_KEY']
Omise.api_version = '2019-05-29'

# All requests use specified version
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})

Pythonโ€‹

import omise

omise.api_secret = os.environ['OMISE_SECRET_KEY']
omise.api_version = '2019-05-29'

# All requests use specified version
charge = omise.Charge.create(
amount=100000,
currency='thb',
card=token
)

PHPโ€‹

<?php
require_once 'vendor/autoload.php';

define('OMISE_SECRET_KEY', getenv('OMISE_SECRET_KEY'));
define('OMISE_API_VERSION', '2019-05-29');

OmiseCharge::create([
'amount' => 100000,
'currency' => 'thb',
'card' => $token
]);

Node.jsโ€‹

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
omiseVersion: '2019-05-29'
});

// All requests use specified version
const charge = await omise.charges.create({
amount: 100000,
currency: 'thb',
card: token
});

Goโ€‹

package main

import (
"github.com/omise/omise-go"
"github.com/omise/omise-go/operations"
)

func main() {
client, _ := omise.NewClient(
os.Getenv("OMISE_PUBLIC_KEY"),
os.Getenv("OMISE_SECRET_KEY"),
)

// Set API version
client.APIVersion = "2019-05-29"

charge, _ := client.CreateCharge(&operations.CreateCharge{
Amount: 100000,
Currency: "thb",
Card: token,
})
}

cURLโ€‹

# Specify version in header
curl https://api.omise.co/charges \
-u skey_test_...: \
-H "Omise-Version: 2019-05-29" \
-X POST \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_..."

Breaking vs Non-Breaking Changesโ€‹

Breaking Changesโ€‹

Breaking changes are only introduced in new API versions:

Examples:

  • Removing API endpoints
  • Removing response fields
  • Changing response field types
  • Changing required parameters
  • Changing error codes
  • Modifying behavior that affects existing flows

How Omise handles them:

  • โœ… Released as new version (new date)
  • โœ… Old version continues to work
  • โœ… You opt-in when ready
  • โœ… Migration guide provided

Non-Breaking Changesโ€‹

Non-breaking changes may be added to all versions:

Examples:

  • Adding new API endpoints
  • Adding new response fields
  • Adding new optional parameters
  • Adding new error codes
  • Adding new event types
  • Improving performance

How to handle:

  • โœ… Ignore unknown fields in responses
  • โœ… Don't rely on field order
  • โœ… Handle unexpected values gracefully
  • โœ… Test with production-like data
Forward Compatibility

Build your integration to handle new fields gracefully:

// โœ… Good - Ignores unknown fields
const { id, amount, status } = charge;

// โŒ Bad - Breaks if new fields added
const charge = { id, amount, status }; // Assumes only these fields

Version Historyโ€‹

2019-05-29 (Current)โ€‹

Released: May 29, 2019

Changes:

  • Enhanced source object structure
  • Improved error responses
  • Updated charge flow handling
  • Better webhook event payloads
  • Refined payment method objects

Migration from 2017-11-02:

  • Source objects have additional fields
  • Some charge status transitions refined
  • Event payloads include more context
  • Test all payment flows after upgrading

2017-11-02โ€‹

Released: November 2, 2017

Changes:

  • Introduced Sources API for alternative payments
  • Enhanced customer object
  • Improved dispute handling
  • Added schedule objects
  • Updated transfer logic

Migration from 2015-11-17:

  • Use sources instead of offsite for alternative payments
  • Update customer handling code
  • Review dispute webhooks
  • Test scheduled operations

2015-11-17โ€‹

Released: November 17, 2015

Legacy version - Still supported but missing newer features:

  • No sources API (uses older offsite method)
  • Limited payment methods
  • Older event structures

Recommendation: Upgrade to 2019-05-29 for best experience


Migration Guideโ€‹

Planning an Upgradeโ€‹

  1. Review changelog for new version
  2. Identify breaking changes affecting your integration
  3. Test in test mode with new version
  4. Update code to handle changes
  5. Test thoroughly before production
  6. Deploy to production during low-traffic period
  7. Monitor for issues
  8. Update account default when stable

Testing New Versionโ€‹

# Test new version in parallel with current version
def create_charge_v2019(params)
charge = Omise::Charge.create(
params,
{ 'Omise-Version' => '2019-05-29' }
)

# Log differences
logger.info("New version charge: #{charge.to_json}")

charge
end

def create_charge_current(params)
charge = Omise::Charge.create(
params,
{ 'Omise-Version' => '2017-11-02' }
)

logger.info("Current version charge: #{charge.to_json}")

charge
end

# Compare results
new_charge = create_charge_v2019(charge_params)
old_charge = create_charge_current(charge_params)

compare_charges(new_charge, old_charge)

Gradual Migrationโ€‹

// Use feature flags for gradual rollout
const useNewAPIVersion = featureFlags.isEnabled('api-version-2019');

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
omiseVersion: useNewAPIVersion ? '2019-05-29' : '2017-11-02'
});

// Monitor both versions
if (useNewAPIVersion) {
analytics.track('api_version_2019_used');
}

Version Detectionโ€‹

# Detect which version was used in response
def get_api_version_from_response(response_headers):
return response_headers.get('Omise-Version')

# Example
response = omise.Charge.retrieve('chrg_test_...')
version = get_api_version_from_response(response.headers)
print(f"Response from API version: {version}")

Deprecation Policyโ€‹

How Deprecation Worksโ€‹

  1. New version released with changes
  2. Old version continues working (no immediate impact)
  3. Deprecation announced via:
    • Email notifications
    • Dashboard notifications
    • API changelog
    • Developer documentation
  4. Migration period (typically 12+ months)
  5. End-of-life warnings (6 months before sunset)
  6. Version sunset (old version stops working)

Deprecation Timeline Exampleโ€‹

Month 0:  New version released (2019-05-29)
Old version (2017-11-02) still works

Month 1: Deprecation announced
Migration guide published

Month 6: Reminder notifications sent

Month 12: Final warning (6 months to sunset)

Month 18: Version 2017-11-02 sunset
Requests without version header use 2019-05-29

Checking for Deprecationsโ€‹

# Check response headers for deprecation warnings
curl -i https://api.omise.co/charges \
-u skey_test_...: \
-H "Omise-Version: 2017-11-02"

# Look for deprecation header
# Omise-Deprecated: true
# Omise-Sunset: 2025-12-31
# Omise-Recommended-Version: 2019-05-29

Best Practicesโ€‹

1. Pin API Version Explicitlyโ€‹

# โœ… Good - Explicit version
Omise.api_version = '2019-05-29'

# โŒ Bad - Relies on account default
Omise.api_version = nil # Uses account default

Why:

  • โœ… Prevents unexpected changes
  • โœ… Makes version clear in code
  • โœ… Easier to test upgrades
  • โœ… Consistent across environments

2. Use Environment Variablesโ€‹

// โœ… Good - Version in config
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
omiseVersion: process.env.OMISE_API_VERSION || '2019-05-29'
});

Benefits:

  • โœ… Easy to change without code deploy
  • โœ… Different versions per environment
  • โœ… Centralized configuration

3. Test Version Upgrades Thoroughlyโ€‹

# Test suite for version upgrade
class TestAPIVersion2019(unittest.TestCase):
def setUp(self):
omise.api_version = '2019-05-29'

def test_charge_creation(self):
charge = omise.Charge.create(
amount=100000,
currency='thb',
card=token
)
self.assertEqual(charge.amount, 100000)

def test_source_creation(self):
source = omise.Source.create(
type='promptpay',
amount=100000,
currency='thb'
)
self.assertIsNotNone(source.scannable_code)

def test_customer_with_card(self):
customer = omise.Customer.create(
email='test@example.com',
card=token
)
self.assertIsNotNone(customer.default_card)

4. Handle Unknown Fields Gracefullyโ€‹

// โœ… Good - Defensive parsing
function parseCharge(chargeData) {
return {
id: chargeData.id,
amount: chargeData.amount,
currency: chargeData.currency,
status: chargeData.status,
// Store unknown fields for future compatibility
_raw: chargeData
};
}

// โŒ Bad - Assumes fixed structure
function parseChargeBad(chargeData) {
const { id, amount, currency, status } = chargeData;
return { id, amount, currency, status };
// Breaks if structure changes
}

5. Monitor API Version Usageโ€‹

# Log API version for monitoring
class OmiseLogger
def self.log_request(endpoint, version)
Rails.logger.info({
event: 'omise_api_request',
endpoint: endpoint,
api_version: version,
timestamp: Time.now.iso8601
}.to_json)
end
end

# Use in requests
OmiseLogger.log_request('/charges', '2019-05-29')
charge = Omise::Charge.create(params)

6. Document Version in Codeโ€‹

<?php
/**
* Omise API Integration
*
* API Version: 2019-05-29
* Last Updated: 2025-01-15
* Migration Guide: https://docs.omise.co/api-versioning
*
* IMPORTANT: When upgrading API version:
* 1. Review changelog
* 2. Test all payment flows
* 3. Check webhook handlers
* 4. Update this comment
*/
class OmisePayment {
const API_VERSION = '2019-05-29';

public function createCharge($params) {
return OmiseCharge::create($params, [
'Omise-Version' => self::API_VERSION
]);
}
}

7. Version in CI/CDโ€‹

# .env.example
OMISE_API_VERSION=2019-05-29

# docker-compose.yml
version: '3.8'
services:
app:
environment:
- OMISE_API_VERSION=${OMISE_API_VERSION}

# GitHub Actions
- name: Run tests
env:
OMISE_API_VERSION: 2019-05-29
run: npm test

Version Upgrade Checklistโ€‹

Before upgrading to a new API version:

Pre-Upgradeโ€‹

  • Review complete changelog for new version
  • Identify all breaking changes
  • Check if your code uses deprecated features
  • Review migration guide
  • Update dependencies (SDK libraries)
  • Plan rollback strategy

Testingโ€‹

  • Test in test mode with new version header
  • Test all payment flows (cards, alternative payments)
  • Test customer creation and management
  • Test refund operations
  • Test transfer operations
  • Verify webhook payload handling
  • Test error handling
  • Load test critical paths
  • Compare responses with old version

Deploymentโ€‹

  • Update API version in code
  • Deploy to staging environment
  • Run smoke tests
  • Monitor error rates
  • Deploy to production (low-traffic period)
  • Monitor dashboards
  • Check webhook deliveries
  • Verify payment success rates

Post-Upgradeโ€‹

  • Monitor for 24-48 hours
  • Review logs for anomalies
  • Check error rates
  • Verify reporting accuracy
  • Update documentation
  • Update account default version (optional)
  • Document any code changes
  • Train team on changes

Troubleshooting Version Issuesโ€‹

Version Mismatch Errorsโ€‹

Problem: Unexpected behavior or errors after version change

Solution:

# Check which version is being used
def debug_api_version
# Make a test request
response = Omise::Account.retrieve

# Check response headers
version = response.http_headers['Omise-Version']
puts "API Version used: #{version}"

# Check client configuration
puts "Client version: #{Omise.api_version}"

# Check account default
puts "Check Dashboard Settings โ†’ API Version for account default"
end

Response Structure Differencesโ€‹

Problem: Fields missing or different type

Solution:

# Compare responses across versions
def compare_versions(operation_fn):
# Version 1
omise.api_version = '2017-11-02'
response_v1 = operation_fn()

# Version 2
omise.api_version = '2019-05-29'
response_v2 = operation_fn()

# Compare
print("Version 2017-11-02:")
print(json.dumps(response_v1, indent=2))

print("\nVersion 2019-05-29:")
print(json.dumps(response_v2, indent=2))

# Find differences
diff = deepdiff.DeepDiff(response_v1, response_v2)
print("\nDifferences:")
print(json.dumps(diff, indent=2))

# Usage
compare_versions(lambda: omise.Charge.retrieve('chrg_test_...'))

SDK Version Compatibilityโ€‹

Problem: SDK doesn't support new API version

Solution:

# Check SDK version
# Ruby
gem list omise

# Python
pip show omise

# Node.js
npm list omise

# Update to latest
# Ruby
gem update omise

# Python
pip install --upgrade omise

# Node.js
npm update omise

FAQโ€‹

What happens if I don't specify a version?

Your requests will use your account's default API version (set in Dashboard). This can lead to inconsistent behavior if the default changes. Always specify the version explicitly in your code.

Can I use different versions for different requests?

Yes! You can specify different versions per request using the Omise-Version header. This is useful during migration to test new version behavior alongside existing integration.

# Request 1 - Old version
curl -H "Omise-Version: 2017-11-02" ...

# Request 2 - New version
curl -H "Omise-Version: 2019-05-29" ...
How often are new versions released?

Omise releases new API versions infrequently - typically when significant improvements or necessary breaking changes are made. Versions are supported for years after release. The current version (2019-05-29) has been stable since 2019.

Do I need to upgrade immediately when a new version is released?

No. Your current version continues to work. You can upgrade on your own schedule:

  • Upgrade for new features
  • Upgrade before old version sunset
  • Upgrade during planned maintenance windows

You typically have 18+ months from deprecation announcement to upgrade.

Will my integration break if I don't upgrade?

Not immediately. Your integration will continue working on its current version. However:

  • You won't get new features
  • Eventually old versions are sunset (with 18+ months notice)
  • Security improvements may require upgrades

Plan regular version reviews (every 6-12 months).

How do I know when my version is deprecated?

Omise notifies you via:

  • Email to account owner
  • Dashboard notifications
  • Response headers (Omise-Deprecated: true)
  • API changelog
  • Developer documentation

Set up monitoring for deprecation headers in your logs.

Can I test a new version without affecting production?

Yes! Use the Omise-Version header:

  1. Keep production on current version (account default)
  2. Test new version in staging with header
  3. Run parallel tests comparing versions
  4. Upgrade production when ready
# Production (uses account default)
Omise::Charge.create(params)

# Staging (tests new version)
Omise::Charge.create(
params,
{ 'Omise-Version' => '2019-05-29' }
)

Quick Referenceโ€‹

Current Versionโ€‹

2019-05-29

Specify Versionโ€‹

# In header
curl -H "Omise-Version: 2019-05-29" ...

# In Ruby
Omise.api_version = '2019-05-29'

# In Python
omise.api_version = '2019-05-29'

# In Node.js
omise = require('omise')({ omiseVersion: '2019-05-29' })

# In PHP
define('OMISE_API_VERSION', '2019-05-29');

# In Go
client.APIVersion = "2019-05-29"

Version Formatโ€‹

YYYY-MM-DD (e.g., 2019-05-29)

Breaking Changesโ€‹

  • Only in new versions
  • Old versions stay stable
  • You control upgrade timing
  • Migration guide provided

Non-Breaking Changesโ€‹

  • May be added to all versions
  • New fields, endpoints, features
  • Handle unknown fields gracefully
  • Build forward-compatible code


Next: Learn about Rate Limiting to stay within API limits and handle rate limit errors.