メインコンテンツへスキップ

Dart SDK

The Omise Dart SDK provides a comprehensive server-side integration for the Omise payment API. Built for backend services, cloud functions, and CLI tools, it offers full API access with type-safe request/response models and async support.

Overview

The Dart SDK enables you to:

  • Full API access - Complete control over charges, customers, cards, and more
  • Server-side operations - Create charges, manage customers, handle refunds
  • Type-safe models - Fully typed request and response objects
  • Async/await support - Modern Dart async patterns
  • Null safety - Built with sound null safety
  • Webhook handling - Verify and process webhook events
  • Error handling - Comprehensive exception types

Key Features

  • Null-safe Dart 2.12+ API
  • Future-based async operations
  • Complete API coverage
  • Type-safe request builders
  • Webhook signature verification
  • Automatic request retry logic
  • Custom HTTP client support
  • Comprehensive error handling

要件

  • Dart 2.12 or later (null safety)
  • Server-side or CLI application
  • Not suitable for client-side/browser use (requires secret key)

インストール

Add to pubspec.yaml

dependencies:
omise_dart: ^3.0.0

Install Package

dart pub add omise_dart

Or manually:

dart pub get

クイックスタート

1. Import the Package

import 'package:omise_dart/omise_dart.dart';

2. Initialize the Client

void main() async {
final omise = Omise(
publicKey: 'pkey_test_5xyzyx5xyzyx5xyzyx5',
secretKey: 'skey_test_5xyzyx5xyzyx5xyzyx5',
);
}

3. Create a Charge

Future<void> createCharge() async {
final omise = Omise(
publicKey: 'pkey_test_5xyzyx5xyzyx5xyzyx5',
secretKey: 'skey_test_5xyzyx5xyzyx5xyzyx5',
);

try {
final charge = await omise.charges.create(
amount: 100000, // 1,000.00 THB
currency: 'thb',
card: 'tokn_test_5xyzyx5xyzyx5xyzyx5',
description: 'Order #1234',
metadata: {
'order_id': '1234',
'customer_email': 'john@example.com',
},
);

print('Charge created: ${charge.id}');
print('Status: ${charge.status}');

if (charge.paid) {
print('Payment successful!');
}

} catch (error) {
print('Error: $error');
}
}

構成

Client Configuration

// Basic configuration
final omise = Omise(
publicKey: 'pkey_test_5xyzyx5xyzyx5xyzyx5',
secretKey: 'skey_test_5xyzyx5xyzyx5xyzyx5',
);

// Advanced configuration
final omise = Omise(
publicKey: 'pkey_test_5xyzyx5xyzyx5xyzyx5',
secretKey: 'skey_test_5xyzyx5xyzyx5xyzyx5',
apiVersion: '2019-05-29',
timeout: Duration(seconds: 60),
debugMode: true,
);

Environment-based Configuration

import 'dart:io';

class Config {
static String get publicKey {
return Platform.environment['OMISE_PUBLIC_KEY'] ??
'pkey_test_5xyzyx5xyzyx5xyzyx5';
}

static String get secretKey {
return Platform.environment['OMISE_SECRET_KEY'] ??
'skey_test_5xyzyx5xyzyx5xyzyx5';
}
}

final omise = Omise(
publicKey: Config.publicKey,
secretKey: Config.secretKey,
);

Custom HTTP Client

import 'package:http/http.dart' as http;

final customClient = http.Client();

final omise = Omise(
publicKey: 'pkey_test_...',
secretKey: 'skey_test_...',
httpClient: customClient,
);

// Don't forget to close the client when done
void cleanup() {
customClient.close();
}

Charges

Create a Charge

// Charge a card token
Future<Charge> chargeCard(String tokenId, int amount) async {
return await omise.charges.create(
amount: amount,
currency: 'thb',
card: tokenId,
description: 'Payment for order',
returnUri: 'https://example.com/payment/callback',
);
}

// Charge a customer's default card
Future<Charge> chargeCustomer(String customerId, int amount) async {
return await omise.charges.create(
amount: amount,
currency: 'thb',
customer: customerId,
description: 'Subscription payment',
);
}

// Charge with a source
Future<Charge> chargeSource(String sourceId, int amount) async {
return await omise.charges.create(
amount: amount,
currency: 'thb',
source: sourceId,
returnUri: 'https://example.com/payment/callback',
);
}

Create Charge with Metadata

Future<Charge> createChargeWithMetadata() async {
return await omise.charges.create(
amount: 100000,
currency: 'thb',
card: 'tokn_test_5xyzyx5xyzyx5xyzyx5',
description: 'Order #1234',
metadata: {
'order_id': '1234',
'customer_email': 'john@example.com',
'customer_name': 'John Doe',
'shipping_method': 'express',
},
);
}

Retrieve a Charge

Future<Charge> getCharge(String chargeId) async {
return await omise.charges.retrieve(chargeId);
}

// Check charge status
Future<void> checkChargeStatus(String chargeId) async {
final charge = await omise.charges.retrieve(chargeId);

print('Charge ID: ${charge.id}');
print('Status: ${charge.status}');
print('Paid: ${charge.paid}');
print('Amount: ${charge.amount}');

if (charge.authorized) {
print('Charge is authorized');
}

if (charge.captured) {
print('Charge is captured');
}

if (charge.reversed) {
print('Charge is reversed');
}
}

List Charges

Future<ChargeList> listCharges({
int limit = 20,
int offset = 0,
}) async {
return await omise.charges.list(
limit: limit,
offset: offset,
);
}

// List all charges
Future<void> listAllCharges() async {
var offset = 0;
const limit = 100;

while (true) {
final charges = await omise.charges.list(
limit: limit,
offset: offset,
);

for (final charge in charges.data) {
print('Charge: ${charge.id} - ${charge.amount}');
}

if (charges.data.length < limit) break;
offset += limit;
}
}

Update a Charge

Future<Charge> updateCharge(String chargeId) async {
return await omise.charges.update(
chargeId,
description: 'Updated description',
metadata: {
'updated_at': DateTime.now().toIso8601String(),
},
);
}

Capture a Charge

Future<Charge> captureCharge(String chargeId) async {
return await omise.charges.capture(chargeId);
}

// Partial capture
Future<Charge> partialCapture(String chargeId, int amount) async {
return await omise.charges.capture(
chargeId,
captureAmount: amount,
);
}

Reverse a Charge

Future<Charge> reverseCharge(String chargeId) async {
return await omise.charges.reverse(chargeId);
}

Customers

Create a Customer

Future<Customer> createCustomer({
required String email,
String? description,
Map<String, dynamic>? metadata,
}) async {
return await omise.customers.create(
email: email,
description: description,
metadata: metadata,
);
}

// 使用方法
final customer = await createCustomer(
email: 'john@example.com',
description: 'John Doe',
metadata: {
'phone': '+66812345678',
'address': '123 Wireless Road, Bangkok',
},
);

Retrieve a Customer

Future<Customer> getCustomer(String customerId) async {
return await omise.customers.retrieve(customerId);
}

Update a Customer

Future<Customer> updateCustomer(String customerId) async {
return await omise.customers.update(
customerId,
email: 'newemail@example.com',
description: 'Updated customer',
metadata: {
'last_updated': DateTime.now().toIso8601String(),
},
);
}

List Customers

Future<CustomerList> listCustomers({
int limit = 20,
int offset = 0,
}) async {
return await omise.customers.list(
limit: limit,
offset: offset,
);
}

Delete a Customer

Future<DeletedCustomer> deleteCustomer(String customerId) async {
return await omise.customers.delete(customerId);
}

Cards

Create a Card

Future<Card> addCardToCustomer(
String customerId,
String tokenId,
) async {
return await omise.customers.cards.create(
customerId,
card: tokenId,
);
}

List Customer Cards

Future<CardList> listCustomerCards(String customerId) async {
return await omise.customers.cards.list(customerId);
}

// Get default card
Future<Card?> getDefaultCard(String customerId) async {
final customer = await omise.customers.retrieve(customerId);

if (customer.defaultCard != null) {
return await omise.customers.cards.retrieve(
customerId,
customer.defaultCard!,
);
}

return null;
}

Update a Card

Future<Card> updateCard(
String customerId,
String cardId, {
String? name,
int? expirationMonth,
int? expirationYear,
}) async {
return await omise.customers.cards.update(
customerId,
cardId,
name: name,
expirationMonth: expirationMonth,
expirationYear: expirationYear,
);
}

Delete a Card

Future<DeletedCard> deleteCard(
String customerId,
String cardId,
) async {
return await omise.customers.cards.delete(customerId, cardId);
}

Refunds

Create a Refund

Future<Refund> createRefund(String chargeId) async {
// 全額返金
return await omise.refunds.create(chargeId);
}

// 部分払い戻し
Future<Refund> partialRefund(String chargeId, int amount) async {
return await omise.refunds.create(
chargeId,
amount: amount,
);
}

// Refund with metadata
Future<Refund> refundWithReason(
String chargeId,
String reason,
) async {
return await omise.refunds.create(
chargeId,
metadata: {
'reason': reason,
'refunded_by': 'system',
'refunded_at': DateTime.now().toIso8601String(),
},
);
}

Retrieve a Refund

Future<Refund> getRefund(String chargeId, String refundId) async {
return await omise.refunds.retrieve(chargeId, refundId);
}

List Refunds

Future<RefundList> listRefunds(String chargeId) async {
return await omise.refunds.list(chargeId);
}

// List all refunds for a charge
Future<void> listAllRefunds(String chargeId) async {
final refunds = await omise.refunds.list(chargeId);

for (final refund in refunds.data) {
print('Refund: ${refund.id}');
print('Amount: ${refund.amount}');
print('Status: ${refund.status}');
}
}

Sources

Create a Source

// インターネットバンキング
Future<Source> createInternetBankingSource(int amount) async {
return await omise.sources.create(
amount: amount,
currency: 'thb',
type: 'internet_banking_bay',
);
}

// PromptPay
Future<Source> createPromptPaySource(int amount) async {
return await omise.sources.create(
amount: amount,
currency: 'thb',
type: 'promptpay',
);
}

// TrueMoney Wallet
Future<Source> createTrueMoneySource(
int amount,
String phoneNumber,
) async {
return await omise.sources.create(
amount: amount,
currency: 'thb',
type: 'truemoney',
phoneNumber: phoneNumber,
);
}

// インストール
Future<Source> createInstallmentSource(
int amount,
int installmentTerms,
) async {
return await omise.sources.create(
amount: amount,
currency: 'thb',
type: 'installment_bay',
installmentTerms: installmentTerms,
);
}

Retrieve a Source

Future<Source> getSource(String sourceId) async {
return await omise.sources.retrieve(sourceId);
}

// Poll source until it's paid
Future<Source> waitForSourcePayment(
String sourceId, {
Duration interval = const Duration(seconds: 3),
Duration timeout = const Duration(minutes: 10),
}) async {
final deadline = DateTime.now().add(timeout);

while (DateTime.now().isBefore(deadline)) {
final source = await omise.sources.retrieve(sourceId);

if (source.status == 'successful' || source.status == 'failed') {
return source;
}

await Future.delayed(interval);
}

throw TimeoutException('Source payment timeout');
}

Tokens

Create a Token

// Note: Tokens should be created client-side for PCI compliance
// This is only for server-to-server scenarios

Future<Token> createToken({
required String name,
required String number,
required int expirationMonth,
required int expirationYear,
required String securityCode,
}) async {
return await omise.tokens.create(
name: name,
number: number,
expirationMonth: expirationMonth,
expirationYear: expirationYear,
securityCode: securityCode,
);
}

Retrieve a Token

Future<Token> getToken(String tokenId) async {
return await omise.tokens.retrieve(tokenId);
}

Transfers

Create a Transfer

Future<Transfer> createTransfer(int amount) async {
return await omise.transfers.create(
amount: amount,
);
}

// Transfer with recipient
Future<Transfer> transferToRecipient(
String recipientId,
int amount,
) async {
return await omise.transfers.create(
amount: amount,
recipient: recipientId,
);
}

Retrieve a Transfer

Future<Transfer> getTransfer(String transferId) async {
return await omise.transfers.retrieve(transferId);
}

List Transfers

Future<TransferList> listTransfers({
int limit = 20,
int offset = 0,
}) async {
return await omise.transfers.list(
limit: limit,
offset: offset,
);
}

Update a Transfer

Future<Transfer> updateTransfer(String transferId) async {
return await omise.transfers.update(
transferId,
amount: 50000, // Update transfer amount
);
}

Destroy a Transfer

Future<DeletedTransfer> deleteTransfer(String transferId) async {
return await omise.transfers.destroy(transferId);
}

Recipients

Create a Recipient

Future<Recipient> createRecipient({
required String name,
required String email,
required String type,
required Map<String, dynamic> bankAccount,
}) async {
return await omise.recipients.create(
name: name,
email: email,
type: type,
bankAccount: bankAccount,
);
}

// 使用方法
final recipient = await createRecipient(
name: 'John Doe',
email: 'john@example.com',
type: 'individual',
bankAccount: {
'brand': 'bbl',
'number': '1234567890',
'name': 'John Doe',
},
);

Retrieve a Recipient

Future<Recipient> getRecipient(String recipientId) async {
return await omise.recipients.retrieve(recipientId);
}

List Recipients

Future<RecipientList> listRecipients({
int limit = 20,
int offset = 0,
}) async {
return await omise.recipients.list(
limit: limit,
offset: offset,
);
}

Update a Recipient

Future<Recipient> updateRecipient(String recipientId) async {
return await omise.recipients.update(
recipientId,
name: 'Updated Name',
email: 'newemail@example.com',
);
}

Delete a Recipient

Future<DeletedRecipient> deleteRecipient(String recipientId) async {
return await omise.recipients.delete(recipientId);
}

Webhooks

Verify Webhook Signature

import 'dart:convert';
import 'package:crypto/crypto.dart';

class WebhookHandler {
final String secretKey;

WebhookHandler(this.secretKey);

bool verifySignature(String payload, String signature) {
final hmac = Hmac(sha256, utf8.encode(secretKey));
final digest = hmac.convert(utf8.encode(payload));
final expectedSignature = base64.encode(digest.bytes);

return signature == expectedSignature;
}

WebhookEvent parseEvent(String payload) {
final json = jsonDecode(payload);
return WebhookEvent.fromJson(json);
}
}

// 使用方法 with shelf (Dart web server)
import 'package:shelf/shelf.dart';

Response handleWebhook(Request request) async {
final payload = await request.readAsString();
final signature = request.headers['x-omise-signature'];

if (signature == null) {
return Response.unauthorized('Missing signature');
}

final handler = WebhookHandler('skey_test_...');

if (!handler.verifySignature(payload, signature)) {
return Response.unauthorized('Invalid signature');
}

final event = handler.parseEvent(payload);
await processWebhookEvent(event);

return Response.ok('OK');
}

Handle Webhook Events

Future<void> processWebhookEvent(WebhookEvent event) async {
print('Received event: ${event.key}');

switch (event.key) {
case 'charge.complete':
await handleChargeComplete(event.data as Charge);
break;

case 'charge.create':
await handleChargeCreate(event.data as Charge);
break;

case 'refund.create':
await handleRefundCreate(event.data as Refund);
break;

case 'transfer.create':
await handleTransferCreate(event.data as Transfer);
break;

default:
print('Unhandled event type: ${event.key}');
}
}

Future<void> handleChargeComplete(Charge charge) async {
print('Charge completed: ${charge.id}');

if (charge.paid) {
// Update order status in your database
await updateOrderStatus(
charge.metadata['order_id'],
'paid',
);

// Send confirmation email
await sendConfirmationEmail(
charge.metadata['customer_email'],
charge.id,
);
}
}

エラーハンドリング

Exception Types

Future<void> handlePayment() async {
try {
final charge = await omise.charges.create(
amount: 100000,
currency: 'thb',
card: 'tokn_test_...',
);

print('Charge created: ${charge.id}');

} on OmiseException catch (e) {
// API error from Omise
print('API Error: ${e.message}');
print('Code: ${e.code}');
print('Status: ${e.statusCode}');

} on NetworkException catch (e) {
// Network connectivity error
print('Network Error: ${e.message}');

} on AuthenticationException catch (e) {
// Invalid API keys
print('Authentication Error: ${e.message}');

} catch (e) {
// Unknown error
print('Unknown Error: $e');
}
}

Handle Specific Error Codes

Future<Charge> createChargeWithErrorHandling(
String tokenId,
int amount,
) async {
try {
return await omise.charges.create(
amount: amount,
currency: 'thb',
card: tokenId,
);

} on OmiseException catch (e) {
switch (e.code) {
case 'invalid_card':
throw PaymentException('Invalid card details');

case 'insufficient_fund':
throw PaymentException('Insufficient funds');

case 'failed_processing':
throw PaymentException('Payment processing failed');

case 'invalid_security_code':
throw PaymentException('Invalid CVV');

case 'stolen_or_lost_card':
throw PaymentException('Card reported stolen or lost');

default:
throw PaymentException('Payment failed: ${e.message}');
}
}
}

class PaymentException implements Exception {
final String message;
PaymentException(this.message);

@override
String toString() => message;
}

Retry Logic

Future<Charge> createChargeWithRetry({
required String tokenId,
required int amount,
int maxAttempts = 3,
Duration delay = const Duration(seconds: 1),
}) async {
int attempts = 0;

while (attempts < maxAttempts) {
try {
return await omise.charges.create(
amount: amount,
currency: 'thb',
card: tokenId,
);

} on NetworkException catch (e) {
attempts++;

if (attempts >= maxAttempts) {
rethrow;
}

print('Attempt $attempts failed, retrying...');
await Future.delayed(delay * attempts);

} on OmiseException catch (e) {
// Don't retry on API errors
rethrow;
}
}

throw Exception('Max retry attempts reached');
}

ベストプラクティス

Security

// ✅ DO: Use environment variables
final omise = Omise(
publicKey: Platform.environment['OMISE_PUBLIC_KEY']!,
secretKey: Platform.environment['OMISE_SECRET_KEY']!,
);

// ❌ DON'T: Hardcode API keys
// final omise = Omise(
// publicKey: 'pkey_...',
// secretKey: 'skey_...',
// );

// ✅ DO: Validate input
Future<Charge> createCharge(Map<String, dynamic> data) async {
final amount = data['amount'] as int?;
if (amount == null || amount <= 0) {
throw ArgumentError('Invalid amount');
}

return await omise.charges.create(
amount: amount,
currency: 'thb',
card: data['token'] as String,
);
}

// ✅ DO: Use HTTPS only
// The SDK enforces HTTPS connections

// ❌ DON'T: Log sensitive data
// print('Card: ${card.number}');

// ✅ DO: Use sanitized logging
print('Charge created: ${charge.id}');

Performance

// ✅ DO: Reuse the client
class Paymentサービス {
static final Paymentサービス _instance = Paymentサービス._internal();
factory Paymentサービス() => _instance;

late final Omise omise;

Paymentサービス._internal() {
omise = Omise(
publicKey: Config.publicKey,
secretKey: Config.secretKey,
);
}
}

// ✅ DO: Use pagination for large lists
Future<List<Charge>> getAllCharges() async {
final allCharges = <Charge>[];
var offset = 0;
const limit = 100;

while (true) {
final charges = await omise.charges.list(
limit: limit,
offset: offset,
);

allCharges.addAll(charges.data);

if (charges.data.length < limit) break;
offset += limit;
}

return allCharges;
}

// ✅ DO: Cache frequently accessed data
class CachedCustomerサービス {
final Omise omise;
final Map<String, Customer> _cache = {};

CachedCustomerサービス(this.omise);

Future<Customer> getCustomer(String id) async {
if (_cache.containsKey(id)) {
return _cache[id]!;
}

final customer = await omise.customers.retrieve(id);
_cache[id] = customer;
return customer;
}
}

エラーハンドリング

// ✅ DO: Handle errors gracefully
Future<Charge?> createChargeWithFallback(
String tokenId,
int amount,
) async {
try {
return await omise.charges.create(
amount: amount,
currency: 'thb',
card: tokenId,
);

} on OmiseException catch (e) {
logger.error('Payment failed', error: e);
await notifyAdmins(e);
return null;

} on NetworkException catch (e) {
logger.error('Network error', error: e);
await queueForRetry(tokenId, amount);
return null;
}
}

// ✅ DO: Validate webhook signatures
Future<void> handleWebhook(Request request) async {
final signature = request.headers['x-omise-signature'];

if (signature == null) {
throw UnauthorizedException('Missing signature');
}

final payload = await request.readAsString();

if (!verifySignature(payload, signature)) {
throw UnauthorizedException('Invalid signature');
}

await processWebhook(payload);
}

テスト

Unit テスト

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';

class MockOmise extends Mock implements Omise {}

void main() {
group('Payment Tests', () {
late MockOmise mockOmise;

setUp(() {
mockOmise = MockOmise();
});

test('createCharge returns charge on success', () async {
// Arrange
final expectedCharge = Charge(
id: 'chrg_test_123',
amount: 100000,
currency: 'thb',
status: 'successful',
paid: true,
);

when(mockOmise.charges.create(
amount: anyNamed('amount'),
currency: anyNamed('currency'),
card: anyNamed('card'),
)).thenAnswer((_) async => expectedCharge);

// Act
final charge = await mockOmise.charges.create(
amount: 100000,
currency: 'thb',
card: 'tokn_test_123',
);

// Assert
expect(charge.id, equals('chrg_test_123'));
expect(charge.paid, isTrue);
});

test('createCharge throws on invalid card', () async {
// Arrange
when(mockOmise.charges.create(
amount: anyNamed('amount'),
currency: anyNamed('currency'),
card: anyNamed('card'),
)).thenThrow(
OmiseException('invalid_card', 'Invalid card'),
);

// Act & Assert
expect(
() => mockOmise.charges.create(
amount: 100000,
currency: 'thb',
card: 'tokn_invalid',
),
throwsA(isA<OmiseException>()),
);
});
});
}

Integration テスト

import 'package:test/test.dart';

void main() {
group('Integration Tests', () {
late Omise omise;

setUp(() {
omise = Omise(
publicKey: 'pkey_test_5xyzyx5xyzyx5xyzyx5',
secretKey: 'skey_test_5xyzyx5xyzyx5xyzyx5',
);
});

test('create and retrieve charge', () async {
// Create token
final token = await omise.tokens.create(
name: 'Test User',
number: '4242424242424242',
expirationMonth: 12,
expirationYear: 2025,
securityCode: '123',
);

// Create charge
final charge = await omise.charges.create(
amount: 100000,
currency: 'thb',
card: token.id,
);

expect(charge.id, isNotEmpty);
expect(charge.amount, equals(100000));

// Retrieve charge
final retrieved = await omise.charges.retrieve(charge.id);
expect(retrieved.id, equals(charge.id));
});
});
}

トラブルシューティング

Common Issues

Issue: "Authentication failed" error

// Solution: Check your API keys
final omise = Omise(
publicKey: 'pkey_test_...', // Must start with pkey_
secretKey: 'skey_test_...', // Must start with skey_
);

Issue: Network timeout errors

// Solution: Increase timeout
final omise = Omise(
publicKey: 'pkey_test_...',
secretKey: 'skey_test_...',
timeout: Duration(seconds: 60),
);

Issue: SSL certificate errors

// Solution: Ensure system certificates are up to date
// For development only:
// import 'dart:io';
// HttpOverrides.global = DevHttpOverrides();

Issue: "Invalid charge" error

// Solution: Ensure amount is in smallest currency unit
final amount = 100000; // 1,000.00 THB (not 1000.00)

final charge = await omise.charges.create(
amount: amount,
currency: 'thb',
card: tokenId,
);

Frequently Asked Questions

Can I use this SDK in Flutter apps?

This SDK is designed for server-side use only as it requires your secret key. For Flutter apps, use the Flutter SDK which only requires your public key.

How do I handle idempotency?

Use the idempotency key parameter to ensure operations are not duplicated:

final charge = await omise.charges.create(
amount: 100000,
currency: 'thb',
card: tokenId,
idempotencyKey: 'order_1234_payment',
);

Can I use this with cloud functions?

Yes, the SDK works great with cloud functions (Firebase, AWS Lambda, etc.):

// Firebase Cloud Function
import 'package:functions_framework/functions_framework.dart';

@CloudFunction()
Future<Response> handlePayment(Request request) async {
final omise = Omise(
publicKey: Platform.environment['OMISE_PUBLIC_KEY']!,
secretKey: Platform.environment['OMISE_SECRET_KEY']!,
);

final body = await request.readAsString();
final data = jsonDecode(body);

final charge = await omise.charges.create(
amount: data['amount'],
currency: 'thb',
card: data['token'],
);

return Response.ok(jsonEncode(charge.toJson()));
}

How do I test webhooks locally?

Use a tool like ngrok to expose your local server:

dart run bin/server.dart
ngrok http 8080

Then configure the ngrok URL in your Omise dashboard.

Can I batch operations?

The SDK doesn't provide built-in batching, but you can use Future.wait:

final charges = await Future.wait([
omise.charges.create(amount: 10000, currency: 'thb', card: token1),
omise.charges.create(amount: 20000, currency: 'thb', card: token2),
omise.charges.create(amount: 30000, currency: 'thb', card: token3),
]);

How do I handle rate limiting?

Implement exponential backoff:

Future<T> withRetry<T>(Future<T> Function() operation) async {
var delay = Duration(seconds: 1);
var attempts = 0;
const maxAttempts = 5;

while (attempts < maxAttempts) {
try {
return await operation();
} on OmiseException catch (e) {
if (e.statusCode == 429) { // Rate limited
attempts++;
if (attempts >= maxAttempts) rethrow;
await Future.delayed(delay);
delay *= 2;
} else {
rethrow;
}
}
}

throw Exception('Max retries exceeded');
}

Can I use this SDK with multiple accounts?

Yes, create multiple client instances:

final omise1 = Omise(
publicKey: 'pkey_account1_...',
secretKey: 'skey_account1_...',
);

final omise2 = Omise(
publicKey: 'pkey_account2_...',
secretKey: 'skey_account2_...',
);

関連リソース

次のステップ

  1. Set up your account to get your API keys
  2. Configure webhooks to receive payment updates
  3. Test your integration with test mode
  4. Go live with production keys

サポート

Need help with the Dart SDK?