Payment Schedule Plugin

Overview

The payment schedule plugin provides a way for configurers to write custom rules for generating payment schedules. This gives fine control for situations like:

  • Non-standard payment schedule, such as “monthly for the first 9 months out of a year-long policy term”

  • Consolidating small value invoices into one

  • Scheduling invoices on certain dates or days of the week

  • Special logic for endorsement or reinstatement invoicing

It also has a facility for changing the payment schedule for an existing policy.

Important

Use of this plugin can cause unexpected proration calculations on endorsements and cancellations. If this feature is enabled, you should also implement the Proration Plugin. This feature is not compatible with legacy cancellations and reinstatements.

Note

This plugin only affects future invoices. Changing already-generated invoices is not supported.

See the Plugins topic for information about enabling the plugin and setting the script path.

Enabling the plugin

To enable the plugin, follow the steps in the plugins topic.

Script

The script is defined in a file called installments.js with exported function createInstallments. This file should be under the scripts branch you wish to use, for example /scripts/main/installments.js.

Charges

The data.charges array contains the information needed to ensure all receivables are properly invoiced. Each charge reflects a receivable amount for an individual peril’s premium or commission, or a tax or fee.

Typically on new business or renewals each peril will be represented by one charge. For endorsement, there are usually four charges per peril:

  • A positive charge representing the original overall amount of premium for the affected policy segment. This could be net of previously invoiced amounts, such that the amount + previouslyInvoicedAmount equals the originalAmount. This charge will have its isNew property equal to false.

  • A negative charge that reverses the original positive charge. Its amount is usually the negative of the positive charge’s originalAmount.

  • A positive charge representing the prorated premium for the segment before the endorsement.

  • A positive charge representing the calculated premium for the segment after the endorsement.

The last three charges in this sequence will have isNew equal to true, previouslyInvoicedAmount equal to zero, and its amount equal to its originalAmount.

For example, in a year-long policy with one peril we might have the following charge passed to the plugin for the new business event:

Start

End

Amount

Original Amount

Prev Inv Amount

Jan 1 2022

Jan 1 2023

$1200

$0

$0

And after endorsement on March 1 with $200 on previously generated invoices and a $400 premium increase, the charges passed to the plugin might look like this:

Start

End

Amount

Original Amount

Prev Inv Amount

Mar 1 2022

Jan 1 2023

$1000

$1200

$200

Jan 1 2022

Jan 1 2023

($1200)

$0

$0

Jan 1 2022

Mar 1 2022

$300

$0

$0

Mar 1 2022

Jan 1 2023

$1300

$0

$0

Note

When amounts have been previously invoiced, the coverageStartTimestamp for the charge is adjusted to show the coverage start for the uninvoiced portion. To get the full time range for the charge, use the charge’s policyModificationLocator to lookup the associated policy modification, and use that modification’s effectiveTimestamp.

Taxes, fees, and commissions are handled similarly to the peril premium case described above.

Write offs

To write off certain charges or portions of charges, put them on a separate set of installments and set the writeOff flag for those installments to true. This can be useful, for example, in putting extra cents onto a separate written-off invoice so that the totals for other invoices remain constant.

Written off invoices will have settlementStatus of settled and settlementType of writtenOff.

Invoice types

Invoices have type Installment unless the installment is generated and issued in conjunction with a transaction. For example, the invoice generated for a newly-issued policy will be labeled New Business, with any subsequent invoices labeled as Installment.

You can ensure that no bill is issued immediately with a given transaction by returning a “zero-due” installment as the first item in the list of invoiceItems returned by the payment schedule plugin.

To ensure that cancellation invoices are labeled with type Cancellation, the installment returned by the payment schedule plugin should have a dueTimestamp prior to the issuedTimestamp of the cancellation transaction, or have issueTimestamp match the cancellation transaction’s issueTimestamp (or both). Invoices that result from lapse and which have type Cancellation are not subject to grace logic, ensuring that they remain outstanding for collection.

The Plugin data Object

The data object passed to the plugin looks like this:

PaymentSchedulePluginData
required
productName string
coverageStartTimestamp timestamp
coverageEndTimestamp timestamp
defaultPaymentTerms PaymentTermsResponse
operation string newBusiness | endorsement | renewal | reinstatement | cancellation | manual | feeAssessment
paymentScheduleName string
plannedInvoices [FutureInvoiceResponse]
tenantTimeZone string
transactionType string newBusiness | endorsement | renewal | reinstatement | cancellation | manual | feeAssessment (deprecated)

optional
oldPaymentScheduleName string

The plannedInvoices property describes what the invoice schedule was planned before the transaction being processed. Those planned invoices will be replaced with the installments returned from the plugin. Your plugin logic may examine the original planned invoice for hints on how to schedule the new installments.

The coverageStartTimestamp and coverageEndTimestamp properties describe the period covered by the transaction:

  • For new business, it is the period from the policy effective date to the expiration date.

  • For an endorsement, it is the period from the endorsement effective date to the policy end.

  • For a renewal, it is the period from the renewal start to the new policy end.

  • For a reinstatement, it is the entire policy from start to the end after reinstatement.

PaymentSchedulePluginCharge
required
coverageStartTimestamp timestamp
coverageEndTimestamp timestamp
amount number
originalAmount number
previouslyInvoicedAmount number
amountCurrency string
chargeId string
isNew boolean
policyModificationLocator string
type string premium | tax | commission | fee | technicalPremium | premiumHoldback | taxHoldback | feeHoldback | commissionHoldback | premiumHoldbackReversal | taxHoldbackReversal | feeHoldbackReversal | commissionHoldbackReversal

optional
perilName string
perilCharacteristicsLocator string
category string new | previously_invoiced | carried_forward
commissionLocator string
commissionRecipient string
feeLocator string
feeName string
perilLocator string
taxLocator string
taxName string
  • The isNew property is set to false for charges that have been scheduled before. These charges will also have originalAmount and previouslyInvoicedAmount properties. The amount for these charges is net of amounts on other invoices that remain in force.

  • The coverageStartTimestamp and coverageEndTimestamp properties for the individual charge describe the period covered by the charge. This can be different from the overall transaction coverage period.

The plugin is required to return a response in this form:

PaymentSchedulePluginResponse
PaymentSchedulePluginInstallmentResponse
required
issueTimestamp timestamp
dueTimestamp timestamp
startTimestamp timestamp
endTimestamp timestamp
installmentFees [InstallmentFee]
writeOff boolean
PaymentSchedulePluginInvoiceItemResponse
required
amount number
chargeId string
InstallmentFee
required
amount number
description string
feeName string

Validation

The response from the plugin must conform to the following criteria:

  • For each charge in the data.charges array, the sum of the invoice item amounts across all installments must exactly equal the charge’s amount.

  • Installments must cover the coverage period with no gaps or overlaps. This means that the first installment’s start must be at the beginning of the coverage period, and each installment’s end timestamp must match the start timestamp of the next installment, except for the last installment, where the end timestamp should equal the coverage end.

  • The end timestamp of each installment must be greater than or equal to its start timestamp.

If plugin execution returns the following error:

Can not generate scheduled invoice while previous scheduled invoices have not been generated.

Check to ensure that every returned installment has at least one invoice item assigned to it. A “zero-due” invoice should still have at least one invoice item, which can be attributed to any charge and have amount 0. Zero-due invoice issuance can be suppressed with the property.endorsement.zerodue.invoices.suppression.enabled flag.

Important

On cancellation invoicing, each new installment must have its startTimestamp and endTimestamp align with the start and end of a previously created installment. This is a known issue which will be fixed in an upcoming release.

Simple Example

This is the simplest possible implementation, which is a full-pay plan. It puts all the charges for each transaction on a single invoice:

function createInstallments(data)
{
  let invoiceItems = data.charges.map(ch => ({
    amount: parseFloat(ch.amount),
    chargeId: ch.chargeId
  }));

  return {
    installments: [{
    dueTimestamp: data.coverageStartTimestamp,
    issueTimestamp: data.coverageStartTimestamp,
    startTimestamp: data.coverageStartTimestamp,
    endTimestamp: data.coverageEndTimestamp,
    invoiceItems: invoiceItems,
    writeOff: false
  }]};
}

exports.createInstallments = createInstallments;

Reference Implementation

See the Socotra Plugin Reference Implementations for a standardized version of the payment schedule plugin that can be configured with a simple set of options.