Node.js ライブラリ (omise-node)
omise-node ライブラリは、TypeScript 定義、Promise/async-await サポート、および優れた Express と NestJS 統合を備えた、Omise API への最新の Node.js インターフェースを提供します。
インストール
npm の使用
npm install omise
Yarn の使用
yarn add omise
pnpm の使用
pnpm add omise
要件
- Node.js 12 以上 (Node.js 12 は 2022 年 4 月に EOL に達したため Node.js 16+ を推奨)
- パッケージ管理用の npm、yarn、または pnpm
- TypeScript 4.0+ (オプション、TypeScript プロジェクト用)
クイックスタート
基本的な構成
const omise = require('omise')({
secretKey: 'skey_test_123456789',
publicKey: 'pkey_test_123456789',
omiseVersion: '2019-05-29'
});
TypeScript の構成
omise-node ライブラリには 組み込み TypeScript 定義 が含まれており、別の @types/omise パッケージは必要ありません。
import Omise from 'omise';
const omise = Omise({
secretKey: process.env.OMISE_SECRET_KEY!,
publicKey: process.env.OMISE_PUBLIC_KEY!,
omiseVersion: '2019-05-29'
});
// 型安全なAPIコール
import type { Charges, Tokens } from 'omise';
// チャージは完全な型推論を持つ
const charge: Charges.ICharge = await omise.charges.create({
amount: 100000,
currency: 'thb',
card: 'tokn_test_123'
});
// トークンレスポンスは完全に型付けされる
const token: Tokens.IToken = await omise.tokens.create({
card: {
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2027,
security_code: '123',
name: 'JOHN DOE'
}
});
TypeScript の機能:
- ✅ 組み込み型 定義 (@types パッケージ不要)
- ✅ VS Code での完全な IntelliSense サポート
- ✅ 型安全なリクエスト/レスポンスオブジェクト
- ✅ 支払い方法、通貨、ステータス向けの列挙型
- ✅ 厳密な null チェックのサポート
- ✅ 高度な使用向けのジェネリック型パラメータ
型定義の場所: 公式の TypeScript 定義は omise-node リポジトリ で保持されています。
Express 構成
// 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'
});
環境変数
.env ファイルを作成:
# 開発/テスト
OMISE_SECRET_KEY=skey_test_123456789
OMISE_PUBLIC_KEY=pkey_test_123456789
# 本番環境
# OMISE_SECRET_KEY=skey_live_123456789
# OMISE_PUBLIC_KEY=pkey_live_123456789
一般的な操作
チャージの作成
Promise で
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.id}`);
} else {
console.log(`チャージ失敗: ${charge.failure_message}`);
}
})
.catch(err => {
console.error('エラー:', err.message);
});
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.id}`);
return charge;
} else {
throw new Error(charge.failure_message);
}
} catch (error) {
console.error('チャージ失敗:', error);
throw error;
}
}
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;
}
3D セキュアで
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) {
// 3D セキュアのために顧客を authorize_uri にリダイレクト
return { redirect: charge.authorize_uri };
} else {
// 3D セキュアなしでチャージ完了
return { success: true, charge };
}
}
throw new Error(charge.failure_message);
}
チャージの取得
// Promise ベース
omise.charges.retrieve('chrg_test_123')
.then(charge => {
console.log(`金額: ${charge.amount}`);
console.log(`通貨: ${charge.currency}`);
console.log(`ステータス: ${charge.status}`);
});
// Async/await
async function getCharge(chargeId) {
const charge = await omise.charges.retrieve(chargeId);
return charge;
}
チャージのリスト表示
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;
}
// 日付フィルタでチャージをリスト表示
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]
});
顧客の作成
async function createCustomer(email, description, metadata = {}) {
const customer = await omise.customers.create({
email,
description,
metadata
});
console.log(`顧客作成: ${customer.id}`);
return customer;
}
// 使用方法
const customer = await createCustomer(
'customer@example.com',
'John Doe',
{ user_id: '12345', account_type: 'premium' }
);
顧客へのカード保存
// カードトークンで顧客を更新
async function addCardToCustomer(customerId, token) {
const customer = await omise.customers.update(customerId, {
card: token
});
console.log(`カード保存: ${customer.default_card}`);
return customer;
}
// カード付きで顧客を作成
async function createCustomerWithCard(email, token) {
const customer = await omise.customers.create({
email,
card: token
});
return customer;
}
顧客カードのリスト表示
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(`有効期限: ${card.expiration_month}/${card.expiration_year}`);
});
return customer.cards.data;
}
払い戻しの作成
// 全額返金
async function refundCharge(chargeId) {
const refund = await omise.charges.refund(chargeId);
return refund;
}
// 部分払い戻し
async function partialRefund(chargeId, amount, metadata = {}) {
const refund = await omise.charges.refund(chargeId, {
amount,
metadata
});
console.log(`返金 ${refund.id}: ${refund.amount} ${refund.currency}`);
return refund;
}
// 使用方法
await partialRefund('chrg_test_123', 25000, {
reason: 'customer_request',
ticket_id: 'TICKET-123'
});
転送の作成
async function createTransfer(amount, recipientId, metadata = {}) {
const transfer = await omise.transfers.create({
amount,
recipient: recipientId,
metadata
});
console.log(`転送 ${transfer.id}: ${transfer.amount}`);
return transfer;
}
代替決済方法
ソースの作成
// PromptPay QR
async function createPromptPaySource(amount) {
const source = await omise.sources.create({
type: 'promptpay',
amount,
currency: 'THB'
});
console.log(`QR コード URL: ${source.scannable_code.image.download_uri}`);
// ソースでチャージを作成
const charge = await omise.charges.create({
amount,
currency: 'THB',
source: source.id,
return_uri: 'https://example.com/payment/callback'
});
return { source, charge };
}
インターネットバンキング
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'
});
// リダイレクト用の authorize_uri を返す
return charge.authorize_uri;
}
分割払い
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;
}
// 使用方法
const charge = await createInstallmentCharge(100000, 'kbank', 6);
エラーハンドリング
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.message);
console.error('ステータスコード:', error.statusCode);
console.error('エラーコード:', error.code);
// 特定のエラーを処理
switch (error.code) {
case 'authentication_failure':
throw new Error('無効な API キー');
case 'invalid_card':
throw new Error('カードが拒否されました');
case 'insufficient_fund':
throw new Error('残高不足');
default:
throw error;
}
}
// ネットワークまたはその他のエラー
throw error;
}
}
TypeScript エラーハンドリング
import Omise, { OmiseError } from 'omise';
async function handleChargeError(error: unknown): Promise<never> {
if (error instanceof OmiseError) {
const errorMessages: Record<string, string> = {
insufficient_fund: 'カードの残高不足',
stolen_or_lost_card: 'カードは盗難または紛失として報告されています',
invalid_security_code: '無効な CVV コード',
payment_cancelled: '支払いがキャンセルされました'
};
const message = errorMessages[error.code] || error.message;
throw new Error(message);
}
throw error;
}