振込スケジュール
振込スケジュールにより、定期的な支払い、給与処理、およびベンダー支払いを完全に自動化できます。このガイドでは、スケジュールの作成、繰り返しパターンの設定、および自動出金の管理について説明します。
概要
振込スケジュールは以下を可能にします:
- 繰り返し支払い: 毎日、毎週、毎月の出金
- 柔軟なスケジュール: カスタムパターンをサポート
- 自動処理: 手動操作不要
- 完全な制御: スケジュールを一時停止、再開、キャンセル
- エラー処理: 失敗したスケジュール振込の通知
- 監視: スケジュール実行をリアルタイムで追跡
スケジュールの作成
月次給与スケジュール
const omise = require('omise')({
secretKey: 'skey_test_123456789'
});
async function createMonthlyPayrollSchedule(recipientId, monthlyAmount) {
const schedule = await omise.schedules.create({
every: 1,
period: 'month',
recipient: recipientId,
transfer: {
amount: monthlyAmount
},
metadata: {
type: 'monthly_salary',
purpose: '従業員報酬'
}
});
console.log('スケジュール作成:', schedule.id);
console.log('次回予定:', schedule.next_occurrence);
console.log('受取人:', schedule.recipient);
return schedule;
}
// 使用例: 月次給与スケジュールを作成
createMonthlyPayrollSchedule('recp_test_123456', 5000000); // 50,000 THB
週次支払いスケジュール
async function createWeeklyPayoutSchedule(recipientId, weeklyAmount, dayOfWeek = 'monday') {
const schedule = await omise.schedules.create({
every: 1,
period: 'week',
weekdays: [dayOfWeek],
recipient: recipientId,
transfer: {
amount: weeklyAmount
},
metadata: {
type: 'weekly_vendor_payment',
vendor_id: 'VENDOR-001'
}
});
return schedule;
}
隔週支払いスケジュール
async function createBiWeeklySchedule(recipientId, biWeeklyAmount, startDate) {
const schedule = await omise.schedules.create({
every: 2,
period: 'week',
start_date: startDate,
recipient: recipientId,
transfer: {
amount: biWeeklyAmount
},
metadata: {
type: 'bi_weekly_payment'
}
});
return schedule;
}
スケジュール管理
スケジュールを取得
async function getScheduleDetails(scheduleId) {
const schedule = await omise.schedules.retrieve(scheduleId);
console.log('スケジュールID:', schedule.id);
console.log('ステータス:', schedule.status);
console.log('受取人:', schedule.recipient);
console.log('金額:', schedule.transfer.amount / 100, 'THB');
console.log('期間:', schedule.every, schedule.period);
console.log('次回実行:', schedule.next_occurrence);
return schedule;
}
スケジュールを一覧表示
async function listAllSchedules(status = 'active') {
const schedules = await omise.schedules.list({
status: status,
limit: 100
});
schedules.data.forEach(schedule => {
console.log(`${schedule.id}: ${schedule.transfer.amount / 100} THB - ${schedule.status}`);
});
return schedules;
}
スケジュールを更新
async function updateScheduleAmount(scheduleId, newAmount) {
const schedule = await omise.schedules.update(scheduleId, {
transfer: {
amount: newAmount
}
});
console.log('スケジュール更新:', schedule.id);
console.log('新しい金額:', schedule.transfer.amount / 100, 'THB');
return schedule;
}
スケジュールを一時停止/再開
async function pauseSchedule(scheduleId) {
const schedule = await omise.schedules.update(scheduleId, {
status: 'paused'
});
console.log('スケジュール一時停止:', schedule.id);
return schedule;
}
async function resumeSchedule(scheduleId) {
const schedule = await omise.schedules.update(scheduleId, {
status: 'active'
});
console.log('スケジュール再開:', schedule.id);
return schedule;
}
スケジュールをキャンセル
async function cancelSchedule(scheduleId) {
const schedule = await omise.schedules.destroy(scheduleId);
console.log('スケジュールキャンセル:', schedule.id);
return schedule;
}
よくあるユースケース
給与処理スケジュール
class PayrollScheduleManager:
def __init__(self, omise_client):
self.omise = omise_client
def create_payroll_schedules(self, employees):
"""複数の従業員のための給与スケジュールを作成"""
schedules = []
for employee in employees:
try:
schedule = self.omise.schedules.create(
every=1,
period='month',
recipient=employee['recipient_id'],
transfer={
'amount': employee['monthly_salary']
},
metadata={
'type': 'monthly_payroll',
'employee_id': employee['employee_id'],
'employee_name': employee['name'],
'department': employee['department']
}
)
schedules.append({
'employee_id': employee['employee_id'],
'employee_name': employee['name'],
'schedule_id': schedule.id,
'status': 'created'
})
print(f"✓ {employee['name']}のスケジュールを作成しました")
except Exception as e:
schedules.append({
'employee_id': employee['employee_id'],
'employee_name': employee['name'],
'error': str(e),
'status': 'failed'
})
print(f"✗ {employee['name']}の失敗: {str(e)}")
return schedules
def pause_all_schedules(self, department):
"""部門内のすべてのスケジュールを一時停止"""
schedules = self.omise.schedules.list(limit=100)
paused = []
for schedule in schedules.data:
if schedule.metadata.get('department') == department:
try:
self.omise.schedules.update(schedule.id, status='paused')
paused.append(schedule.id)
except Exception as e:
print(f"{schedule.id}の一時停止失敗: {str(e)}")
print(f"{len(paused)}件のスケジュールを一時停止しました")
return paused
def resume_paused_schedules(self, department):
"""部門内のすべての一時停止されたスケジュールを再開"""
schedules = self.omise.schedules.list(
status='paused',
limit=100
)
resumed = []
for schedule in schedules.data:
if schedule.metadata.get('department') == department:
try:
self.omise.schedules.update(schedule.id, status='active')
resumed.append(schedule.id)
except Exception as e:
print(f"{schedule.id}の再開失敗: {str(e)}")
return resumed
ベンダー支払 いスケジュール
class VendorPaymentScheduleManager {
constructor(omise) {
this.omise = omise;
}
async createWeeklyVendorPayments(vendors) {
const schedules = [];
for (const vendor of vendors) {
try {
const schedule = await this.omise.schedules.create({
every: 1,
period: 'week',
weekdays: ['friday'], // 毎週金曜日に支払い
recipient: vendor.recipientId,
transfer: {
amount: vendor.weeklyAmount
},
metadata: {
type: 'vendor_payment',
vendor_id: vendor.vendorId,
vendor_name: vendor.name,
category: vendor.category
}
});
schedules.push({
vendorId: vendor.vendorId,
scheduleId: schedule.id,
status: 'active'
});
console.log(`✓ ${vendor.name}の週次スケジュールを作成しました`);
} catch (error) {
console.error(`✗ ${vendor.name}の失敗: ${error.message}`);
schedules.push({
vendorId: vendor.vendorId,
error: error.message,
status: 'failed'
});
}
}
return schedules;
}
async adjustVendorPayment(scheduleId, newAmount) {
const schedule = await this.omise.schedules.update(scheduleId, {
transfer: { amount: newAmount }
});
console.log(`スケジュール${scheduleId}を${newAmount / 100} THBに更新しました`);
return schedule;
}
async suspendVendor(scheduleId, reason) {
const schedule = await this.omise.schedules.update(scheduleId, {
status: 'paused'
});
// 記録用にメモを保存
console.log(`スケジュール${scheduleId}を停止しました: ${reason}`);
return schedule;
}
}
スケジュール実行の監視
スケジュール実行を追跡
async function trackScheduleExecutions(scheduleId) {
const executions = await omise.schedule_transfers.list({
schedule: scheduleId,
limit: 50,
order: 'reverse_chronological'
});
console.log(`スケジュール${scheduleId}の実行:`);
executions.data.forEach(execution => {
console.log(`
振込ID: ${execution.transfer.id}
金額: ${execution.transfer.amount / 100} THB
ステータス: ${execution.transfer.status}
作成日: ${execution.created}
`);
});
return executions;
}
スケジュール実行統計
class ScheduleAnalytics:
def __init__(self, omise_client):
self.omise = omise_client
def get_schedule_stats(self, schedule_id, months=12):
"""スケジュールの実行統計を取得"""
executions = self.omise.schedule_transfers.list(
schedule=schedule_id,
limit=100
)
stats = {
'total_executions': len(executions.data),
'successful': 0,
'failed': 0,
'total_amount_transferred': 0,
'total_fees': 0,
'average_transfer': 0
}
for execution in executions.data:
transfer = execution.transfer
if transfer.paid or transfer.sent:
stats['successful'] += 1
stats['total_amount_transferred'] += transfer.amount
stats['total_fees'] += transfer.fee
else:
stats['failed'] += 1
if stats['successful'] > 0:
stats['average_transfer'] = (
stats['total_amount_transferred'] / stats['successful']
)
return stats
def get_scheduled_vs_actual(self, schedule_id):
"""スケジュール済みとして予期されていた金額と実際に送付された金額を比較"""
schedule = self.omise.schedules.retrieve(schedule_id)
executions = self.omise.schedule_transfers.list(
schedule=schedule_id,
limit=100
)
total_scheduled = len(executions.data) * schedule.transfer.amount
total_transferred = sum(
e.transfer.amount for e in executions.data
if e.transfer.paid or e.transfer.sent
)
return {
'scheduled_amount': total_scheduled,
'transferred_amount': total_transferred,
'difference': total_scheduled - total_transferred,
'execution_rate': (
total_transferred / total_scheduled * 100
if total_scheduled > 0 else 0
)
}
ベストプラクティス
1. スケジュール作成前に検証
async function createValidatedSchedule(recipientId, amount, frequency) {
// 受取人を確認
const recipient = await omise.recipients.retrieve(recipientId);
if (!recipient.active || !recipient.verified) {
throw new Error('受取人がアクティブまたは検証されていません');
}
// 金額を確認
if (amount < 2000) { // 最小額20 THB
throw new Error('金額が最小額を下回っています');
}
// スケジュール作成
const schedule = await omise.schedules.create({
every: frequency.every,
period: frequency.period,
recipient: recipientId,
transfer: { amount }
});
return schedule;
}
2. スケジュール失敗を監視
def monitor_schedule_failures(schedule_id, notification_email):
"""スケジュール失敗を監視してアラートを送信"""
executions = omise.ScheduleTransfer.list(
schedule=schedule_id,
limit=100
)
failures = [
e for e in executions.data
if e.transfer.failure_code
]
if failures:
# アラートを送信
send_alert_email(
to=notification_email,
subject=f"スケジュール{schedule_id}に失敗があります",
body=f"{len(failures)}件の振込が失敗しました"
)
# ログに記録
for failure in failures:
print(f"失敗した振込: {failure.transfer.id}")
print(f"理由: {failure.transfer.failure_message}")
return failures
よくある質問
スケジュールの最小頻度は?
毎日が最小頻度です。より頻繁な振込が必要な場合は、手動で振込を作成する必要があります。
スケジュールはスケジュール時刻に実行されますか?
スケジュールは翌日の基準時間(UTC)に実行されます。銀行の営業時間により、資金が実際に到達するにはさらに時間がかかる場合があります。
スケジュールの最大数は?
アカウントあたりのスケジュール数に技術的な制限はありませんが、多数の同時スケジュールを管理することはお勧めしません。
スケジュールは失敗時に自動的に再試行されますか?
いいえ。失敗したスケジュール振込は自動的には再試行されません。失敗は記録され、Webhook経由で通知されます。
実行中のスケジュールを編集できますか?
はい。スケジュールを一時停止することなく、スケジュール内の金額やメタデータを編集できます。
スケジュール時刻を変更できますか?
スケジュール時刻を直接変更することはできません。別の開始日で新しいスケジュールを作成する必要があります。