# Transactions and Billing



import Image from 'next/image';

import { visuals } from './transactions-and-billing.visuals';

In this tutorial, we will showcase key transactions and examine how they impact billing and accounting ledgers. We'll move from issuance, through a series of standard transactions, and conclude with an in-depth look at some out-of-sequence scenarios.

You can follow along by deploying the configuration and running the Postman collections in the [tutorial](https://github.com/socotra/ec-learning-paths/tree/main/transactions-and-billing) repo. The sample configuration is a simplified homeowner's product with just enough rating logic to illustrate the concepts.

Homeowner Product Structure [#homeowner-product-structure]

The diagram below shows an example product and a policy element tree: A product (HO3) with product-level tax and fee charges, with a single exposure (Dwelling) with two coverages. Each coverage has its own premium charge.

<ProductTree data={visuals.productStructure} />

Standard Transactions [#standard-transactions]

Issuance [#issuance]

First, let's have a look at issuance ("Issue" in the corresponding Postman collection). When the policy is issued, the rated charges are assigned to elements as follows:

<ProductTree data={visuals.issuanceCharges} />

These charges are sent to the billing system, which slices them across installments according to your billing settings. To keep things simple in this tutorial, we're reducing the number of installments and invoices by using these "up-front" <ApiLink name="InstallmentPlanRef" /> settings:

```json
{
	"displayName": "Upfront",
	"cadence": "fullPay",
	"anchorMode": "termStartDay",
	"generateLeadDays": 14,
	"dueLeadDays": 0,
	"maxInstallmentsPerTerm": 1000
}
```

The diagram below shows how charges flow into a billing stream installment and then to an account invoice. In this case, the issuance transaction results in a single installment, for which an invoice is generated. See the [Installment Lattices](/features/billing/installments-and-installment-lattices) and [Invoicing](/features/billing/invoicing) feature guides for more details on installment grouping and invoice generation.

<ChargesBillingAccount data={visuals.issuanceFlow} />

From transaction issuance to invoice generation, the following `faTransaction` ledger entries will be posted:

* Billing receipt of quote issuance (credit to policy ledger, debits to charge ledger)
* Created installments (credits to charge ledger, debits to installment item ledger)
* Generated invoice(s) (credits to installment item ledger, debits to invoice items)

<LedgerTAccounts data={visuals.issuanceLedger} />

In this guide, we're showing credits and debits rolled up to the ledger category level (policy, charge, etc.). Socotra's accounting is more granular than that, which you can see if you follow the sequence of ledger transactions in the "Issue" flow in the Transaction Lab.

1. The first transaction, "Get ledger account - policy" shows the credit to this particular policy's ledger (Click the image for full-size view):

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-1.png" alt="Transaction Lab — policy ledger after issue" width={1755} height={606} unoptimized />

2. When we get the financial transaction (A) that affected that ledger, we see not just one `charge` ledger but four: A `charge` ledger for each of the charges. In the Postman post-response script, we select one of those `charge` ledgers for the next ledger call.

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-2.png" alt="Transaction Lab — financial transaction A with four charge ledgers" width={1758} height={814} unoptimized />

3. "Get ledger account - charge" shows the debit from financial transaction A, along with a credit from another financial transaction (B), "Created installments".

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-3.png" alt="Transaction Lab — charge ledger with debit from A and credit from B" width={1754} height={783} unoptimized />

4. When fetching details for financial transaction B, we see its corresponding credits against four of the `charge` ledgers, and debits against four `installmentItem` ledgers.

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-4.png" alt="Transaction Lab — financial transaction B credits and installment item debits" width={1745} height={775} unoptimized />

5. Again, having chosen one ledger at random, this time for `installmentItem`, the "Get ledger account - installmentItem" shows (B) having debited and another financial transaction (C) "Generated invoice(s)", crediting the `installmentItem` ledger.

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-5.png" alt="Transaction Lab — installmentItem ledger with debit from B and credit from C" width={1771} height={774} unoptimized />

6. Fetching financial transaction (C) shows the credits against all the `installmentItem` ledgers and all of the relevant `invoiceItem` ledgers.

   <Image src="/images/learning-paths/transactions-and-billing/transaction-issuance-6.png" alt="Transaction Lab — financial transaction C credits to installment items and invoice items" width={1761} height={775} unoptimized />

This level of detail enables thorough credit tracking through the system, but for the purposes of this guide, we'll show simplified views in which T-accounts are consolidated by type.

Endorsement [#endorsement]

Now let's look at an endorsement transaction ("Issue and endorse" in the corresponding Postman collection).

In this series, we'll change the coverage limit for Coverage A from $350,000 to $550,000, effective a few months after policy start.

This time, when fetching the `policy` ledger, we'll see an additional financial transaction: "Billing Receipt of Transaction", including the transaction locator.

The charges assigned to elements on the endorsement segment will look like this:

<ProductTree data={visuals.endorsementCharges} />

Notice that coverage B has no assigned charges, since the rater returned no rate items for it.

The endorsement transaction will result in charges sent to the billing system:

<ChargesBillingAccount data={visuals.endorsementFlow} />

Since we're using up-front billing, the endorsement transaction will result in a single installment, for which an invoice is generated. The ledgers now look like this:

<LedgerTAccounts data={visuals.endorsementLedger} />

Cancellation [#cancellation]

Next, let's have a look at cancellations. Suppose that instead of having issued an endorsement, we had cancelled the policy. In a typical cancellation scenario, the flow of credit will be reversed, reflecting a return of the value that had been assigned to the period after the effective cancellation time.

For example, cancelling our sample policy about 1 month after the start date will result in an overall charge reduction of $452.36. Charges sent to the billing system will have negative values, and instead of a $452.36 credit to the policy ledger, we will see a $452.36 debit.

<LedgerTAccounts data={visuals.cancellationLedger} />

The Postman collection includes a "flat cancel" routine you can run to see similar results.

Renewal [#renewal]

In a renewal scenario ("Issue and renew" in the corresponding Postman collection), the flow of credit will be similar to that of an endorsement, but with the addition of a new term. Because of the invoicing settings in the sample configuration, we will not yet see a generated invoice for the transaction. Here's how the charges on the segment for the transaction will look:

<ProductTree data={visuals.renewalCharges} />

And the billing stream will look like this:

<ChargesBillingAccount data={visuals.renewalFlow} />

Notice that the invoice has **not** been generated yet, since the corresponding installment created by the transaction has a `generateTime` in the future, as a consequence of the billing settings that we highlighted earlier. In particular, setting the `anchorMode` to `termStartDay` and `generateLeadDays` to 14 means that the installment will have a `generateTime` set to 14 days before the renewal term. Accordingly, the ledgers after this sequence of issuance and renewal will not yet have a generated invoice transaction for the renewal:

<LedgerTAccounts data={visuals.renewalLedger} />

Reversals [#reversals]

Next, we'll take a look at reversals (Postman: "Issue, endorse, reverse"). Starting from the endorsement sequence we saw earlier, we'll reverse the endorsement transaction to see how the platform reacts.

Upon issuance of the reversal transaction, if you fetch the issued transactions for the policy ("Get issued transactions" list), you'll see just two transactions:

1. Issuance
2. Reversal

What happened to the endorsement transaction? You can still fetch information about it by using the <ApiLink name="fetchAffectedTransactions" /> API endpoint and supplying the reversal transaction locator. The issued transactions list is a streamlined view of the transactions that have directly brought the policy to its current state, including reversals.

If you fetch pricing for the reversal transaction, you won't see charges there: offset charges are created automatically by the billing service when it detects a transaction's transition from `issued` to `reversed`. As you might expect, the billing stream for the reversal transaction is the inverse of the endorsement:

<ChargesBillingAccount data={visuals.reversalFlow} />

In accounting, we'll have three financial transactions:

1. Billing Receipt of Quote Issuance
2. Billing Receipt of Transaction: \[locator: ..., category: change]
3. Created offset installments

With the resulting ledgers:

<LedgerTAccounts data={visuals.reversalLedger} />

Out-of-Sequence [#out-of-sequence]

We recommend taking a look at the [Out-of-Sequence Transactions](/features/policy-management/out-of-sequence-transactions) guide for some background before diving into the examples below. We'll illustrate the key points in that article and show how out-of-sequence transactions affect billing and accounting.

Case 1: Issue, Endorse, Cancel [#case-1-issue-endorse-cancel]

In the Postman collection "Issue, endorse, cancel", we will issue the same endorsement we saw in the earlier examples, and then issue a cancellation back to policy issuance ("Flat cancel"). This is out of sequence since the cancellation's effective time is earlier than the endorsement's.

You'll notice that when you create the cancellation transaction, the <ApiLink name="PolicyTransactionResponse" /> `transactionCategory` is `aggregate`, and that there are two transactions listed in the `aggregatedTransactions` array: The cancellation transaction and the reapplication of the original endorsement transaction. Notice that the `locator` of the endorsement transaction is now different from its original locator. The original locator remains constant as the `staticLocator` so that the same transaction is recognizable even if new instances of it are created for reapplication purposes like this.

After issuing the transaction and running "Get issued transactions list" for the policy, you'll see three transactions, ordered as though these transactions were issued in sequence:

1. Issuance
2. Cancellation
3. Endorsement

You can trace the order definitively by looking at the `baseTransactionLocator` for each transaction. The issuance has no `baseTransactionLocator` since it is the very first transaction. The cancellation's `baseTransactionLocator` points to issuance, while the endorsement points to the cancellation.

*Before issuing the cancellation transaction*

| Transaction       | Based on | Reapplication of | State  |
| ----------------- | -------- | ---------------- | ------ |
| Issuance (Tx1)    |          |                  | Issued |
| Endorsement (Tx2) | Tx1      |                  | Issued |

*After issuing the cancellation transaction*

| Transaction          | Based on | Reapplication of | State    |
| -------------------- | -------- | ---------------- | -------- |
| Issuance (Tx1)       |          |                  | Issued   |
| Endorsement (Tx2)    | Tx1      |                  | Reversed |
| Cancellation (Tx3.1) | Tx1      |                  | Issued   |
| Endorsement (Tx3.2)  | Tx3.1    | Tx2              | Issued   |

This pattern is what we mean when we say that out-of-sequence transactions will be handled as though all the transactions were issued in sequence, and that "all sequences of transactions through a given base transaction (which is called that transaction's [local stack)](/features/policy-management/out-of-sequence-transactions#high-level-approach) are in sequence". The issued transactions list tells this story, while also allowing you to reconstruct the complete history of the policy if needed. You can see that both the endorsement and cancellation transactions share the same `aggregateTransactionLocator` that you can use to view details about the aggregate, and that the endorsement has a `reapplicationOfLocator` pointing to its previous instance (in this case, the original version of the endorsement transaction).

Fetching the ledger for the policy, we'll have four financial transactions:

1. Billing Receipt of Quote Issuance
2. Billing Receipt of Transaction: \[locator: ..., category: change]
3. Created offset installments
4. Billing Receipt of Transaction: \[locator: ..., category: cancellation]

Since well-designed financial ledgers are fundamentally append-only, preserving a complete audit trail rather than rewriting history, the financial transactions follow our transaction issuance (not effective date) order:

1. Charges created by policy issuance
2. Charges created by the endorsement
3. Endorsement charges reversed due to the out-of-sequence cancellation
4. Inverse policy issuance charges created by the flat cancellation

The resulting ledgers look like this:

<LedgerTAccounts data={visuals.oosIssueEndorseCancelLedger} />

If you run "List invoices for policy", you'll see three invoices: One resulting from issuance, another for the endorsement, and a third for the endorsement reversal and cancellation. This is exactly what the ledger state reveals -- even though there were distinct "created installments" financial transactions for the endorsement reversal ("offset") and cancellation, both of those installments were grouped into a single invoice, for which there is one "generated invoices" financial transaction.

Case 2: Issue, Endorse, Endorse, Endorse [#case-2-issue-endorse-endorse-endorse]

As mentioned in the [Out-of-Sequence Transactions](/features/policy-management/out-of-sequence-transactions) guide, aggregate transactions do not nest. To illustrate handling for multiple out-of-sequence transactions, we'll issue a series of transactions out of order:

1. Issuance with coverage A limit of $350,000
2. Endorsement effective 3 months from policy start, changing the coverage A limit to $400,000
3. Endorsement effective 2 months from policy start, changing the coverage A limit to $450,000
4. Endorsement effective 1 month from policy start, changing the coverage A limit to $500,000

Recall that Socotra's default out-of-sequence functionality will display the resulting policy state as though the transactions had been issued in order of effective date. You can think of each transaction as retaining just the changes it had made relative to its original base transaction, so all endorsement 1 knows is "apply a change to set the coverage A limit to $400,000", all endorsement 2 knows is "apply a change to set the coverage A limit to $450,000", etc.

This is the resulting policy state after all these endorsements are issued:

1. Segment 1, policy start to month 1: Coverage A limit is $350,000 (policy issuance)
2. Segment 2, from month 1 to month 2: Coverage A limit is $500,000 (endorsement 3's change)
3. Segment 3, from month 2 to month 3: Coverage A limit is $450,000 (endorsement 2's change)
4. Segment 4, from month 3 onward: Coverage A limit is $400,000 (endorsement 1's change)

Navigation through the ledgers is left as an exercise for the reader.

In this guide, we have explored the interplay between fundamental transaction sequences and Socotra's billing system. While the product data model and invoicing configuration have been kept deliberately simple, these concepts apply uniformly across implementations, and we encourage you to use this sample as the basis for study and scenario analysis specific to your product.
