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 theoriginalAmount
. This charge will have itsisNew
property equal tofalse
.A negative charge that reverses the original positive charge. Its
amount
is usually the negative of the positive charge’soriginalAmount
.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:
requiredproductName stringcoverageStartTimestamp timestampcoverageEndTimestamp timestampcharges [PaymentSchedulePluginCharge]defaultPaymentTerms PaymentTermsResponseoperation string newBusiness | endorsement | renewal | reinstatement | cancellation | manual | feeAssessmentpaymentScheduleName stringplannedInvoices [FutureInvoiceResponse]policy PolicyResponsetenantTimeZone stringtransactionType string newBusiness | endorsement | renewal | reinstatement | cancellation | manual | feeAssessment (deprecated)optionaloldPaymentScheduleName 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.
requiredcoverageStartTimestamp timestampcoverageEndTimestamp timestampamount numberoriginalAmount numberpreviouslyInvoicedAmount numberamountCurrency stringchargeId stringisNew booleanpolicyModificationLocator stringtype string premium | tax | commission | fee | technicalPremium | premiumHoldback | taxHoldback | feeHoldback | commissionHoldback | premiumHoldbackReversal | taxHoldbackReversal | feeHoldbackReversal | commissionHoldbackReversaloptionalperilName stringperilCharacteristicsLocator stringcategory string new | previously_invoiced | carried_forwardcommissionLocator stringcommissionRecipient stringfeeLocator stringfeeName stringperilLocator stringtaxLocator stringtaxName string
The
isNew
property is set tofalse
for charges that have been scheduled before. These charges will also haveoriginalAmount
andpreviouslyInvoicedAmount
properties. Theamount
for these charges is net of amounts on other invoices that remain in force.The
coverageStartTimestamp
andcoverageEndTimestamp
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:
requiredinstallments [PaymentSchedulePluginInstallmentResponse]
requiredissueTimestamp timestampdueTimestamp timestampstartTimestamp timestampendTimestamp timestampinstallmentFees [InstallmentFee]invoiceItems [PaymentSchedulePluginInvoiceItemResponse]writeOff boolean
requiredamount numberchargeId string
requiredamount numberdescription stringfeeName 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 for endorsements with the property.endorsement.zerodue.invoices.suppression.enabled
flag, and for cancellations with the property.cancellation.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.