Balance & Transactions 概要
Omiseアカウントのbalanceは、アカウント内で利用可能な資金を表します。このガイドでは、balanceの確認方法、さまざまなbalanceタイプの理解、および資金を効果的に管理する方法について説明します。
概要
アカウントbalanceの理解は以下の目的で重要です:
- Transfer計画: 支払いに利用可能な資金の把握
- キャッシュフロー管理: 入出金の監視
- Reconciliation: transactionと銀行入金の照合
- 財務計画: 利用可能資金の予測
- 運用上の意思決定: refundとtransferの計画
主要な概念
- Total Balance: アカウント内の全資金(available + pending)
- Available Balance: 即座に使用可能な資金
- Pending Balance: settlement待ちまたは処理中の資金
- Transferable Balance: 手数料控除後の送金可能金額
- Currency: 通貨ごとに追跡されるbalance
Balanceの確認
現在のBalanceの取得
- Node.js
- Python
- Ruby
- PHP
- Go
const omise = require('omise')({
secretKey: 'skey_test_123456789',
});
// 現在のbalanceを取得
async function getBalance() {
try {
const balance = await omise.balance.retrieve();
console.log('Balance情報:');
console.log('------------------');
console.log(`合計: ${balance.total / 100} ${balance.currency.toUpperCase()}`);
console.log(`利用可能: ${balance.available / 100} ${balance.currency.toUpperCase()}`);
console.log(`通貨: ${balance.currency.toUpperCase()}`);
console.log(`ライブモード: ${balance.livemode}`);
return balance;
} catch (error) {
console.error('Balanceの取得に失敗しました:', error.message);
throw error;
}
}
// 詳細なbalance内訳を取得
async function getBalanceBreakdown() {
const balance = await omise.balance.retrieve();
const pending = balance.total - balance.available;
return {
total: balance.total,
available: balance.available,
pending: pending,
currency: balance.currency,
breakdown: {
total_formatted: `${balance.total / 100} ${balance.currency.toUpperCase()}`,
available_formatted: `${balance.available / 100} ${balance.currency.toUpperCase()}`,
pending_formatted: `${pending / 100} ${balance.currency.toUpperCase()}`
}
};
}
// 操作に十分なbalanceがあるか確認
async function hasSufficientBalance(requiredAmount) {
const balance = await omise.balance.retrieve();
return {
sufficient: balance.available >= requiredAmount,
available: balance.available,
required: requiredAmount,
shortfall: Math.max(0, requiredAmount - balance.available)
};
}
// 使用例
getBalance();
getBalanceBreakdown().then(breakdown => console.log(breakdown));
hasSufficientBalance(100000).then(result => {
if (result.sufficient) {
console.log('✓ 残高は十分です');
} else {
console.log(`✗ 残高が不足しています。不足額: ${result.shortfall / 100}`);
}
});
import omise
omise.api_secret = 'skey_test_123456789'
def get_balance():
"""現在のアカウントbalanceを取得"""
try:
balance = omise.Balance.retrieve()
print("Balance情報:")
print("------------------")
print(f"合計: {balance.total / 100} {balance.currency.upper()}")
print(f"利用可能: {balance.available / 100} {balance.currency.upper()}")
print(f"通貨: {balance.currency.upper()}")
print(f"ライブモード: {balance.livemode}")
return balance
except omise.errors.BaseError as e:
print(f"Balanceの取得に失敗しました: {str(e)}")
raise
def get_balance_breakdown():
"""詳細なbalance内訳を取得"""
balance = omise.Balance.retrieve()
pending = balance.total - balance.available
return {
'total': balance.total,
'available': balance.available,
'pending': pending,
'currency': balance.currency,
'breakdown': {
'total_formatted': f"{balance.total / 100:.2f} {balance.currency.upper()}",
'available_formatted': f"{balance.available / 100:.2f} {balance.currency.upper()}",
'pending_formatted': f"{pending / 100:.2f} {balance.currency.upper()}"
}
}
def has_sufficient_balance(required_amount):
"""操作に十分なbalanceがあるか確認"""
balance = omise.Balance.retrieve()
return {
'sufficient': balance.available >= required_amount,
'available': balance.available,
'required': required_amount,
'shortfall': max(0, required_amount - balance.available)
}
def format_balance_display(balance):
"""表示用にbalanceをフォーマット"""
pending = balance.total - balance.available
print("\n" + "="*50)
print("アカウントBALANCE")
print("="*50)
print(f"Total Balance: {balance.total / 100:>12,.2f} {balance.currency.upper()}")
print(f"Available: {balance.available / 100:>12,.2f} {balance.currency.upper()}")
print(f"Pending: {pending / 100:>12,.2f} {balance.currency.upper()}")
print("="*50)
# 使用例
balance = get_balance()
format_balance_display(balance)
breakdown = get_balance_breakdown()
print(f"\n詳細内訳: {breakdown}")
result = has_sufficient_balance(100000)
if result['sufficient']:
print("✓ 残高は十分です")
else:
print(f"✗ 残高が不足しています。不足額: {result['shortfall'] / 100:.2f}")
require 'omise'
Omise.api_key = 'skey_test_123456789'
# 現在のbalanceを取得
def get_balance
begin
balance = Omise::Balance.retrieve
puts "Balance情報:"
puts "------------------"
puts "合計: #{balance.total / 100.0} #{balance.currency.upcase}"
puts "利用可能: #{balance.available / 100.0} #{balance.currency.upcase}"
puts "通貨: #{balance.currency.upcase}"
puts "ライブモード: #{balance.livemode}"
balance
rescue Omise::Error => e
puts "Balanceの取得に失敗しました: #{e.message}"
raise
end
end
# 詳細なbalance内訳を取得
def get_balance_breakdown
balance = Omise::Balance.retrieve
pending = balance.total - balance.available
{
total: balance.total,
available: balance.available,
pending: pending,
currency: balance.currency,
breakdown: {
total_formatted: "#{balance.total / 100.0} #{balance.currency.upcase}",
available_formatted: "#{balance.available / 100.0} #{balance.currency.upcase}",
pending_formatted: "#{pending / 100.0} #{balance.currency.upcase}"
}
}
end
# 十分なbalanceがあるか確認
def has_sufficient_balance?(required_amount)
balance = Omise::Balance.retrieve
{
sufficient: balance.available >= required_amount,
available: balance.available,
required: required_amount,
shortfall: [0, required_amount - balance.available].max
}
end
# Balance表示をフォーマッ ト
def format_balance_display(balance)
pending = balance.total - balance.available
puts "\n#{'='*50}"
puts "アカウントBALANCE"
puts "="*50
puts "Total Balance: %12.2f %s" % [balance.total / 100.0, balance.currency.upcase]
puts "Available: %12.2f %s" % [balance.available / 100.0, balance.currency.upcase]
puts "Pending: %12.2f %s" % [pending / 100.0, balance.currency.upcase]
puts "="*50
end
# 使用例
balance = get_balance
format_balance_display(balance)
breakdown = get_balance_breakdown
puts "\n詳細内訳: #{breakdown}"
result = has_sufficient_balance?(100000)
if result[:sufficient]
puts "✓ 残高は十分です"
else
puts "✗ 残高が不足しています。不足額: #{result[:shortfall] / 100.0}"
end
<?php
require_once 'vendor/autoload.php';
define('OMISE_SECRET_KEY', 'skey_test_123456789');
// 現在のbalanceを取得
function getBalance() {
try {
$balance = OmiseBalance::retrieve();
echo "Balance情報:\n";
echo "------------------\n";
echo "合計: " . ($balance['total'] / 100) . " " . strtoupper($balance['currency']) . "\n";
echo "利用可能: " . ($balance['available'] / 100) . " " . strtoupper($balance['currency']) . "\n";
echo "通貨: " . strtoupper($balance['currency']) . "\n";
echo "ライブモード: " . ($balance['livemode'] ? 'true' : 'false') . "\n";
return $balance;
} catch (Exception $e) {
echo "Balanceの取得に失敗しました: {$e->getMessage()}\n";
throw $e;
}
}
// 詳細なbalance内訳を取得
function getBalanceBreakdown() {
$balance = OmiseBalance::retrieve();
$pending = $balance['total'] - $balance['available'];
return [
'total' => $balance['total'],
'available' => $balance['available'],
'pending' => $pending,
'currency' => $balance['currency'],
'breakdown' => [
'total_formatted' => number_format($balance['total'] / 100, 2) . ' ' . strtoupper($balance['currency']),
'available_formatted' => number_format($balance['available'] / 100, 2) . ' ' . strtoupper($balance['currency']),
'pending_formatted' => number_format($pending / 100, 2) . ' ' . strtoupper($balance['currency'])
]
];
}
// 十分なbalanceがあるか確認
function hasSufficientBalance($requiredAmount) {
$balance = OmiseBalance::retrieve();
return [
'sufficient' => $balance['available'] >= $requiredAmount,
'available' => $balance['available'],
'required' => $requiredAmount,
'shortfall' => max(0, $requiredAmount - $balance['available'])
];
}
// Balance表示をフォーマット
function formatBalanceDisplay($balance) {
$pending = $balance['total'] - $balance['available'];
echo "\n" . str_repeat('=', 50) . "\n";
echo "アカウントBALANCE\n";
echo str_repeat('=', 50) . "\n";
printf("Total Balance: %15s %s\n", number_format($balance['total'] / 100, 2), strtoupper($balance['currency']));
printf("Available: %15s %s\n", number_format($balance['available'] / 100, 2), strtoupper($balance['currency']));
printf("Pending: %15s %s\n", number_format($pending / 100, 2), strtoupper($balance['currency']));
echo str_repeat('=', 50) . "\n";
}
// 使用例
$balance = getBalance();
formatBalanceDisplay($balance);
$breakdown = getBalanceBreakdown();
print_r($breakdown);
$result = hasSufficientBalance(100000);
if ($result['sufficient']) {
echo "✓ 残高は十分です\n";
} else {
echo "✗ 残高が不足しています。不足額: " . ($result['shortfall'] / 100) . "\n";
}
?>
package main
import (
"fmt"
"log"
"github.com/omise/omise-go"
"github.com/omise/omise-go/operations"
)
const secretKey = "skey_test_123456789"
// GetBalance は現在のアカウントbalanceを取得します
func GetBalance() (*omise.Balance, error) {
client, err := omise.NewClient(secretKey, "")
if err != nil {
return nil, fmt.Errorf("clientの作成に失敗しました: %w", err)
}
balance := &omise.Balance{}
err = client.Do(balance, &operations.RetrieveBalance{})
if err != nil {
return nil, fmt.Errorf("balanceの取得に失敗しました: %w", err)
}
fmt.Println("Balance情報:")
fmt.Println("------------------")
fmt.Printf("合計: %.2f %s\n", float64(balance.Total)/100, balance.Currency)
fmt.Printf("利用可能: %.2f %s\n", float64(balance.Available)/100, balance.Currency)
fmt.Printf("通貨: %s\n", balance.Currency)
fmt.Printf("ライブモード: %v\n", balance.Livemode)
return balance, nil
}
// BalanceBreakdown は詳細なbalance情報を表します
type BalanceBreakdown struct {
Total int64
Available int64
Pending int64
Currency string
Breakdown map[string]string
}
// GetBalanceBreakdown は詳細なbalance内訳を返します
func GetBalanceBreakdown() (*BalanceBreakdown, error) {
client, err := omise.NewClient(secretKey, "")
if err != nil {
return nil, err
}
balance := &omise.Balance{}
err = client.Do(balance, &operations.RetrieveBalance{})
if err != nil {
return nil, err
}
pending := balance.Total - balance.Available
return &BalanceBreakdown{
Total: balance.Total,
Available: balance.Available,
Pending: pending,
Currency: balance.Currency,
Breakdown: map[string]string{
"total_formatted": fmt.Sprintf("%.2f %s", float64(balance.Total)/100, balance.Currency),
"available_formatted": fmt.Sprintf("%.2f %s", float64(balance.Available)/100, balance.Currency),
"pending_formatted": fmt.Sprintf("%.2f %s", float64(pending)/100, balance.Currency),
},
}, nil
}
// SufficientBalanceResult はbalanceチェック結果を表します
type SufficientBalanceResult struct {
Sufficient bool
Available int64
Required int64
Shortfall int64
}
// HasSufficientBalance は十分なbalanceがあるか確認します
func HasSufficientBalance(requiredAmount int64) (*SufficientBalanceResult, error) {
client, err := omise.NewClient(secretKey, "")
if err != nil {
return nil, err
}
balance := &omise.Balance{}
err = client.Do(balance, &operations.RetrieveBalance{})
if err != nil {
return nil, err
}
shortfall := int64(0)
if balance.Available < requiredAmount {
shortfall = requiredAmount - balance.Available
}
return &SufficientBalanceResult{
Sufficient: balance.Available >= requiredAmount,
Available: balance.Available,
Required: requiredAmount,
Shortfall: shortfall,
}, nil
}
// FormatBalanceDisplay は表示用にbalanceをフォーマットします
func FormatBalanceDisplay(balance *omise.Balance) {
pending := balance.Total - balance.Available
fmt.Println("\n==================================================")
fmt.Println("アカウントBALANCE")
fmt.Println("==================================================")
fmt.Printf("Total Balance: %15.2f %s\n", float64(balance.Total)/100, balance.Currency)
fmt.Printf("Available: %15.2f %s\n", float64(balance.Available)/100, balance.Currency)
fmt.Printf("Pending: %15.2f %s\n", float64(pending)/100, balance.Currency)
fmt.Println("==================================================")
}
func main() {
// 使用例
balance, err := GetBalance()
if err != nil {
log.Fatalf("Balanceの取得に失敗しました: %v", err)
}
FormatBalanceDisplay(balance)
breakdown, err := GetBalanceBreakdown()
if err != nil {
log.Fatalf("内訳の取得に失敗しました: %v", err)
}
fmt.Printf("\n詳細内訳: %+v\n", breakdown)
result, err := HasSufficientBalance(100000)
if err != nil {
log.Fatalf("Balanceチェックに失敗しました: %v", err)
}
if result.Sufficient {
fmt.Println("✓ 残高は十分です")
} else {
fmt.Printf("✗ 残高が不足しています。不足額: %.2f\n", float64(result.Shortfall)/100)
}
}
APIレスポンス
{
"object": "balance",
"livemode": false,
"location": "/balance",
"available": 500000,
"total": 750000,
"currency": "thb"
}
Balanceタイプの理解
Available BalanceとTotal Balance
// Available Balance: すぐに使用可能
// Total Balance: Available + Pending資金
function explainBalance(balance) {
const pending = balance.total - balance.available;
console.log('Balance説明:');
console.log(`Total Balance: ${balance.total / 100} ${balance.currency.toUpperCase()}`);
console.log(` ├─ Available: ${balance.available / 100} (使用可能)`);
console.log(` └─ Pending: ${pending / 100} (処理中)`);
console.log('\n実行可能な操作:');
console.log(` • 最大 ${balance.available / 100} までのtransferを作成`);
console.log(` • 最大 ${balance.available / 100} までのrefundを作成`);
console.log(` • Pendingはsettlement後にavailableになります`);
}
Pending Balance
Pending balanceには以下が含まれます:
- settlement待ちの最近のcharge
- 処理中のrefund
- 処理中のtransfer
- 保留中の異議申し立てcharge
def analyze_pending_balance():
"""Pending資金の理由を分析"""
balance = omise.Balance.retrieve()
pending = balance.total - balance.available
if pending > 0:
print(f"Pending Balance: {pending / 100:.2f} {balance.currency.upper()}")
print("\nPending資金の考えられる理由:")
print(" • Settlement待ちの最近のcharge(1〜2日)")
print(" • 処理中のrefund")
print(" • 処理中のtransfer")
print(" • 保留中の異議申し立てtransaction")
print("\nこれらの資金はsettlement後にavailableになります。")
else:
print("Pending資金はありません。すべてのbalanceが利用可能です。")
Balance監視
リアルタイム監視
class BalanceMonitor {
constructor(thresholds) {
this.thresholds = thresholds || {
low: 100000, // 1,000 THB
critical: 50000 // 500 THB
};
}
async checkBalance() {
const balance = await omise.balance.retrieve();
const status = {
current: balance.available,
status: this.getBalanceStatus(balance.available),
alerts: []
};
if (balance.available <= this.thresholds.critical) {
status.alerts.push({
level: 'critical',
message: `緊急: Balance at ${balance.available / 100} ${balance.currency.toUpperCase()}`
});
await this.notifyCriticalBalance(balance);
} else if (balance.available <= this.thresholds.low) {
status.alerts.push({
level: 'warning',
message: `警告: Low balance at ${balance.available / 100} ${balance.currency.toUpperCase()}`
});
await this.notifyLowBalance(balance);
}
return status;
}
getBalanceStatus(available) {
if (available <= this.thresholds.critical) return 'critical';
if (available <= this.thresholds.low) return 'low';
return 'healthy';
}
async notifyCriticalBalance(balance) {
console.log('🚨 緊急: Balanceが非常に少ない!');
// 緊急通知を送信
}
async notifyLowBalance(balance) {
console.log('⚠️ 警告: Balanceが少ない');
// 警告通知を送信
}
}
// 使用方法
const monitor = new BalanceMonitor({
low: 100000,
critical: 50000
});
setInterval(async () => {
const status = await monitor.checkBalance();
console.log('Balanceステータス:', status.status);
}, 3600000); // 1時間ごとにチェック
一般的なユースケース
1. 操作前のBalance確認
class BalanceGuard:
def __init__(self, buffer_amount=0):
self.buffer_amount = buffer_amount
def can_perform_operation(self, operation_type, amount):
"""操作を実行できるか確認"""
balance = omise.Balance.retrieve()
# 操作タイプに基づいて必要な金額を計算
if operation_type == 'transfer':
# Transfer + fee
required = amount + 2500 # 25 THB fee
elif operation_type == 'refund':
required = amount
else:
required = amount
# バッファを追加
required += self.buffer_amount
if balance.available < required:
return {
'allowed': False,
'reason': 'insufficient_balance',
'available': balance.available,
'required': required,
'shortfall': required - balance.available
}
return {
'allowed': True,
'available': balance.available,
'required': required,
'remaining_after': balance.available - required
}
# 使用方法
guard = BalanceGuard(buffer_amount=10000) # 100 THBのバッファを保持
check = guard.can_perform_operation('transfer', 100000)
if check['allowed']:
print(f"✓ 実行可能。残高 {check['remaining_after']/100:.2f} が残ります")
else:
print(f"✗ 実行不可。{check['shortfall']/100:.2f} 不足しています")
2. 日次Balanceレポート
class DailyBalanceReport
def generate_report
balance = Omise::Balance.retrieve
report = {
date: Date.today.to_s,
balance: {
total: balance.total,
available: balance.available,
pending: balance.total - balance.available,
currency: balance.currency
},
formatted: format_balance(balance),
status: assess_balance_health(balance),
recommendations: get_recommendations(balance)
}
print_report(report)
save_report(report)
report
end
def format_balance(balance)
{
total: "#{balance.total / 100.0} #{balance.currency.upcase}",
available: "#{balance.available / 100.0} #{balance.currency.upcase}",
pending: "#{(balance.total - balance.available) / 100.0} #{balance.currency.upcase}"
}
end
def assess_balance_health(balance)
case balance.available
when 0..50000
'critical'
when 50001..100000
'low'
when 100001..500000
'moderate'
else
'healthy'
end
end
def get_recommendations(balance)
recommendations = []
if balance.available < 100000
recommendations << "資金の追加を検討してください"
end
pending = balance.total - balance.available
if pending > balance.available * 2
recommendations << "Pending balanceが高い - settlementを確認してください"
end
recommendations
end
def print_report(report)
puts "\n#{'='*50}"
puts "日次BALANCEレポート - #{report[:date]}"
puts "="*50
puts "Total: #{report[:formatted][:total]}"
puts "Available: #{report[:formatted][:available]}"
puts "Pending: #{report[:formatted][:pending]}"
puts "Status: #{report[:status].upcase}"
unless report[:recommendations].empty?
puts "\n推奨事項:"
report[:recommendations].each { |r| puts " • #{r}" }
end
puts "="*50
end
def save_report(report)
# ファイルまたはデータベースに保存
File.open('balance_reports.log', 'a') do |f|
f.puts JSON.generate(report)
end
end
end
ベストプラクティス
1. 操作前に常にBalanceを確認
async function safeOperation(operationType, amount) {
const balance = await omise.balance.retrieve();
// 必要な金額を計算
let required = amount;
if (operationType === 'transfer') {
required += 2500; // Transfer手数料を追加
}
// Balanceをチェック
if (balance.available < required) {
throw new Error(`残高不足: 必要 ${required}, 保有 ${balance.available}`);
}
// 操作を続行
console.log(`✓ 十分なbalance。${operationType}を実行します`);
return true;
}