Skip to main content

Viewing Transaction History

Transaction history provides a complete record of all activities affecting your Omise account balance. This guide covers viewing, filtering, searching, and exporting transaction data.

Overviewโ€‹

Transaction history includes:

  • Charges: Customer payments received
  • Refunds: Money returned to customers
  • Transfers: Payouts to recipients
  • Fees: Platform and transaction fees
  • Adjustments: Manual balance corrections
  • Disputes: Chargeback-related transactions

Key Featuresโ€‹

  • Complete History: All balance-affecting transactions
  • Advanced Filtering: Filter by type, date, amount, status
  • Search Capability: Find specific transactions quickly
  • Pagination: Handle large transaction volumes
  • Export Options: Download data for reporting
  • Real-time Updates: See transactions as they occur

Retrieving Transactionsโ€‹

List All Transactionsโ€‹

const omise = require('omise')({
secretKey: 'skey_test_123456789',
});

// Get recent transactions
async function getTransactions(limit = 20) {
try {
const transactions = await omise.transactions.list({
limit: limit,
order: 'reverse_chronological'
});

console.log(`Found ${transactions.total} transactions`);
console.log(`Showing ${transactions.data.length} of ${transactions.total}`);

transactions.data.forEach(txn => {
console.log(`${txn.id}: ${txn.type} - ${txn.amount / 100} ${txn.currency.toUpperCase()}`);
});

return transactions;
} catch (error) {
console.error('Failed to retrieve transactions:', error.message);
throw error;
}
}

// Get transactions with pagination
async function getPaginatedTransactions(page = 1, perPage = 20) {
const offset = (page - 1) * perPage;

const transactions = await omise.transactions.list({
limit: perPage,
offset: offset,
order: 'reverse_chronological'
});

return {
data: transactions.data,
pagination: {
page: page,
per_page: perPage,
total: transactions.total,
total_pages: Math.ceil(transactions.total / perPage),
has_more: transactions.data.length === perPage
}
};
}

// Get transactions by date range
async function getTransactionsByDateRange(startDate, endDate) {
// Convert dates to ISO format
const from = new Date(startDate).toISOString();
const to = new Date(endDate).toISOString();

const transactions = await omise.transactions.list({
from: from,
to: to,
order: 'reverse_chronological'
});

console.log(`Transactions from ${startDate} to ${endDate}:`);
console.log(`Total: ${transactions.total}`);

return transactions;
}

// Get transactions by type
async function getTransactionsByType(type) {
// Types: 'credit', 'debit'
const transactions = await omise.transactions.list({
order: 'reverse_chronological',
limit: 100
});

// Filter by type (API doesn't support direct type filtering)
const filtered = transactions.data.filter(txn => txn.type === type);

console.log(`Found ${filtered.length} ${type} transactions`);
return filtered;
}

// Example usage
getTransactions(10);

getPaginatedTransactions(1, 20).then(result => {
console.log(`Page ${result.pagination.page} of ${result.pagination.total_pages}`);
});

getTransactionsByDateRange('2024-01-01', '2024-01-31');
getTransactionsByType('credit');

API Responseโ€‹

{
"object": "list",
"data": [
{
"object": "transaction",
"id": "trxn_test_5xyz789abc",
"type": "credit",
"amount": 100000,
"currency": "thb",
"created": "2024-01-15T10:30:00Z",
"source": "chrg_test_123456789"
}
],
"limit": 20,
"offset": 0,
"total": 150,
"location": "/transactions",
"order": "chronological",
"from": "2024-01-01T00:00:00Z",
"to": "2024-01-31T23:59:59Z"
}

Filtering & Searchingโ€‹

Advanced Filteringโ€‹

class TransactionFilter {
constructor() {
this.filters = {};
}

async byDateRange(startDate, endDate) {
this.filters.from = new Date(startDate).toISOString();
this.filters.to = new Date(endDate).toISOString();
return this;
}

async byType(type) {
this.filters.type = type; // 'credit' or 'debit'
return this;
}

async byAmountRange(minAmount, maxAmount) {
this.filters.minAmount = minAmount;
this.filters.maxAmount = maxAmount;
return this;
}

async execute() {
const transactions = await omise.transactions.list({
from: this.filters.from,
to: this.filters.to,
limit: 100,
order: 'reverse_chronological'
});

let filtered = transactions.data;

// Apply client-side filters
if (this.filters.type) {
filtered = filtered.filter(txn => txn.type === this.filters.type);
}

if (this.filters.minAmount || this.filters.maxAmount) {
filtered = filtered.filter(txn => {
if (this.filters.minAmount && txn.amount < this.filters.minAmount) return false;
if (this.filters.maxAmount && txn.amount > this.filters.maxAmount) return false;
return true;
});
}

return filtered;
}
}

// Usage
const filter = new TransactionFilter();
const results = await filter
.byDateRange('2024-01-01', '2024-01-31')
.byType('credit')
.byAmountRange(100000, 1000000)
.execute();

console.log(`Found ${results.length} matching transactions`);

Exporting Transactionsโ€‹

Export to CSVโ€‹

import csv
from datetime import datetime, timedelta

def export_transactions_csv(start_date, end_date, filename='transactions.csv'):
"""Export transactions to CSV"""

# Get transactions
transactions = omise.Transaction.retrieve(
created={
'gte': start_date.isoformat(),
'lte': end_date.isoformat()
},
limit=1000,
order='chronological'
)

# Write to CSV
with open(filename, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)

# Write header
writer.writerow([
'Transaction ID',
'Date',
'Type',
'Amount',
'Currency',
'Source',
'Description'
])

# Write data
for txn in transactions.data:
writer.writerow([
txn.id,
datetime.fromtimestamp(txn.created).strftime('%Y-%m-%d %H:%M:%S'),
txn.type,
txn.amount / 100,
txn.currency.upper(),
txn.source if hasattr(txn, 'source') else 'N/A',
f"{txn.type.capitalize()} transaction"
])

print(f"Exported {len(transactions.data)} transactions to {filename}")
return filename

# Usage
start = datetime.now() - timedelta(days=30)
end = datetime.now()
export_transactions_csv(start, end, 'monthly_transactions.csv')

Generate Reportsโ€‹

class TransactionReportGenerator
def generate_monthly_report(year, month)
start_date = Date.new(year, month, 1)
end_date = start_date.next_month - 1

transactions = Omise::Transaction.retrieve(
created: {
gte: start_date.to_time.iso8601,
lte: end_date.to_time.iso8601
},
limit: 1000,
order: 'chronological'
)

report = {
period: "#{start_date.strftime('%B %Y')}",
summary: calculate_summary(transactions),
by_type: group_by_type(transactions),
by_day: group_by_day(transactions),
transactions: transactions.data
}

generate_report_html(report)
generate_report_pdf(report)

report
end

private

def calculate_summary(transactions)
{
total_transactions: transactions.data.length,
total_credit: transactions.data.select { |t| t.type == 'credit' }.sum(&:amount),
total_debit: transactions.data.select { |t| t.type == 'debit' }.sum(&:amount),
net: transactions.data.sum { |t| t.type == 'credit' ? t.amount : -t.amount }
}
end

def group_by_type(transactions)
transactions.data.group_by(&:type).transform_values do |txns|
{
count: txns.length,
total: txns.sum(&:amount)
}
end
end

def group_by_day(transactions)
transactions.data.group_by { |t| Date.parse(t.created_at.to_s) }
.transform_values { |txns| txns.length }
end
end

Common Use Casesโ€‹

1. Monthly Financial Reportโ€‹

async function generateMonthlyFinancialReport(year, month) {
const startDate = new Date(year, month - 1, 1);
const endDate = new Date(year, month, 0);

const transactions = await omise.transactions.list({
from: startDate.toISOString(),
to: endDate.toISOString(),
limit: 1000,
order: 'chronological'
});

const report = {
period: `${startDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}`,
summary: {
total_transactions: transactions.total,
credits: 0,
debits: 0,
fees: 0,
net: 0
},
daily_breakdown: {},
transactions: transactions.data
};

transactions.data.forEach(txn => {
if (txn.type === 'credit') {
report.summary.credits += txn.amount;
} else if (txn.type === 'debit') {
report.summary.debits += txn.amount;
}

// Group by day
const day = new Date(txn.created).toISOString().split('T')[0];
if (!report.daily_breakdown[day]) {
report.daily_breakdown[day] = { credits: 0, debits: 0, count: 0 };
}
report.daily_breakdown[day].count++;
report.daily_breakdown[day][txn.type === 'credit' ? 'credits' : 'debits'] += txn.amount;
});

report.summary.net = report.summary.credits - report.summary.debits;

console.log(`Monthly Report: ${report.period}`);
console.log(`Transactions: ${report.summary.total_transactions}`);
console.log(`Credits: ${report.summary.credits / 100} THB`);
console.log(`Debits: ${report.summary.debits / 100} THB`);
console.log(`Net: ${report.summary.net / 100} THB`);

return report;
}

// Usage
generateMonthlyFinancialReport(2024, 1);

2. Transaction Reconciliation Helperโ€‹

class TransactionReconciliation:
def __init__(self, start_date, end_date):
self.start_date = start_date
self.end_date = end_date
self.transactions = self.fetch_transactions()

def fetch_transactions(self):
"""Fetch all transactions for period"""
return omise.Transaction.retrieve(
created={
'gte': self.start_date.isoformat(),
'lte': self.end_date.isoformat()
},
limit=1000,
order='chronological'
)

def match_with_bank_statement(self, bank_statement):
"""Match transactions with bank statement"""
matched = []
unmatched_transactions = []
unmatched_bank = []

txn_dict = {t.id: t for t in self.transactions.data}

for bank_entry in bank_statement:
# Try to find matching transaction
matching_txn = self.find_matching_transaction(
bank_entry,
self.transactions.data
)

if matching_txn:
matched.append({
'transaction': matching_txn,
'bank_entry': bank_entry,
'match_confidence': 'high'
})
del txn_dict[matching_txn.id]
else:
unmatched_bank.append(bank_entry)

unmatched_transactions = list(txn_dict.values())

return {
'matched': matched,
'unmatched_transactions': unmatched_transactions,
'unmatched_bank': unmatched_bank,
'reconciliation_rate': len(matched) / len(bank_statement) * 100
}

def find_matching_transaction(self, bank_entry, transactions):
"""Find transaction matching bank entry"""
# Match by amount and date
for txn in transactions:
if (abs(txn.amount - bank_entry['amount']) < 100 and # Allow 1 THB difference
self.dates_match(txn.created, bank_entry['date'])):
return txn
return None

def dates_match(self, txn_timestamp, bank_date, tolerance_days=2):
"""Check if dates match within tolerance"""
txn_date = datetime.fromtimestamp(txn_timestamp).date()
return abs((txn_date - bank_date).days) <= tolerance_days

Best Practicesโ€‹

1. Implement Pagination for Large Datasetsโ€‹

async function getAllTransactions() {
const allTransactions = [];
let offset = 0;
const limit = 100;
let hasMore = true;

while (hasMore) {
const batch = await omise.transactions.list({
limit: limit,
offset: offset,
order: 'reverse_chronological'
});

allTransactions.push(...batch.data);

offset += limit;
hasMore = batch.data.length === limit;

console.log(`Fetched ${allTransactions.length} transactions...`);
}

return allTransactions;
}

2. Cache Transaction Dataโ€‹

import json
from datetime import datetime

class TransactionCache:
def __init__(self, cache_file='transaction_cache.json'):
self.cache_file = cache_file
self.cache = self.load_cache()

def load_cache(self):
"""Load cache from file"""
try:
with open(self.cache_file, 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}

def save_cache(self):
"""Save cache to file"""
with open(self.cache_file, 'w') as f:
json.dump(self.cache, f)

def get_transactions(self, start_date, end_date, force_refresh=False):
"""Get transactions with caching"""
cache_key = f"{start_date}_{end_date}"

if not force_refresh and cache_key in self.cache:
print("Using cached data")
return self.cache[cache_key]

print("Fetching fresh data")
transactions = omise.Transaction.retrieve(
created={
'gte': start_date.isoformat(),
'lte': end_date.isoformat()
},
limit=1000
)

self.cache[cache_key] = {
'data': [self.serialize_transaction(t) for t in transactions.data],
'cached_at': datetime.now().isoformat()
}
self.save_cache()

return self.cache[cache_key]

def serialize_transaction(self, txn):
"""Convert transaction to dict for caching"""
return {
'id': txn.id,
'type': txn.type,
'amount': txn.amount,
'currency': txn.currency,
'created': txn.created
}

FAQโ€‹

How far back can I retrieve transactions?โ€‹

You can retrieve transactions from any time period since your account was created. However, for very old transactions, consider using date ranges to optimize API performance.

Can I filter transactions by payment method?โ€‹

The API doesn't directly support filtering by payment method. You'll need to retrieve transactions and filter them client-side based on the source field.

How do I get real-time transaction updates?โ€‹

Use webhooks to receive real-time notifications when transactions occur. This is more efficient than polling the transaction list.

What's the maximum number of transactions I can retrieve in one request?โ€‹

The maximum limit per request is 100. For larger datasets, use pagination with the offset parameter.

Can I delete transactions from my history?โ€‹

No, transactions cannot be deleted. They form a permanent audit trail. If you need to exclude certain transactions from reports, filter them out in your application logic.

How do I export transactions for accounting software?โ€‹

Use the CSV export functionality or integrate directly with your accounting software using the Omise API. Many accounting platforms offer Omise integrations.

Why don't I see a recent transaction in the list?โ€‹

Transactions may take a few seconds to appear in the list. If using webhooks, you'll be notified immediately, but the transaction might not be in the list API yet.

Can I search transactions by customer email?โ€‹

The transaction API doesn't support searching by customer details. You'll need to retrieve the charge associated with the transaction and check its customer information.

Next Stepsโ€‹