Transaction Flow

Learn about the transaction flow.

Note that the transaction flow permutations described on this page reflect the Lithic platform's current production behavior. A few improvements to the transaction object will be effective in Sandbox on January 4, 2023 and in Production on February 8, 2023. For all currently implementing users, please refer to the updated version of this page to be prepared for the new behavior.

Basic Transaction Flow Overview

Many transactions follow a basic flow consisting of an initial authorization and a subsequent clearing message to settle funds:

  1. Network transmits ISO-8583 MTI 0100 message to Lithic.
  2. Lithic converts the ISO-8583 message to transaction model JSON and sends an ASA request to the client.
  3. The client responds with HTTP 200 ASA JSON response body with result APPROVED. *HTTP 200 & ASA response required.
  4. Lithic converts the ASA response body to ISO-8583 response and returns to the network.
  5. Acquirer initiates completion of the transactions and Lithic receives ISO-8583 MTI 0220 advice from the network.
  6. Lithic processes the ISO-8583 message and responds with an approved response back to the network.
  7. Lithic converts the ISO-8583 message to a JSON transaction model with status SETTLED and sends a Clearing message to the client. Step 6 & 7 are processed concurrently.
  8. The client responds with HTTP response code 200 to acknowledge. *HTTP 200 required.

Detailed Transaction Flow Guide

While many transactions will follow the above flow, at times more complicated lifecycles occur. At each step in the transaction lifecycle, Lithic will send the client a webhook containing information about the transaction (see Webhooks for information about the different types of webhooks sent). There are eight message types that can be sent without a prior related transaction in Lithic’s system (i.e., with a new transaction token). Across those eight messages, there are two places that the client can receive the webhook:

  • Authorization stream access (ASA) endpoint
  • Transaction webhook endpoint

See below for a list of supported transaction flows:

Since merchant behavior can be non-standard, there is a possibility that transactions will come through the network that don’t follow the outlined flows. These transactions are rare and potentially subject to review if the merchant behavior breaks network rules.

📘

Ledger Integration

If you’re using Lithic to integrate with a 3rd party or internal ledger, you’ll need to be able to react and respond to the messages detailed in this guide. Your system should have the ability to keep track of available customer balances, place holds on authorized funds, and internally transfer cleared amounts to an account used for daily settlement. This can be done in one of three ways:

  • Integrate with a third party wallet provider
  • Pool your customer funds, and use a 3rd party core system for ledger accounting
  • Pool your customer funds, and build a ledgering system internally

When Lithic sends a request to your ASA endpoint, your approval decision should be based on the available customer balance (total balance minus any pending and settled transactions).

In order to ensure your ledger remains current, whenever Lithic sends an advice message to your transaction webhook endpoint, you should update your ledger based on the information in the transaction. At each point in the transaction lifecycle, you can calculate the hold amount and settled amount as follows:

  • Hold amount: authorization_amount minus settled_amount
  • Settled amount: settled_amount

Message Types Originating with an ASA Request

For new transactions that require approval from the network, Lithic will send an ASA request to the client’s configured endpoint. These requests can be one of five types, as designated in the status field in the ASA request:

1: Authorization

An initial authorization request through the ASA endpoint is the typical “happy path” of a dual-message system (DMS) transaction. An example ASA request is below:

{
  "status": "AUTHORIZATION",
  "amount": 900,
  "acquirer_fee": 100,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": []
}

In this example, the cardholder has initiated a $9 DMS transaction, on which a $1 acquirer fee has been levied. The events array will always be empty for authorization requests.

At this point, the client has three options: approve the transaction, decline the transaction, or approve the authorization up to a specific amount (see Partial Approval for more information). To do this, the client will respond to the ASA request using result APPROVED to accept the authorization, or decline with the appropriate reason.

Once the response is sent to Lithic, the client will receive an advice message at their transaction webhook endpoint notifying the client of the result of the authorization.

If the authorization is declined, a message will come at the transaction webhook endpoint notifying the client on the decline. In this situation, the payload of the message will look like the following:

{
  "status": "DECLINED",
  "amount": 1000,
  "acquirer_fee": 100,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "UNAUTHORIZED_MERCHANT"
    }
  ]
}

Note: At this point, the acquirer_fee is included in the amount field both on the overall transaction object and in the events array.

This decline can happen in two situations. The first is when the client responds to the ASA request any result other than APPROVED (i.e., an expected decline). In this case, the result field in the response will contain the decline result used by the client.

The other situation is when the client responds to the ASA request with result APPROVED, but returns an error, exceeds the allotted response time, or returns a malformed response. These declines should be treated in the same manner as a decline via ASA response. Once a transaction has been declined, no further related messages are expected from Lithic related to the transaction.

In the case of an approved authorization, the client will receive a message at the transaction webhook endpoint with the following information:

{
  "status": "PENDING",
  "amount": 1000,
  "acquirer_fee": 100,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    }
  ]
}

As the transaction is now in a pending state, the client should wait for additional messages to come through the network to update the transaction. There are three possible message types after the initial authorization: CLEARING, VOID, and AUTHORIZATION_ADVICE.

Authorization > Clearing

Continuing along the DMS “happy path,” after an authorization is approved, the client may receive a Clearing message at the transaction webhook endpoint:

{
  "status": "SETTLED",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "settled_amount": 1000,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "CLEARING",
      "result": "APPROVED"
    }
  ]
}

When a Clearing message is received for a previously authorized transaction, there are three situations that can arise:

  1. The Clearing message is more than the authorization amount. This is most commonly seen in the case of a tip at a restaurant or bar.
  2. The Clearing message is the same as the authorization amount. This is the most common flow that is seen in the majority of transactions.
  3. The Clearing message is less than the authorization amount. This is most common in the case of a “multiple completion,” where a merchant fulfills a transaction at multiple times (e.g., a merchant ships two packages separately from a single online order).

In all of the above cases, the status of the transaction will be SETTLED. This means that there can be additional Clearing or Void messages that come on a SETTLED transaction, as well as returns. See Multiple Completion for information on these situations.

Authorization > Void

When the merchant elects to cancel an order before it has been settled, the client will receive a Void message at the transaction webhook endpoint. Similar to Clearing messages, there are multiple situations that can arise. The first and most common is that the voided amount matches the authorization amount. In this case, the status will be VOIDED and the authorization_amount will be zero:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "VOID",
      "result": "APPROVED"
    }
  ]
}

The other possible case is that the voided amount is less than the authorized amount:

{
  "status": "PENDING",
  "amount": 100,
  "acquirer_fee": 0,
  "authorization_amount": 100,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -900,
      "type": "VOID",
      "result": "APPROVED"
    }
  ]
}

In this situation, the authorization_amount will equal the difference between the originally authorized and voided amounts, and the status will remain PENDING until another message comes to either clear or void the remaining authorized amount.

After a Void event, there can be additional Clearing and Void events received on the transaction. Once the first Clearing is received, Return events can also be sent. See Multiple Completion for more information.

Authorization > Authorization Advice

After an approved authorization, a message of type AUTHORIZATION_ADVICE can be received at the client’s transaction webhook endpoint. Authorization Advice messages update the authorized amount of previous authorizations without clearing any funds. An example Authorization Advice message can be found below:

{
  "status": "PENDING",
  "amount": 2000,
  "acquirer_fee": 0,
  "authorization_amount": 2000,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 2000,
      "type": "AUTHORIZATION_ADVICE",
      "result": "APPROVED"
    }
  ]
}

In this situation, an Authorization Advice message has come through that changed the authorization amount to $20 (from the original $10). A typical situation where an Authorization Advice like the above example is sent is when a user makes a gasoline purchase (an initial authorization is sent before the gas is pumped, then updated to the true amount afterwards).

After receiving an Authorization Advice message, a further message is expected that will either clear or void the authorized amount. An example of each is below:

{
  "status": "SETTLED",
  "amount": 2000,
  "acquirer_fee": 0,
  "authorization_amount": 2000,
  "settled_amount": 2000,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 2000,
      "type": "AUTHORIZATION_ADVICE",
      "result": "APPROVED"
    },
    {
      "amount": 2000,
      "type": "CLEARING",
      "result": "APPROVED"
    }
  ]
}
{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 2000,
      "type": "AUTHORIZATION_ADVICE",
      "result": "APPROVED"
    },
    {
      "amount": -2000,
      "type": "VOID",
      "result": "APPROVED"
    }
  ]
}

When an Authorization Advice event occurs on a transaction, multiple Clearing or Void events are not expected to complete the transaction: only a single Clearing or Void will be used to finalize.

Another situation in which an Authorization Advice message is sent is when a decline occurs based on an upstream switch during initial authorization (e.g., the client ASA response is received by Lithic, but there is a timeout between Lithic and the network). In this case, an Authorization Advice message is sent with status DECLINED:

{
  "status": "DECLINED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "AUTHORIZATION_ADVICE",
      "result": "DECLINED"
    }
  ]
}

No further messages are expected from Lithic after an Authorization Advice decline.

Multiple Completion

After a transaction has been fully or partially cleared, there are multiple additional events that can occur associated with the same transaction.

One event type that can be received is a return. Sometimes returns are not able to be mapped to the original transaction due to lack of information provided by the merchant, but when the return is able to be associated, it will appear as a RETURN event on the existing transaction:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "CLEARING",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "RETURN",
      "result": "APPROVED"
      ]
    }

In the above example, an initial authorization for $10 is cleared before being returned.

Once a transaction has been at least partially cleared, there can be any permutation of Return, Clearing, and Void messages on the transaction. An example transaction is below:

{
  "status": "SETTLED",
  "amount": 100,
  "acquirer_fee": 0,
  "authorization_amount": 100,
  "settled_amount": 100,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 800,
      "type": "CLEARING",
      "result": "APPROVED"
    },
    {
      "amount": -100,
      "type": "VOID",
      "result": "APPROVED"
    },
    {
      "amount": 100,
      "type": "CLEARING",
      "result": "APPROVED"
    },
    {
      "amount": -800,
      "type": "RETURN",
      "result": "APPROVED"
    }
  ]
}

In the above example, an initial $10 authorization is accepted. $8 is cleared, $1 is voided, and another $1 is cleared before the original $8 clearing is returned. The final settled amount is $1.

If a transaction reaches its time to live (TTL) with a non-zero difference between the authorized and settled amounts (i.e., authorized_amount != settled_amount), Lithic will initiate a Void message to the client to clear the remaining difference. A typical TTL is 7 days from the initial authorization, but can be longer in certain cases (e.g., auto rentals, hotel reservations).

2: Financial Authorization

Financial Authorization requests are single-event transactions with no subsequent clearing. These are considered “single message system” (SMS) requests, where authorization and clearing is combined into a single message. Approving an SMS transaction has immediate financial impact, but SMS transactions can still be reversed. An example Financial Authorization ASA request is below:

{
  "status": "FINANCIAL_AUTHORIZATION",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": []
}

In the above example, the cardholder has initiated a $10 SMS transaction. The events array will always be empty for ASA requests.

If the client responds to a Financial Authorization with a decline, a message will be sent to the transaction webhook endpoint with the following information:

{
  "status": "DECLINED",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "FINANCIAL_AUTHORIZATION",
      "result": "UNAUTHORIZED_MERCHANT"
    }
  ]
}

The result field will contain the decline reason returned by the client in response to the ASA request (e.g., UNAUTHORIZED_MERCHANT). No further messages are expected from Lithic after a decline.

🚧

If you're not a part of Lithic's Financial Authorization event beta, the type for events created after responding to Financial Authorization ASA requests will be AUTHORIZATION instead of FINANCIAL_AUTHORIZATION. All other fields will remain the same.

If instead the client responds to the request with an approval, a confirmation will be sent to the transaction webhook endpoint:

{
  "status": "SETTLED",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "settled_amount": 1000,
  "events": [
    {
      "amount": 1000,
      "type": "FINANCIAL_AUTHORIZATION",
      "result": "APPROVED"
    }
  ]
}

At this point, the transaction is considered settled and no further Clearing messages are expected from Lithic related to the transaction.

Financial Authorizations can be reversed by the merchant. These returns operate the same as returns on other authorizations: they can either be associated with the original transaction or included as a new transaction. An example return can be found below:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "FINANCIAL_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "RETURN",
      "result": "APPROVED"
    }
  ]
}

No further messages are expected from Lithic after a reversed Financial Authorization.

3: Balance Inquiry

A Balance Inquiry is a $0 authorization that includes a request for the balance held on the card. The most common situation where a Balance Inquiry is sent is when a user requests the card’s balance at an ATM. An example ASA request is below:

{
  "status": "BALANCE_INQUIRY",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": []
}

The client should respond to the balance inquiry with either an approval or a decline. Balance Inquiries should be approved unless the client desires the balance to not be displayed. The client should respond to the ASA request using result APPROVED to accept the authorization, and include relevant information in the balance fields, or decline with the appropriate reason.

When a Balance Inquiry is declined, the client can expect a message at the transaction webhook endpoint:

{
  "status": "DECLINED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 0,
      "type": "FINANCIAL_AUTHORIZATION",
      "result": "UNAUTHORIZED_MERCHANT"
    }
  ]
}

The result field will contain the decline reason returned by the client in response to the ASA request (e.g., UNAUTHORIZED_MERCHANT).

🚧

If you're not a part of Lithic's Financial Authorization event beta, the type for events created after responding to Balance Inquiry ASA requests will be AUTHORIZATION instead of FINANCIAL_AUTHORIZATION. All other fields will remain the same.

When a Balance Inquiry is approved, the client will receive a message at the transaction webhook endpoint confirming the approval:

{
  "status": "SETTLED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": 0,
      "type": "FINANCIAL_AUTHORIZATION",
      "result": "APPROVED"
    }
  ]
}

Regardless of approval or decline, no further messages are expected from Lithic related to the transaction.

4: Credit Authorization [beta]

Some credits are able to approved or declined by the client. A Credit Authorization is a DMS credit (i.e., the credit requires another message to settle credited funds). An example ASA request is below:

{
  "status": "CREDIT_AUTHORIZATION",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": []
}

The client should respond to the Credit Authorization with either an approval using result APPROVED or a decline code. Credit Authorizations should not be declined except in the case of a closed card or suspected return fraud.

After a decline, the client will receive a message at the transaction webhook endpoint confirming the decline:

{
  "status": "DECLINED",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "CARD_CLOSED"
    }
  ]
}

No further messages are expected from Lithic after a declined Credit Authorization.

If the transaction is approved, the client will receive a message at the transaction webhook endpoint confirming the approval:

{
  "status": "PENDING",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    }
  ]
}

After a Credit Authorization approval, the client can expect another event to either settle or void the credit. In the case of a voided credit, the following message will be received at the transaction webhook endpoint:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "VOID",
      "result": "APPROVED"
    }
  ]
}

No further messages are expected from Lithic after a voided credit.

If instead the credit is settled, the client will receive a Return event at the transaction webhook endpoint:

{
  "status": "SETTLED",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": -1000,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "RETURN",
      "result": "APPROVED"
    }
  ]
}

Credits can be reversed once settled. An example payload is below:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "RETURN",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "RETURN",
      "result": "APPROVED"
    }
  ]
}

No further messages are expected from Lithic after the reversal.

5: Financial Credit Authorization [beta]

Financial Credit Authorization requests are SMS credits with no subsequent clearing. An example request is below:

{
  "status": "FINANCIAL_CREDIT_AUTHORIZATION",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": []
}

The client should respond to the request with either an approval using result APPROVED or a decline code. Similar to other Credit Authorizations, Financial Credit Authorizations should not be declined except in the case of a closed card or suspected return fraud.

After a decline, the client will receive a message at the transaction webhook endpoint confirming the decline:

{
  "status": "DECLINED",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "FINANCIAL_CREDIT_AUTHORIZATION",
      "result": "CARD_CLOSED"
    }
  ]
}

No further messages are expected after a declined Financial Credit Authorization.

If the transaction is approved, the client will receive a message at the transaction webhook endpoint confirming the approval:

{
  "status": "SETTLED",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": -1000,
  "events": [
    {
      "amount": -1000,
      "type": "FINANCIAL_CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    }
  ]
}

Similar to other credits, financial credits can be reversed. An example payload is below:

{
  "status": "VOIDED",
  "amount": 0,
  "acquirer_fee": 0,
  "authorization_amount": 0,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "FINANCIAL_CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": 1000,
      "type": "RETURN",
      "result": "APPROVED"
    }  
  ]
}

No further messages are expected from Lithic after the reversal.

Message Types Originating with a Transaction Webhook

If a transaction webhook arrives at the client’s endpoint standalone (i.e., with no prior authorization or existing transaction token), it will be one of three types, designated by the events.type field in the webhook body:

6: Authorization

If the client receives an Authorization message at the transaction webhook endpoint without a prior ASA request, this signifies that there was a decline due to a check performed by Lithic before the ASA request was sent. Example reasons for these declines include:

  • Transactions initiated on paused card
  • Preset card limit exceeded
  • Authorization rule tripped

An example payload can be found below:

{
  "status": "DECLINED",
  "amount": 1000,
  "acquirer_fee": 100,
  "authorization_amount": 1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": 1000,
      "type": "AUTHORIZATION",
      "result": "UNAUTHORIZED_MERCHANT"
    }
  ]
}

Declines due to Lithic’s checks should be treated the same as if an ASA request were declined by the client. No further messages related to the transaction are expected. Authorization messages signifying approvals should never be received without a prior ASA request.

7: Clearing

In the case where a Clearing message is received but there is no previously authorized transaction, funds should still be designated as settled. This situation is known as a “Force Post”:

{
  "status": "SETTLED",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "settled_amount": 1000,
  "events": [
    {
      "amount": 1000,
      "type": "CLEARING",
      "result": "APPROVED"
    }
  ]
}

Force Posts pose some risk to card programs because they allow the potential for a transaction that exceeds the user’s balance without the opportunity to decline. Force Posts can be indicative of bad merchant behavior, and in the case where the user’s balance is exceeded, are sometimes subject to chargeback. No further messages are expected from Lithic after a Force Post.

8: Return

When a return is initiated on a settled transaction, often the return is not able to be mapped to the original transaction. For this reason, many returns are sent as advice messages through the transaction webhook endpoint on a new transaction object. An example can be found below:

{
  "status": "SETTLED",
  "amount": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": -1000,
  "events": [
    {
      "amount": -1000,
      "type": "RETURN",
      "result": "APPROVED"
    }
  ]
}

It is possible to build a system to match these returns to the original transaction using a combination of transaction amount and merchant information, but such systems can be unreliable. No further messages are expected from Lithic after a return.