Below are two different integration strategies for creating a digital wallet using Ledgers. Event Handlers allow you to stream information to be ledgered based on previously-created handler templates. The Transactions API gives you full control over when and how you ledger activity.

TAB-Event Handlers

# Overview

The creation of the LT requires two objects to exist before we begin translating. The first is the:

## Ledger Event Handler

`POST /api/ledger_event_handlers`

### Example Request



### Example Response



The Event Handler dictates the formatting of the Ledgerable Event to the Ledger Transaction via the `ledger_transaction_template`.

Clients would need to build the `ledger_transaction` object within the `ledger_transaction_template` object. They have two additional forms of data injection beyond raw input:

  1. Ledgerable Event fields may be referenced via the `{{ledgerable_event.field_name}}` syntax. Nested fields can be accessed using `.` delimiters (e.g. `{ foo: { bar: baz } } }`, `{{ledgerable_event.foo.bar}}` would yield `baz`)

  2. Outside of the `ledger_transaction_template` there is the `variables` key. Variables are a `name => object` mapping, currently only Ledger Accounts are supported as an object. Ledger Accounts may be fetched and referenced from the `ledger_transaction_template` by writing a query to the ledger accounts table. Any field that exists in the [Ledger Account](🔗) object may be accessed the same way.

Logic is not evaluated, and we will error in the case where there are either mixed `{{field_name}}` and raw string inputs (e.g. `{{custom_data.foo}} and more stuff here}}`).

The `conditions` field dictates whether we apply a Event Handler to a Ledgerable Event. We currently **_only_** support specifying the `value` field in the request. This is to guarantee matching only one ledgerable event to one event handler.

## Ledgerable Event

`POST /api/ledgerable_events`

### Example Request



### Example Response



The Ledgerable Event is the financial event occurring on the partner side. The only field required is `name`, otherwise it is up to clients to decide what they provide.

On creation of a Ledgerable Event, we match the `name` of the event to the `conditions` field of the Event Handler. **If there is no match, we error**. On a match, the event is supplied as input to the template, creating an LT at the same time.

On a successful response, there are always two objects created: the ledgerable event (in the response), and the Ledger Transaction. The Ledger Transaction has the Ledgerable Event as the Ledgerable ID.

In the example above, if we were to `GET` the ledger transaction with the provided ID in the response by querying the `ledgerable_id`, we’d receive:



Notice the bolded fields were injected from the ledgerable event and variables.

TAB-Transactions API

## Overview

This guide will explain how to use the [Ledgers API](🔗) for a card product. Any card product needs to be able to determine what balances users can spend or have spent using their cards. The Ledgers API lets you record these balances at scale alongside other transactions in your app.

In this example, we will assume you are building a product called Swipe that allows users to deposit funds and spend those funds using a card. We will demonstrate a simple flow here with a few events:

  • The user deposits funds

  • The user swipes their card and you authorize the transaction

  • A payment is made to the card issuer

The Modern Treasury ledger will serve as a central source of truth on money movements while Swipe interacts with multiple external systems:

  • A service to initiate bank payments, like [Modern Treasury Payments](🔗)

  • A service to issue cards, like Lithic or Marqeta

## Setup

First, you will make a ledger for Swipe.



This will return a ledger object with an ID to be used in the following step.



Next, you can create 3 ledger accounts to represent balances you need your application to track:

  • Cash in Swipe's bank account

  • Funds held for a given user, Jane Doe. When Jane signs up, you create this account and issue her a card through your card issuer.

  • Funds to be settled with the card issuer

Note that the cash account is `normal_balance=debit` (because it represents a balance that you hold), whereas the user wallet and issuer accounts are `normal_balance=credit` (because they represent balances that you owe).



This will return the 3 ledger accounts you've created.



## Recording a deposit

Now that the setup is done, you can write to the ledger to record what happens in your business.

First, you'll pull funds from Jane Doe using your external payment provider. Once the payment is executed, you create a ledger transaction to record that Jane Doe has deposited $100 in her wallet. This will recognize that $100 has entered your bank account, and that $100 of funds are held on behalf of Jane.



Because you control the ledger, you can allow Jane to spend these in-app funds in any number of ways. For example, you could allow her to send funds to another Swipe user. To see how this would be represented in the ledger, refer to the [Quickstart for Digital Wallets](🔗).

## Authorizing a card transaction

Jane can also spend funds through her card. When Jane swipes her card to buy a $50 item, you receive an authorization request from your card issuing partner.

Your will need to check Jane's balance in your ledger in order to determine whether to authorize this payment, by querying the [Get Ledger Account](🔗) endpoint:



This will return Jane's live wallet balance.



Based on Jane's sufficient balance and any other attributes of the card swipe you want to consider, you decide to authorize this transaction.

First, you'll write a transaction putting an authorization hold on $50 on Jane's account and noting that $50 should be settled with your card issuer. When creating this transaction, you can refer to the `lock_version` of Jane's account balance to ensure that her account balance has not changed since you last checked it. The transaction will fail if the balance has changed (for example, because Jane has already spent her funds in another part of your app).



If the transaction is created, you have successfully put a hold on Jane's in-app funds. You can respond to your issuer's request authorizing the card transaction.

## Settling with the issuer

Finally, at the end of the day, you can settle with your card issuer. This involves sending them the funds that users have spent that day through your payment provider.

Once the payment is executed through your external provider, you can create a ledger transaction recording that $50 has left your bank account, and that $50 is no longer owed to the issuer.