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

定期支払いスケジュール

自動化されたサブスクリプション請求、メンバーシップ、定期請求のための定期支払いスケジュールの作成と管理方法について説明します。スケジュールは手動干渉なしで顧客に定期的に請求するプロセスを自動化します。

概要

Schedules API により、手動干渉なしで定期請求を自動化できます。以下に最適です:

  • サブスクリプションサービス(月額、年額)
  • メンバーシップ費用
  • 分割払い
  • 使用量ベースの請求周期
  • 定期寄付
  • ライセンス更新

主な利点

  • 自動請求 - 設定して完了、請求が自動的に発生します
  • 柔軟なスケジュール - 毎日、毎週、毎月、またはカスタム期間
  • 再試行ロジック - 失敗した支払い処理の組み込み
  • 簡単な管理 - スケジュールを一時停止、再開、またはキャンセル
  • 包括的な追跡 - すべてのスケジュール請求を監視
  • 顧客の維持 - シームレスな更新により離脱を減らします

スケジュールの動作方法

  1. 顧客と請求の詳細を使用してスケジュールを作成
  2. スケジュールは指定された日付に自動的に請求を生成
  3. システムは顧客のデフォルト支払い方法への請求を試みます
  4. Webhook は成功/失敗した請求について通知します
  5. スケジュール終了またはキャンセルまで続行します

スケジュールの作成

基本的なスケジュール作成

curl https://api.omise.co/schedules \
-u skey_test_123: \
-d "every=1" \
-d "period=month" \
-d "start_date=2024-02-01" \
-d "end_date=2024-12-31" \
-d "charge[customer]=cust_test_123456" \
-d "charge[amount]=100000" \
-d "charge[currency]=THB" \
-d "charge[description]=Monthly Premium Subscription"
const omise = require('omise')({
secretKey: 'skey_test_123'
});

const schedule = await omise.schedules.create({
every: 1,
period: 'month',
start_date: '2024-02-01',
end_date: '2024-12-31',
charge: {
customer: 'cust_test_123456',
amount: 100000,
currency: 'THB',
description: 'Monthly Premium Subscription'
}
});

console.log('スケジュール ID:', schedule.id);
console.log('ステータス:', schedule.status);
console.log('次の発生:', schedule.next_occurrences_on[0]);
import omise
from datetime import datetime, timedelta

omise.api_secret = 'skey_test_123'

schedule = omise.Schedule.create(
every=1,
period='month',
start_date='2024-02-01',
end_date='2024-12-31',
charge={
'customer': 'cust_test_123456',
'amount': 100000,
'currency': 'THB',
'description': 'Monthly Premium Subscription'
}
)

print(f'スケジュール ID: {schedule.id}')
print(f'ステータス: {schedule.status}')
print(f'次の発生: {schedule.next_occurrences_on[0]}')

スケジュール期間

// 月額請求
const monthly = await omise.schedules.create({
every: 1,
period: 'month',
start_date: '2024-02-01',
charge: { /* ... */ }
});

// 週単位請求
const weekly = await omise.schedules.create({
every: 1,
period: 'week',
start_date: '2024-02-01',
charge: { /* ... */ }
});

// 日単位請求
const daily = await omise.schedules.create({
every: 1,
period: 'day',
start_date: '2024-02-01',
charge: { /* ... */ }
});

// 四半期ごと(3ヶ月ごと)
const quarterly = await omise.schedules.create({
every: 3,
period: 'month',
start_date: '2024-02-01',
charge: { /* ... */ }
});

// 年額請求
const annual = await omise.schedules.create({
every: 1,
period: 'year',
start_date: '2024-02-01',
charge: { /* ... */ }
});

スケジュールの管理

スケジュールの取得

const schedule = await omise.schedules.retrieve('schd_test_123456');

console.log('スケジュール:', schedule.in_words);
console.log('ステータス:', schedule.status);
console.log('次の請求:', schedule.next_occurrences_on);
console.log('完了した請求:', schedule.occurrences.total);

すべてのスケジュールをリストアップ

// フィルター付きでリスト
const schedules = await omise.schedules.list({
limit: 20,
offset: 0,
order: 'reverse_chronological'
});

schedules.data.forEach(schedule => {
console.log(`${schedule.id} - ${schedule.status} - ${schedule.in_words}`);
});

// ステータス別でフィルター
const activeSchedules = schedules.data.filter(
s => s.status === 'active'
);

スケジュールを一時停止

// スケジュール一時停止
await omise.schedules.destroy('schd_test_123456');

// 停止を確認
const schedule = await omise.schedules.retrieve('schd_test_123456');
console.log('ステータス:', schedule.status);

スケジュール発生を表示

const schedule = await omise.schedules.retrieve('schd_test_123456');
const occurrences = schedule.occurrences.data;

occurrences.forEach(occurrence => {
console.log('日付:', occurrence.schedule_date);
console.log('ステータス:', occurrence.status);
console.log('請求:', occurrence.result?.id);
console.log('---');
});

高度なスケジュール設定

特定の日付に請求

// 毎月特定の日付に請求
const schedule = await omise.schedules.create({
every: 1,
period: 'month',
on: {
days_of_month: [15] // 毎月15日に請求
},
start_date: '2024-02-15',
charge: {
customer: 'cust_test_123456',
amount: 100000,
currency: 'THB'
}
});

// 月複数日に請求
const bimonthly = await omise.schedules.create({
every: 1,
period: 'month',
on: {
days_of_month: [1, 15] // 1日と15日に請求
},
start_date: '2024-02-01',
charge: { /* ... */ }
});

メタデータを付きスケジュール

const schedule = await omise.schedules.create({
every: 1,
period: 'month',
start_date: '2024-02-01',
charge: {
customer: 'cust_test_123456',
amount: 100000,
currency: 'THB',
description: 'Premium Subscription',
metadata: {
subscription_id: 'sub_12345',
plan: 'premium',
user_id: '67890',
billing_cycle: 'monthly'
}
}
});

ベストプラクティス

1. スケジュール作成を安全に

// スケジュール作成前に顧客を検証
async function createScheduleSafely(customerId, scheduleData) {
const customer = await omise.customers.retrieve(customerId);

if (!customer.default_card) {
throw new Error('Customer has no payment method');
}

// 使用期限確認
const card = customer.cards.data.find(
c => c.id === customer.default_card
);

const expiry = new Date(
card.expiration_year,
card.expiration_month - 1,
1
);

if (expiry <= new Date()) {
throw new Error('Payment method has expired');
}

return await omise.schedules.create({
...scheduleData,
charge: {
...scheduleData.charge,
customer: customerId
}
});
}

2. エラーハンドリング

class ScheduleErrorHandler {
async createScheduleWithRetry(scheduleData, maxRetries = 3) {
let lastError;

for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await omise.schedules.create(scheduleData);
} catch (error) {
lastError = error;
console.log(`Attempt ${attempt} failed:`, error.message);

if (error.code === 'customer_not_found') {
throw error;
}

if (attempt < maxRetries) {
await this.delay(1000 * attempt);
}
}
}

throw lastError;
}
}

FAQ

Q: 最初の請求はいつ発生しますか?

A: 指定した start_date で最初の請求が発生します。少なくとも1日先の日付を確認してください。

Q: 作成後にスケジュールを変更できますか?

A: いいえ、スケジュールは不変です。パラメータを変更するには、古いスケジュールを削除して新しいものを作成する必要があります。

Q: スケジュール済み請求が失敗した場合はどうなりますか?

A: Webhook 通知を受け取ります。スケジュールは今後の請求を試み続けます。アプリケーションで再試行ロジックを実装してください。

Q: スケジュール請求が失敗した場合の対処方法は?

A: 再試行ロジックを実装し(バックオフ付き)、顧客に通知し、支払い情報を更新する簡単な方法を提供してください。猶予期間を検討してください。

関連リソース

次のステップ