Ledger Entry Details

Transaction receipt and proof

Ledger Entry Details

The Ledger Entry Details endpoint provides a detailed receipt for a specific ledger movement, perfect for audit documentation, customer support, and accounting proof.

What is a Ledger Entry Receipt?

Each movement in your ledger statement has a unique ledgerEntryId. Use this ID to retrieve comprehensive details about that specific transaction, including:

  • Balance before and after the movement
  • Merchant and account details
  • References to associated orders or settlements
  • Human-readable description

Use Cases

When to use Ledger Entry Details:

  • Audit documentation: Generate proof of specific transactions
  • Customer support: Quickly retrieve transaction details for inquiries
  • Accounting proof: Provide detailed receipts for bookkeeping
  • Dispute resolution: Document transaction details for disputes
  • Compliance: Maintain detailed records for regulatory requirements

API Endpoint

GET /api/v1/organizations/{organizationId}/merchants/{merchantId}/accounts/{accountId}/reports/ledger-entry/{ledgerEntryId}

Path Parameters

ParameterRequiredDescription
organizationIdYesOrganization ID
merchantIdYesMerchant ID
accountIdYesVirtual account ID
ledgerEntryIdYesLedger entry ID (from ledger statement)

Quick Example

1const response = await axios.get(
2 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/137`,
3 {
4 headers: { 'Authorization': `Bearer ${token}` }
5 }
6);
7
8console.log('Entry ID:', response.data.ledgerEntryId);
9console.log('Amount:', response.data.amount, response.data.currency);
10console.log('Balance Before:', response.data.balanceBefore);
11console.log('Balance After:', response.data.balanceAfter);
12console.log('Description:', response.data.description);

Understanding the Response

1{
2 "ledgerEntryId": "137",
3 "accountId": "acc_0031c537-2301-40ab-9153-0f7c48505350",
4 "merchantId": "mrc_2e8f96ab-dbd5-45f9-b4b6-645945daf340",
5 "merchantName": "Acme Corporation",
6 "type": "credit",
7 "amount": "1000000.00",
8 "currency": "CLP",
9 "postedAt": "2025-01-15T10:30:00.000Z",
10 "description": "PAYIN from Juan Pérez - Bank transfer received",
11 "category": "PAYIN",
12 "references": {
13 "orderId": "ord_abc123",
14 "settlementId": null
15 },
16 "balanceBefore": "4000000.00",
17 "balanceAfter": "5000000.00",
18 "generatedAt": "2025-01-31T12:00:00.000Z"
19}

Response Fields Explained

FieldDescription
ledgerEntryIdUnique identifier for this ledger entry
merchantIdMerchant ID associated with the account
merchantNameHuman-readable merchant name
typecredit (increases balance) or debit (decreases balance)
amountTransaction amount
currencyCurrency symbol
postedAtTimestamp when movement was recorded
descriptionHuman-readable description
categoryMovement category (PAYIN, PAYOUT, SETTLEMENT, etc.)
references.orderIdAssociated order ID (if applicable)
references.settlementIdAssociated settlement ID (if applicable)
balanceBeforeAccount balance before this movement
balanceAfterAccount balance after this movement

The balanceBefore and balanceAfter fields provide audit-ready proof of how the transaction affected the account balance.


Workflow: From Statement to Details

The typical workflow is to first retrieve a ledger statement, then get details for specific entries:


Complete Example: Statement to Details

1async function getTransactionReceipt(orgId, merchantId, accountId, date, token) {
2 // Step 1: Get ledger statement for the date
3 const statementResponse = await axios.get(
4 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-statement`,
5 {
6 params: {
7 from: date,
8 to: date
9 },
10 headers: { 'Authorization': `Bearer ${token}` }
11 }
12 );
13
14 const movements = statementResponse.data.movements;
15 console.log(`Found ${movements.length} movements on ${date}`);
16
17 // Step 2: Get details for each movement
18 const receipts = [];
19
20 for (const movement of movements) {
21 console.log(`\nFetching details for entry ${movement.ledgerEntryId}...`);
22
23 const detailResponse = await axios.get(
24 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/${movement.ledgerEntryId}`,
25 {
26 headers: { 'Authorization': `Bearer ${token}` }
27 }
28 );
29
30 const receipt = detailResponse.data;
31 receipts.push(receipt);
32
33 // Print receipt
34 console.log('='.repeat(50));
35 console.log('TRANSACTION RECEIPT');
36 console.log('='.repeat(50));
37 console.log(`Entry ID: ${receipt.ledgerEntryId}`);
38 console.log(`Date: ${receipt.postedAt}`);
39 console.log(`Merchant: ${receipt.merchantName}`);
40 console.log(`Type: ${receipt.type.toUpperCase()}`);
41 console.log(`Category: ${receipt.category}`);
42 console.log(`Amount: ${receipt.amount} ${receipt.currency}`);
43 console.log('-'.repeat(50));
44 console.log(`Balance Before: ${receipt.balanceBefore} ${receipt.currency}`);
45 console.log(`Balance After: ${receipt.balanceAfter} ${receipt.currency}`);
46 console.log('-'.repeat(50));
47 console.log(`Description: ${receipt.description}`);
48
49 if (receipt.references.orderId) {
50 console.log(`Order ID: ${receipt.references.orderId}`);
51 }
52 if (receipt.references.settlementId) {
53 console.log(`Settlement ID: ${receipt.references.settlementId}`);
54 }
55
56 console.log('='.repeat(50));
57 }
58
59 return receipts;
60}
61
62// Usage: Get all receipts for January 15, 2025
63const receipts = await getTransactionReceipt(
64 'org3_xxx',
65 'mrc_xxx',
66 'acc_xxx',
67 '2025-01-15',
68 token
69);

Finding the Ledger Entry ID

The ledgerEntryId is available in the ledger statement response. Here’s how to find a specific entry:

1// Find ledger entry by associated order
2const statement = await getLedgerStatement(orgId, merchantId, accountId, from, to, token);
3
4const targetOrderId = 'ord_abc123';
5const entry = statement.movements.find(m => m.orderId === targetOrderId);
6
7if (entry) {
8 console.log(`Found entry ${entry.ledgerEntryId} for order ${targetOrderId}`);
9 // Now fetch details
10 const receipt = await getLedgerEntryDetails(orgId, merchantId, accountId, entry.ledgerEntryId, token);
11}

Error Handling

Common Errors:

  • 404 Not Found: Ledger entry ID doesn’t exist or doesn’t belong to the specified account
  • 403 Forbidden: Entry doesn’t belong to the merchant or insufficient permissions
  • 401 Unauthorized: Invalid or expired token
Error Handling
1async function safeGetLedgerEntry(orgId, merchantId, accountId, entryId, token) {
2 try {
3 const response = await axios.get(
4 `https://api.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/accounts/${accountId}/reports/ledger-entry/${entryId}`,
5 {
6 headers: { 'Authorization': `Bearer ${token}` }
7 }
8 );
9 return response.data;
10 } catch (error) {
11 if (error.response?.status === 404) {
12 console.error(`Ledger entry ${entryId} not found`);
13 return null;
14 }
15 if (error.response?.status === 403) {
16 console.error(`Access denied to ledger entry ${entryId}`);
17 return null;
18 }
19 throw error;
20 }
21}

Next Steps