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

振込スケジュール

振込スケジュールにより、定期的な支払い、給与処理、およびベンダー支払いを完全に自動化できます。このガイドでは、スケジュールの作成、繰り返しパターンの設定、および自動出金の管理について説明します。

概要

振込スケジュールは以下を可能にします:

  • 繰り返し支払い: 毎日、毎週、毎月の出金
  • 柔軟なスケジュール: カスタムパターンをサポート
  • 自動処理: 手動操作不要
  • 完全な制御: スケジュールを一時停止、再開、キャンセル
  • エラー処理: 失敗したスケジュール振込の通知
  • 監視: スケジュール実行をリアルタイムで追跡

スケジュールの作成

月次給与スケジュール

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経由で通知されます。

実行中のスケジュールを編集できますか?

はい。スケジュールを一時停止することなく、スケジュール内の金額やメタデータを編集できます。

スケジュール時刻を変更できますか?

スケジュール時刻を直接変更することはできません。別の開始日で新しいスケジュールを作成する必要があります。

関連リソース