Transaction Flow

Learn about the most common transaction flow permutations you can expect to see on the Lithic platform.

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 an ISO-8583 Message Type Identifier (MTI) 0100 message (i.e., an authorization request) to Lithic.
  2. Lithic converts the ISO-8583 message to transaction model JSON and sends an ASA request to the user.
  3. The user responds with HTTP 200 ASA JSON response body with result APPROVED. *HTTP 200 & ASA response required.
  4. Lithic converts the ASA response body to an ISO-8583 response and returns it to the network.
  5. Merchant/acquirer initiates completion of the transaction and Lithic receives an ISO-8583 MTI 0220 message (i.e., financial transaction advice) from the network. *This message typically arrives between 0-7 days after the previous response.
  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 user. Step 6 & 7 are processed concurrently.
  8. The user 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 user 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 that initiate a transaction, which will be represented with a new transaction token. Across those eight messages, there are two places that the user can receive the webhook:

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

See below for a list of expected 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 a transaction webhook to your 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; unless the transaction status is DECLINED, in which case you can bring down hold amount to 0
  • Settled amount: settled_amount

Message Types Originating with an ASA Request

For new transactions that require approval, Lithic will send an ASA request to the user's configured endpoint. These requests can be one of five types, as represented by 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.

Example ASA request:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION.

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 user has three options: approve the authorization, decline the authorization, or approve the authorization up to a specific amount (see Partial Approval for more information). To do this, the user 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 user will receive a transaction webhook notifying them of the result of the authorization.

If the authorization is declined, a transaction webhook will be sent notifying the user of the decline. In this situation, the payload of the message will look like the following.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, then decline the ASA request.

At this point, any acquirer_fee will be included in the amount field both on the overall transaction object and in the events array.

This decline can happen in two situations.

  • Expected decline: The first is when the user responds to the ASA request with any result other than APPROVED. In this case, the result field in the response will contain the decline result used by the user.
  • Unexpected decline: The second is when the user responds to the ASA request with result APPROVED, but returns an error, exceeds the allotted response time, or returns a malformed response. These declines will be treated in the same manner as a decline performed by the user indicated via the ASA response. Once an authorization has been declined, no further related messages are expected related to the transaction.

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

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, then accept the ASA request.

As the transaction is now in a pending state, the user should wait for additional messages to come through via the network and Lithic that will update the transaction. There are four possible message types that can come after the initial authorization (as indicated by the events.type field): CLEARING, AUTHORIZATION_REVERSAL, AUTHORIZATION_EXPIRY and AUTHORIZATION_ADVICE.

Authorization > Clearing

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

Example transaction webhook:

{
  "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"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, then call the simulate clearing transaction endpoint with the transaction token generated from the authorization.

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, Authorization Reversal, and Authorization Expiry messages that come on a SETTLED transaction, as well as returns. See Multiple Completion for information on these situations.

Authorization > Authorization Reversal

When the merchant elects to cancel an order before it has been settled, the user will receive an Authorization Reversal 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 reversed amount matches the authorization amount. In this case, the status will be VOIDED and the authorization_amount will be zero.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, then call the simulate void transaction endpoint with type of AUTHORIZATION_REVERSAL and the transaction token generated from the authorization.

The other possible case is that the reversed amount is less than the authorized amount.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, then call the simulate void transaction endpoint with type of AUTHORIZATION_REVERSAL, the transaction token generated from the authorization, and an amount of less than the original amount authorized.

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

It is also possible for the reversed amount to be greater than the authorized amount when:

  • the transaction is in a foreign currency. If the foreign exchange rate has changed since the initial authorization, then the amount on the Authorization Reversal message could be greater or less than the amount on the original Authorization message
  • merchants make an error and enter an incorrect reversal amount. This is a rare occurrence as the networks generally have checks to prevent over-reversals

In either case, if there is an over-reversal, Lithic will cap the authorization_amount field in the Transaction object to $0.

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

An uncommon sequence that can appear is an Authorization Reversal followed by an Authorization Advice. This typically occurs when there is a timeout (e.g., user's ASA responder took too long to respond, Lithic platform takes too long to process the authorization). When this occurs, the final Authorization Advice event can effectively be ignored as no additional events are expected to take place after the reversal.

Example transaction webhook:

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

Authorization > Authorization Expiry

Each authorization that comes through from the card network has an associated authorization validity window that indicates how long the merchant has to clear (or settle) the transaction. If the window has passed and there is any remaining authorized amount that has not yet been cleared by the merchant, Lithic will automatically expire the original authorization. Holds placed on cardholder funds can be lifted once this occurs. Similar to Authorization Reversals, the most common case where this occurs is that the entire authorization is expired and authorization_amount goes to zero.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, then call the simulate void transaction endpoint with type of AUTHORIZATION_EXPIRY and the transaction token generated from the authorization.

There is an additional case where an authorization occurs, is partially cleared, and the remaining authorization_amount is expired. See Multiple Completion for more information.

There is also a case where a merchant clears the transaction after the authorization has been expired. When this occurs, a CLEARING event will appear after AUTHORIZATION_EXPIRY. While the Lithic platform cannot reject these late clearing events, this can be indicative of bad merchant behavior, and these transactions may be subject to chargeback.

Authorization > Authorization Advice

After an approved authorization, a message of type AUTHORIZATION_ADVICE may come through via the transaction webhook. Authorization Advice messages update the authorized amount of previous authorizations without clearing any funds. A typical situation where an Authorization Advice message is sent is when a cardholder makes a gasoline purchase: an initial authorization is sent before the gas is pumped, then updated to the true amount afterwards. An example Authorization Advice message can be found below.

Example transaction webhook:

{
  "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"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, then call the simulate authorization advice with a new amount and the transaction token generated from the authorization.

In this situation, an Authorization Advice message has come through that changed the authorization amount to $20 (from the original $10).

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

Example transaction webhooks:

{
  "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"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, call the simulate authorization advice endpoint with a new amount and the transaction token generated from the authorization, then call the simulate clearing transaction endpoint with the same transaction token.

{
  "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": "AUTHORIZATION_REVERSAL",
      "result": "APPROVED"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, call the simulate authorization advice endpoint with a new amount and the transaction token generated from the authorization, then call the simulate void transaction endpoint with type of AUTHORIZATION_REVERSAL and the transaction token generated from the authorization.

{
  "status": "EXPIRED",
  "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": "AUTHORIZATION_EXPIRY",
      "result": "APPROVED"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of AUTHORIZATION, accept the ASA request, call the simulate authorization advice endpoint with a new amount and the transaction token generated from the authorization, then call the simulate void transaction endpoint with type of AUTHORIZATION_EXPIRY and the transaction token generated from the authorization.

When an Authorization Advice event occurs on a transaction, only a single clearing, authorization reversal, or authorization expiry message is expected.

Another situation in which an Authorization Advice message is sent is when the networks “stand-in” to respond on behalf of Lithic and our customers. This can occur when Lithic does not respond to an authorization request in time, resulting in a time-out.

For most Lithic customers, the networks will stand-in to decline an authorization by emitting an Authorization Advice message with status of DECLINED.

Example transaction webhook:

{
  "status": "DECLINED",
  "amount": 1000,
  "acquirer_fee": 0,
  "authorization_amount": 1000,
  "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.

Certain Enterprise customers may be able to customize their stand-in behavior so that the networks respond with an approval instead of decline on their behalf. However, customers should be prepared for a scenario in which:

  • They respond to an ASA request with a decline
  • Lithic times out and does not pass that response to the networks in time
  • The networks then generate an authorization advice approval on their behalf based on pre-configured stand-in behavior

Please reach out to your Lithic Implementation or Customer Success Manager to understand if this applies to you.

Example transaction webhook:

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

Multiple Completion

After a transaction has been fully or partially cleared, there are multiple additional events that can occur on 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.

Example transaction webhook:

{
  "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, Return Reversal, Clearing, Authorization Reversal, and Authorization Expiry messages on the transaction.

Example transaction webhook:

{
  "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": "AUTHORIZATION_REVERSAL",
      "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 reversed, 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 an Authorization Expiry message 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). In other cases, the merchant may indicate no additional clearings will be sent, in which case Lithic will expire the remaining authorization amount same-day.

For transactions in foreign currencies, it is possible that a full return in the local currency results in a return amount that is different than the clearing amount in the settlement currency. For example:

  • A transaction in France cleared for €10 in local currency of Euro. The foreign exchange rate of Euro to USD is 0.80. This results in a Clearing message for $8 in settlement currency of USD
  • A week later, the transaction was refunded for the full €10 in local Euro currency. However, the foreign exchange rate has since changed to 1
  • This results in a Return message for $10 in settlement currency of USD. So the cardholder receives a net credit of $2 due to changes in foreign exchange

Example transaction webhook:

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

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 by the merchant.

Example ASA request:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_AUTHORIZATION.

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

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

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_AUTHORIZATION, then decline the ASA request.

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

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

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_AUTHORIZATION, then accept the ASA request.

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

Transactions taking place via a Financial Authorization can be returned. These returns operate the same way as returns on other authorizations: they can either be associated with the original transaction (and appear as a new event under the original authorization) or come through as a new transaction. An example of the former case can be found below.

Example transaction webhook:

{
  "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"
    }
  ]
}

Simulating a linked return on a cleared transaction in Sandbox is not yet available.

No further messages are expected from Lithic after a Financial Authorization has been returned.

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.

Example ASA request:

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

To simulate the above example, call the simulate authorization endpoint with status of BALANCE_INQUIRY.

The user should respond to the balance inquiry with either an approval or a decline. Balance Inquiries should generally be approved unless the user has a reason for why they do not want the balance not be displayed. The user should either respond to the ASA request using result APPROVED and include relevant information in the balance fields, or decline with the appropriate reason.

When a Balance Inquiry is declined, the user can expect a message at the transaction webhook endpoint.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of BALANCE_INQUIRY, then decline the ASA request.

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

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

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of BALANCE_INQUIRY, then accept the ASA request.

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

4: Credit Authorization (only available for customer decisioning via ASA on certain programs; sent via webhooks on all programs)

Certain credits and refunds come through as a dual message, meaning the merchant makes a credit authorization request, followed by another message to settle credited funds. Only certain eligible card programs will receive these messages via ASA. The default behavior for all other programs is that these credits will be accepted, and the first notification from Lithic that this has occurred on your program will be via the transaction webhook.

Example ASA request (eligible programs only):

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

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION.

The user 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.

If a decline occurs, the user will receive a message at the transaction webhook endpoint confirming the decline.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, then decline the ASA request.

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

If the transaction is approved, the user will receive a message at the transaction webhook endpoint confirming the approval.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, then accept the ASA request.

After a Credit Authorization approval, the user can expect another event to either settle, reverse, or expire the credit. In the case of a reversed credit, the following message will be received at the transaction webhook endpoint.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, accept the ASA request, then call the simulate void transaction endpoint with type of AUTHORIZATION_REVERSAL and the transaction token generated from the authorization.

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

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

Example transaction webhook:

{
  "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"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, accept the ASA request, then call the simulate clearing transaction endpoint with the transaction token generated from the authorization.

If the credit authorization was not settled in time, the Lithic platform will expire the authorization to indicate that the credit was not completed (and credits should not be pushed to the end cardholder).

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, accept the ASA request, then call the simulate void transaction endpoint with type of AUTHORIZATION_EXPIRY and the transaction token generated from the authorization.

Credits can also be reversed once settled.

Example transaction webhook:

{
  "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_REVERSAL",
      "result": "APPROVED"
    }
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of CREDIT_AUTHORIZATION, and accept the ASA request. Then call the simulate clearing transaction endpoint with the transaction token generated from the authorization. Finally, call the simulate return reversal endpoint with the same transaction token.

No further messages are expected from Lithic after the reversal.

Another situation in which a Credit Authorization Advice message is sent is when a decline occurs based on an upstream switch during initial authorization (e.g., the user's 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": -1000,
  "acquirer_fee": 0,
  "authorization_amount": -1000,
  "settled_amount": 0,
  "events": [
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION",
      "result": "APPROVED"
    },
    {
      "amount": -1000,
      "type": "CREDIT_AUTHORIZATION_ADVICE",
      "result": "DECLINED"
    }
  ]
}

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

5: Financial Credit Authorization (only available for customer decisioning via ASA on certain programs; sent via webhooks on all programs)

Financial Credit Authorization requests are similar to Credit Authorizations, but are single message credits with no subsequent clearing. The default behavior for all other programs is that these credits will be accepted, and the first notification from Lithic that this has occurred on your program will be via the transaction webhook.

Example ASA request:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_CREDIT_AUTHORIZATION.

The user should respond to the request with either an approval using result APPROVED or a decline code. Similar to 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 user will receive a message at the transaction webhook endpoint confirming the decline.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_CREDIT_AUTHORIZATION, and decline the ASA request.

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

If the transaction is approved, the user will receive a message at the transaction webhook endpoint confirming the approval.

Example transaction webhook:

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

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_CREDIT_AUTHORIZATION, and accept the ASA request.

Similar to other credits, financial credits can be reversed.

Example transaction webhook:

{
  "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_REVERSAL",
      "result": "APPROVED"
    }  
  ]
}

To simulate the above example, call the simulate authorization endpoint with status of FINANCIAL_CREDIT_AUTHORIZATION, and accept the ASA request. Then call the simulate return reversal endpoint with the same transaction token.

No further messages are expected from Lithic after the reversal.

Message Types Originating with a Transaction Webhook

If a transaction webhook arrives at the user'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 user 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:

  • Transaction was run on a paused card
  • Card spend limit exceeded
  • Authorization rule triggered

Example transaction webhook:

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

Simulating a pre-declined authorization in Sandbox is not yet available.

Declines due to Lithic’s checks can be treated the same as if an ASA request were declined by the user. 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 will be designated as settled. This situation is known as a “Force Post”.

Example transaction webhook:

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

Simulating an unlinked clearing (aka force post) in Sandbox is not yet available.

Force Posts pose some risk to card programs because they allow the potential for a transaction to be settled that exceeds the cardholder's balance (without allowing the user an 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 will appear as a standalone transaction object. 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 and risk over-crediting.

Example transaction webhook:

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

To simulate the above example, call the simulate return endpoint.

In some cases, Lithic may mark a return transaction with a status of DECLINED and result of ORIGINAL_NOT_FOUND. In these cases, there was likely a prior financial authorization that was missed, so you should ignore the refund event to avoid over-crediting the cardholder.

No further messages are expected from Lithic after a return.

9: Authorization Advice

In the most common path, transactions begin with an AUTHORIZATION event, and subsequent AUTHORIZATION_ADVICE events serve the purpose of modifying the original authorization amount (e.g., fuel station authorizes for $1, then sends through authorization advice for the final amount of gas pumped). However, users should also anticipate cases where a transaction begins with an AUTHORIZATION_ADVICE event. In these cases, you should expect subsequent events in the same way you would for a transaction that begins with AUTHORIZATION followed by AUTHORIZATION_ADVICE (see this section of this page for more). Two known cases where this can occur are:

  • Card is used at an offline point-of-sale system (e.g., buying food on a plane where the POS is not running online authorizations), and the transaction is sent through as authorization advice
  • Merchant sends an adjustment due to some POS error; while some merchants will send this through as a Force Post (more detail here), others will send this as an authorization advice where a clearing subsequently follows

In both of the above cases, since an authorization was not properly approved by the issuer, these transactions would be sometimes subject to chargeback.

Example transaction webhook:

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

Transactions can also begin with a declined AUTHORIZATION_ADVICE event. This most typically occurs when a party upstream of Lithic - either the acquirer or card network - made a decision to decline the authorization.

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

No further events are expected to occur on transactions once they were in the above state.

10: Credit Authorization Advice

While Lithic's default behavior when receiving a Credit Authorization from the network is to accept it, at times a user may receive a Credit Authorization Advice message when it has been accepted upstream from Lithic. For example, in the event where there is a timeout between Lithic and the network during a credit authorization request, the network may "stand-in" and accept the credit on Lithic's (and its user's) behalf. In this case, a Credit Authorization Advice message is sent with status PENDING.

Example transaction webhook:

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

To simulate the above example, call the simulate credit authorization advice endpoint.

Similar to a Credit Authorization, the user can expect another event to either settle or void the credit authorization advice. In the case of a reversed credit authorization advice, the following message will be received at the transaction webhook endpoint.

Example transaction webhook:

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

To simulate the above example, call the simulate credit authorization advice endpoint, then call the simulate void transaction endpoint with type of AUTHORIZATION_REVERSAL and the transaction token generated from the credit authorization advice.

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

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

Example transaction webhook:

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

To simulate the above example, call the simulate credit authorization advice endpoint, then call the simulate clearing transaction endpoint with the transaction token generated from the credit authorization advice.

Credits can be reversed once settled.

Example transaction webhook:

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

To simulate the above example, call the simulate credit authorization advice endpoint. Then call the simulate clearing transaction endpoint with the transaction token generated from the credit authorization advice. Finally, call the simulate return reversal endpoint with the same transaction token.

No further messages are expected from Lithic after the reversal.

Similar to transactions that begin with authorization advice messages, transactions can also begin with a declined CREDIT_AUTHORIZATION_ADVICE event. This most typically occurs when a party upstream of Lithic - either the acquirer or card network - made a decision to decline the credit authorization.

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

No further events are expected to occur on transactions once they were in the above state.

11: Authorization Reversal

Occasionally, a transaction object is created with a standalone authorization reversal event. This most typically takes place when a cardholder initiates a return or refund on a prior purchase that has already cleared (see this standard sequence) but the merchant attempts to reverse the authorization (as they would with an outstanding, uncleared authorization) rather than initiate a standard credit authorization flow. This can sometimes be done accidentally or because the merchant is unaware that their acquirer has already cleared the authorization.

In these cases, since the Lithic platform will not be able to locate an outstanding authorization tied to the card on which a refund is taking place, it will not link the authorization reversal event to the original transaction, and instead surface the event as its own transaction with a declined status. This webhook will serve as a notification that this event has taken place on your card program, but no action is needed as no clearing or money movement has taken place. The event will typically contain the ORIGINAL_NOT_FOUND result type to indicate that the merchant submitted a reversal but the Lithic platform was unable to locate a corresponding authorization to reverse.

Example transaction webhook:

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

The typical next step to ensure that the cardholder will receive the credit is that the merchant and acquirer will send the refund through as a credit authorization, financial credit authorization, or force posted return. Credit should not be extended to the end cardholder until one of the above sequences occur and the transaction is in a SETTLED status (as indication that money has moved).