Skip to main content

Node.js Library (omise-node)

The omise-node library provides a modern Node.js interface to the Omise API with TypeScript definitions, Promise/async-await support, and excellent Express and NestJS integration.

Installationโ€‹

Using npmโ€‹

npm install omise

Using Yarnโ€‹

yarn add omise

Using pnpmโ€‹

pnpm add omise

Requirementsโ€‹

  • Node.js 12 or higher (Node.js 16+ recommended as Node.js 12 reached EOL in April 2022)
  • npm, yarn, or pnpm for package management
  • TypeScript 4.0+ (optional, for TypeScript projects)

Quick Startโ€‹

Basic Configurationโ€‹

const omise = require('omise')({
secretKey: 'skey_test_123456789',
publicKey: 'pkey_test_123456789',
omiseVersion: '2019-05-29'
});

TypeScript Configurationโ€‹

The omise-node library includes built-in TypeScript definitions - no separate @types/omise package is needed.

import Omise from 'omise';

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

// Type-safe API calls
import type { Charges, Tokens } from 'omise';

// Charges have full type inference
const charge: Charges.ICharge = await omise.charges.create({
amount: 100000,
currency: 'thb',
card: 'tokn_test_123'
});

// Token responses are fully typed
const token: Tokens.IToken = await omise.tokens.create({
card: {
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2027,
security_code: '123',
name: 'JOHN DOE'
}
});

TypeScript Features:

  • โœ… Built-in type definitions (no @types package needed)
  • โœ… Full IntelliSense support in VS Code
  • โœ… Type-safe request/response objects
  • โœ… Enum types for payment methods, currencies, statuses
  • โœ… Strict null checking support
  • โœ… Generic type parameters for advanced usage

Type Definitions Location: The official TypeScript definitions are maintained in the omise-node repository.

Express Configurationโ€‹

// config/omise.js
require('dotenv').config();

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

Environment Variablesโ€‹

Create a .env file:

# Development/Test
OMISE_SECRET_KEY=skey_test_123456789
OMISE_PUBLIC_KEY=pkey_test_123456789

# Production
# OMISE_SECRET_KEY=skey_live_123456789
# OMISE_PUBLIC_KEY=pkey_live_123456789

Common Operationsโ€‹

Creating a Chargeโ€‹

With Promisesโ€‹

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

omise.charges.create({
amount: 100000, // 1,000.00 THB
currency: 'THB',
card: 'tokn_test_123',
description: 'Order #1234',
metadata: {
order_id: '1234',
customer_name: 'John Doe'
}
})
.then(charge => {
if (charge.paid) {
console.log(`Charge successful: ${charge.id}`);
} else {
console.log(`Charge failed: ${charge.failure_message}`);
}
})
.catch(err => {
console.error('Error:', err.message);
});

With Async/Awaitโ€‹

async function createCharge(token, amount) {
try {
const charge = await omise.charges.create({
amount,
currency: 'THB',
card: token,
description: 'Order #1234',
metadata: {
order_id: '1234',
customer_name: 'John Doe'
}
});

if (charge.paid) {
console.log(`Charge successful: ${charge.id}`);
return charge;
} else {
throw new Error(charge.failure_message);
}
} catch (error) {
console.error('Charge failed:', error);
throw error;
}
}

With TypeScriptโ€‹

interface ChargeMetadata {
order_id: string;
customer_name: string;
}

interface CreateChargeParams {
amount: number;
currency: string;
card: string;
metadata: ChargeMetadata;
}

async function createCharge(params: CreateChargeParams): Promise<Omise.Charges.ICharge> {
const charge = await omise.charges.create({
amount: params.amount,
currency: params.currency,
card: params.card,
metadata: params.metadata
});

return charge;
}

With 3D Secureโ€‹

async function createSecureCharge(token, amount, returnUri) {
const charge = await omise.charges.create({
amount,
currency: 'THB',
card: token,
return_uri: returnUri
});

if (charge.authorized) {
if (charge.authorize_uri) {
// Redirect customer to authorize_uri for 3D Secure
return { redirect: charge.authorize_uri };
} else {
// Charge completed without 3D Secure
return { success: true, charge };
}
}

throw new Error(charge.failure_message);
}

Retrieving a Chargeโ€‹

// Promise-based
omise.charges.retrieve('chrg_test_123')
.then(charge => {
console.log(`Amount: ${charge.amount}`);
console.log(`Currency: ${charge.currency}`);
console.log(`Status: ${charge.status}`);
});

// Async/await
async function getCharge(chargeId) {
const charge = await omise.charges.retrieve(chargeId);
return charge;
}

Listing Chargesโ€‹

async function listCharges(options = {}) {
const charges = await omise.charges.list({
limit: 20,
offset: 0,
order: 'reverse_chronological',
...options
});

charges.data.forEach(charge => {
console.log(`${charge.id}: ${charge.amount} ${charge.currency}`);
});

return charges;
}

// List charges with date filter
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const charges = await omise.charges.list({
from: weekAgo.toISOString().split('T')[0],
to: new Date().toISOString().split('T')[0]
});

Creating a Customerโ€‹

async function createCustomer(email, description, metadata = {}) {
const customer = await omise.customers.create({
email,
description,
metadata
});

console.log(`Customer created: ${customer.id}`);
return customer;
}

// Usage
const customer = await createCustomer(
'customer@example.com',
'John Doe',
{ user_id: '12345', account_type: 'premium' }
);

Saving a Card to a Customerโ€‹

// Update customer with card token
async function addCardToCustomer(customerId, token) {
const customer = await omise.customers.update(customerId, {
card: token
});

console.log(`Card saved: ${customer.default_card}`);
return customer;
}

// Create customer with card
async function createCustomerWithCard(email, token) {
const customer = await omise.customers.create({
email,
card: token
});

return customer;
}

Listing Customer Cardsโ€‹

async function listCustomerCards(customerId) {
const customer = await omise.customers.retrieve(customerId);

customer.cards.data.forEach(card => {
console.log(`${card.brand} ending in ${card.last_digits}`);
console.log(`Expires: ${card.expiration_month}/${card.expiration_year}`);
});

return customer.cards.data;
}

Creating a Refundโ€‹

// Full refund
async function refundCharge(chargeId) {
const refund = await omise.charges.refund(chargeId);
return refund;
}

// Partial refund
async function partialRefund(chargeId, amount, metadata = {}) {
const refund = await omise.charges.refund(chargeId, {
amount,
metadata
});

console.log(`Refund ${refund.id}: ${refund.amount} ${refund.currency}`);
return refund;
}

// Usage
await partialRefund('chrg_test_123', 25000, {
reason: 'customer_request',
ticket_id: 'TICKET-123'
});

Creating a Transferโ€‹

async function createTransfer(amount, recipientId, metadata = {}) {
const transfer = await omise.transfers.create({
amount,
recipient: recipientId,
metadata
});

console.log(`Transfer ${transfer.id}: ${transfer.amount}`);
return transfer;
}

Alternative Payment Methodsโ€‹

Creating a Sourceโ€‹

// Prompt Pay QR
async function createPromptPaySource(amount) {
const source = await omise.sources.create({
type: 'promptpay',
amount,
currency: 'THB'
});

console.log(`QR Code URL: ${source.scannable_code.image.download_uri}`);

// Create charge with source
const charge = await omise.charges.create({
amount,
currency: 'THB',
source: source.id,
return_uri: 'https://example.com/payment/callback'
});

return { source, charge };
}

Internet Bankingโ€‹

async function createInternetBankingCharge(amount, bankCode = 'scb') {
const source = await omise.sources.create({
type: `internet_banking_${bankCode}`,
amount,
currency: 'THB'
});

const charge = await omise.charges.create({
amount,
currency: 'THB',
source: source.id,
return_uri: 'https://example.com/payment/callback'
});

// Return authorize_uri for redirect
return charge.authorize_uri;
}

Installmentsโ€‹

async function createInstallmentCharge(amount, bank, term) {
const source = await omise.sources.create({
type: `installment_${bank}`,
amount,
currency: 'THB',
installment_term: term
});

const charge = await omise.charges.create({
amount,
currency: 'THB',
source: source.id,
return_uri: 'https://example.com/payment/callback'
});

return charge;
}

// Usage
const charge = await createInstallmentCharge(100000, 'kbank', 6);

Error Handlingโ€‹

const { OmiseError } = require('omise');

async function createChargeWithErrorHandling(params) {
try {
const charge = await omise.charges.create(params);
return charge;
} catch (error) {
if (error instanceof OmiseError) {
console.error('Omise Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Error Code:', error.code);

// Handle specific errors
switch (error.code) {
case 'authentication_failure':
throw new Error('Invalid API key');
case 'invalid_card':
throw new Error('Card was declined');
case 'insufficient_fund':
throw new Error('Insufficient funds');
default:
throw error;
}
}

// Network or other errors
throw error;
}
}

TypeScript Error Handlingโ€‹

import Omise, { OmiseError } from 'omise';

async function handleChargeError(error: unknown): Promise<never> {
if (error instanceof OmiseError) {
const errorMessages: Record<string, string> = {
insufficient_fund: 'Insufficient funds on card',
stolen_or_lost_card: 'Card reported as stolen or lost',
invalid_security_code: 'Invalid CVV code',
payment_cancelled: 'Payment was cancelled'
};

const message = errorMessages[error.code] || error.message;
throw new Error(message);
}

throw error;
}

Express Integrationโ€‹

Controller Exampleโ€‹

// controllers/paymentController.js
const omise = require('../config/omise');
const Order = require('../models/Order');
const Payment = require('../models/Payment');

exports.createPayment = async (req, res) => {
try {
const { orderId } = req.params;
const { omiseToken } = req.body;

const order = await Order.findById(orderId);
if (!order) {
return res.status(404).json({ error: 'Order not found' });
}

const charge = await omise.charges.create({
amount: Math.round(order.total * 100),
currency: 'THB',
card: omiseToken,
description: `Order #${order.id}`,
metadata: {
order_id: order.id,
customer_email: order.email
},
return_uri: `${req.protocol}://${req.get('host')}/payment/callback`
});

// Save payment record
const payment = await Payment.create({
orderId: order.id,
chargeId: charge.id,
amount: order.total,
status: charge.status,
paid: charge.paid
});

if (charge.paid) {
order.paymentStatus = 'paid';
await order.save();
return res.json({ success: true, charge });
} else if (charge.authorize_uri) {
return res.json({ redirect: charge.authorize_uri });
} else {
return res.status(400).json({ error: charge.failure_message });
}

} catch (error) {
console.error('Payment error:', error);
res.status(500).json({ error: 'Payment failed' });
}
};

exports.paymentCallback = async (req, res) => {
try {
const { id: chargeId } = req.query;

const charge = await omise.charges.retrieve(chargeId);
const payment = await Payment.findOne({ chargeId: charge.id });

if (!payment) {
return res.status(404).send('Payment not found');
}

payment.status = charge.status;
payment.paid = charge.paid;
await payment.save();

if (charge.paid) {
const order = await Order.findById(payment.orderId);
order.paymentStatus = 'paid';
await order.save();
res.redirect(`/orders/${order.id}?success=true`);
} else {
res.redirect(`/payment/${payment.orderId}?error=${charge.failure_message}`);
}

} catch (error) {
console.error('Callback error:', error);
res.status(500).send('Payment verification failed');
}
};

Routesโ€‹

// routes/payment.js
const express = require('express');
const router = express.Router();
const paymentController = require('../controllers/paymentController');

router.post('/payment/:orderId', paymentController.createPayment);
router.get('/payment/callback', paymentController.paymentCallback);

module.exports = router;

Middleware for Error Handlingโ€‹

// middleware/errorHandler.js
const { OmiseError } = require('omise');

function errorHandler(err, req, res, next) {
if (err instanceof OmiseError) {
console.error('Omise Error:', {
message: err.message,
code: err.code,
statusCode: err.statusCode
});

return res.status(err.statusCode || 500).json({
error: err.message,
code: err.code
});
}

console.error('Unexpected error:', err);
res.status(500).json({ error: 'Internal server error' });
}

module.exports = errorHandler;

NestJS Integrationโ€‹

Module Setupโ€‹

// omise/omise.module.ts
import { Module, Global } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { OmiseService } from './omise.service';

@Global()
@Module({
imports: [ConfigModule],
providers: [OmiseService],
exports: [OmiseService],
})
export class OmiseModule {}

Serviceโ€‹

// omise/omise.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import Omise from 'omise';

@Injectable()
export class OmiseService {
private omise: ReturnType<typeof Omise>;

constructor(private configService: ConfigService) {
this.omise = Omise({
secretKey: this.configService.get<string>('OMISE_SECRET_KEY')!,
publicKey: this.configService.get<string>('OMISE_PUBLIC_KEY')!,
omiseVersion: '2019-05-29'
});
}

async createCharge(params: Omise.Charges.CreatePayload): Promise<Omise.Charges.ICharge> {
return this.omise.charges.create(params);
}

async retrieveCharge(chargeId: string): Promise<Omise.Charges.ICharge> {
return this.omise.charges.retrieve(chargeId);
}

async createCustomer(params: Omise.Customers.CreatePayload): Promise<Omise.Customers.ICustomer> {
return this.omise.customers.create(params);
}

async refundCharge(chargeId: string, amount?: number): Promise<Omise.Refunds.IRefund> {
return this.omise.charges.refund(chargeId, amount ? { amount } : undefined);
}
}

Controllerโ€‹

// payment/payment.controller.ts
import { Controller, Post, Get, Body, Param, Query, HttpException, HttpStatus } from '@nestjs/common';
import { OmiseService } from '../omise/omise.service';
import { PaymentService } from './payment.service';

@Controller('payment')
export class PaymentController {
constructor(
private omiseService: OmiseService,
private paymentService: PaymentService
) {}

@Post(':orderId')
async createPayment(
@Param('orderId') orderId: string,
@Body('omiseToken') omiseToken: string
) {
try {
const order = await this.paymentService.findOrder(orderId);

const charge = await this.omiseService.createCharge({
amount: Math.round(order.total * 100),
currency: 'THB',
card: omiseToken,
description: `Order #${order.id}`,
metadata: {
order_id: order.id,
customer_email: order.email
},
return_uri: `${process.env.APP_URL}/payment/callback`
});

await this.paymentService.savePayment({
orderId: order.id,
chargeId: charge.id,
amount: order.total,
status: charge.status,
paid: charge.paid
});

if (charge.paid) {
await this.paymentService.markOrderPaid(order.id);
return { success: true, charge };
} else if (charge.authorize_uri) {
return { redirect: charge.authorize_uri };
} else {
throw new HttpException(charge.failure_message, HttpStatus.BAD_REQUEST);
}

} catch (error) {
throw new HttpException('Payment failed', HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@Get('callback')
async paymentCallback(@Query('id') chargeId: string) {
const charge = await this.omiseService.retrieveCharge(chargeId);
await this.paymentService.updatePaymentStatus(charge.id, charge.status, charge.paid);

if (charge.paid) {
return { success: true, message: 'Payment successful' };
} else {
throw new HttpException(charge.failure_message, HttpStatus.BAD_REQUEST);
}
}
}

Best Practicesโ€‹

1. Use Environment Variablesโ€‹

require('dotenv').config();

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
publicKey: process.env.OMISE_PUBLIC_KEY
});

if (!process.env.OMISE_SECRET_KEY) {
throw new Error('OMISE_SECRET_KEY is not set');
}

2. Implement Idempotencyโ€‹

async function createIdempotentCharge(params, orderId) {
// Use deterministic idempotency key based on orderId
// This ensures the same order always gets the same key
const idempotencyKey = `order-${orderId}`;

return omise.charges.create(params, {
headers: {
'Idempotency-Key': idempotencyKey
}
});
}

3. Use Retry Logicโ€‹

async function createChargeWithRetry(params, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await omise.charges.create(params);
} catch (error) {
if (attempt === maxRetries - 1) throw error;

const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

4. Store Minimal Dataโ€‹

class Payment {
constructor(chargeId) {
this.chargeId = chargeId;
this._charge = null;
}

async getCharge() {
if (!this._charge) {
this._charge = await omise.charges.retrieve(this.chargeId);
}
return this._charge;
}

async refreshCharge() {
this._charge = null;
return this.getCharge();
}
}

5. Implement Loggingโ€‹

const winston = require('winston');

const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});

async function createChargeWithLogging(params) {
logger.info('Creating charge', { amount: params.amount, currency: params.currency });

try {
const charge = await omise.charges.create(params);
logger.info('Charge created', { chargeId: charge.id, paid: charge.paid });
return charge;
} catch (error) {
logger.error('Charge failed', { error: error.message, code: error.code });
throw error;
}
}

6. Validate Inputโ€‹

const Joi = require('joi');

const chargeSchema = Joi.object({
amount: Joi.number().min(2000).required(),
currency: Joi.string().valid('THB', 'USD', 'SGD', 'JPY').required(),
token: Joi.string().required()
});

async function createValidatedCharge(params) {
const { error, value } = chargeSchema.validate(params);

if (error) {
throw new Error(`Validation error: ${error.message}`);
}

return omise.charges.create({
amount: value.amount,
currency: value.currency,
card: value.token
});
}

Testingโ€‹

Jest Examplesโ€‹

// __tests__/payment.test.js
const omise = require('../config/omise');

jest.mock('../config/omise');

describe('Payment Service', () => {
beforeEach(() => {
jest.clearAllMocks();
});

test('should create a charge successfully', async () => {
const mockCharge = {
id: 'chrg_test_123',
amount: 100000,
currency: 'THB',
paid: true,
status: 'successful'
};

omise.charges.create.mockResolvedValue(mockCharge);

const result = await omise.charges.create({
amount: 100000,
currency: 'THB',
card: 'tokn_test_123'
});

expect(result.id).toBe('chrg_test_123');
expect(result.paid).toBe(true);
});

test('should handle charge error', async () => {
const mockError = new Error('insufficient_fund');
mockError.code = 'insufficient_fund';

omise.charges.create.mockRejectedValue(mockError);

await expect(
omise.charges.create({ amount: 100000, currency: 'THB', card: 'tokn_test_123' })
).rejects.toThrow('insufficient_fund');
});
});

Integration Tests with Supertestโ€‹

// __tests__/payment.integration.test.js
const request = require('supertest');
const app = require('../app');
const omise = require('../config/omise');

jest.mock('../config/omise');

describe('Payment API', () => {
test('POST /payment/:orderId should create a payment', async () => {
const mockCharge = {
id: 'chrg_test_123',
paid: true,
status: 'successful'
};

omise.charges.create.mockResolvedValue(mockCharge);

const response = await request(app)
.post('/payment/order_123')
.send({ omiseToken: 'tokn_test_123' });

expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.charge.id).toBe('chrg_test_123');
});
});

Troubleshootingโ€‹

SSL Certificate Errorsโ€‹

const https = require('https');

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
agent: new https.Agent({
rejectUnauthorized: false // Only for development!
})
});

Connection Timeoutsโ€‹

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
timeout: 60000 // 60 seconds
});

Debug Modeโ€‹

const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY,
debug: true // Logs request/response details
});

Webhook Signature Verificationโ€‹

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

// Express middleware
function webhookVerification(req, res, next) {
const payload = JSON.stringify(req.body);
const signature = req.headers['omise-signature'];

if (!verifyWebhookSignature(payload, signature, process.env.OMISE_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}

next();
}

FAQโ€‹

How do I handle webhooks in Express?โ€‹

const express = require('express');
const router = express.Router();

router.post('/webhooks/omise', express.json(), (req, res) => {
const event = req.body;

switch (event.key) {
case 'charge.complete':
handleChargeComplete(event.data);
break;
case 'refund.create':
handleRefundCreate(event.data);
break;
}

res.json({ status: 'ok' });
});

async function handleChargeComplete(chargeData) {
const charge = await omise.charges.retrieve(chargeData.id);
// Update payment status
}

How do I test payments without real charges?โ€‹

// Use test API keys
const omise = require('omise')({
secretKey: 'skey_test_123456789'
});

// Use test tokens
const charge = await omise.charges.create({
amount: 100000,
currency: 'THB',
card: 'tokn_test_5086xl7ddjbases4sq3i' // Test token
});

console.log('Test mode:', !charge.livemode);

How do I handle currency conversion?โ€‹

class Money {
constructor(amountBaht) {
this.amountSatang = Math.round(amountBaht * 100);
}

getSatang() {
return this.amountSatang;
}

getBaht() {
return this.amountSatang / 100;
}

static fromSatang(amountSatang) {
const instance = new Money(0);
instance.amountSatang = amountSatang;
return instance;
}
}

// Usage
const money = new Money(1000.00);
const charge = await omise.charges.create({
amount: money.getSatang(),
currency: 'THB',
card: 'tokn_test_123'
});

How do I implement retry logic with exponential backoff?โ€‹

async function retry(fn, maxRetries = 3, baseDelay = 1000) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries - 1) throw error;

const delay = baseDelay * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

// Usage
const charge = await retry(() =>
omise.charges.create({
amount: 100000,
currency: 'THB',
card: 'tokn_test_123'
})
);

How do I handle partial refunds?โ€‹

async function refundCharge(chargeId, refundAmount = null) {
const charge = await omise.charges.retrieve(chargeId);

const refundable = charge.amount - charge.refunded;

if (refundAmount && refundAmount > refundable) {
throw new Error('Refund amount exceeds refundable amount');
}

return omise.charges.refund(chargeId, {
amount: refundAmount
});
}

How do I save multiple cards for a customer?โ€‹

async function addCardToCustomer(customerId, token) {
return omise.customers.update(customerId, { card: token });
}

async function listCustomerCards(customerId) {
const customer = await omise.customers.retrieve(customerId);
return customer.cards.data;
}

async function chargeSpecificCard(customerId, cardId, amount) {
return omise.charges.create({
amount,
currency: 'THB',
customer: customerId,
card: cardId
});
}

How do I implement subscription billing?โ€‹

const cron = require('node-cron');

class SubscriptionManager {
constructor(customerId, planAmount) {
this.customerId = customerId;
this.planAmount = planAmount;
}

async chargeMonthly() {
const charge = await omise.charges.create({
amount: this.planAmount,
currency: 'THB',
customer: this.customerId,
description: `Subscription ${new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}`
});

return charge;
}

handleFailedPayment(charge) {
// Send notification
// Update subscription status
}
}

// Schedule monthly charges
cron.schedule('0 0 1 * *', async () => {
const subscriptions = await getActiveSubscriptions();

for (const subscription of subscriptions) {
const manager = new SubscriptionManager(
subscription.customerId,
subscription.planAmount
);

try {
await manager.chargeMonthly();
} catch (error) {
manager.handleFailedPayment(error);
}
}
});

Next Stepsโ€‹

Supportโ€‹

If you encounter issues with the Node.js library:

  1. Check the GitHub Issues
  2. Review the API documentation
  3. Contact support@omise.co with:
    • Node.js version
    • omise-node library version
    • Error message and stack trace
    • Steps to reproduce