Reverse and rebill
With persisted cash invoices, the ability to rebill subscribers via a one step process will no longer be available unless it is for individuals in 20.3.223+ with steps used here: Rebilling a single contact which works great if you are billing the same products. If you are billing different products the steps below are what is needed. You will first need to reverse any existing invoices and then bill the subscribers again. In version 20.3.208 and later, it is possible to include both the invoice reversal and the rebill in a single API execute method.
Reversing and rebilling an entire billing run
Step 1: Find the original billing log
If you know of an invoice that was generated in the billing you wish to reverse, you should be able to see the BillingLogKey in the list of invoice properties and use that to fetch the original billing details
GET https://{{URL}}/api/BillingLog/{yourBillingLogKeyHere}
Alternatively, you can search by billing cycle, billing run name or other properties about the billing
GET https://{{URL}}/api/BillingLog?BillingCycleName={yourBillingCycleNameHere}
After you find the billing log, you should be able to see the original options used for the billing such as EffectiveDate and AutoPayOption. This will be important when filling out the BillGenerationData object in the rebill step below.
Note the BillingLogKey, EffectiveDate, BillingCycleId, and AutoPayOption.
Step 2: Add a new billing log for the reverse and rebill (optional)
Reversing invoices can take a while, especially if there are thousands of invoices to be reversed. It could be useful to add a new BillingLog with a "Reversing invoices" status and pass this through to the rebill step so that the status can be updated once billing begins.
To add the BillingLog, just POST to the BillingLog endpoint. Include the OriginalBillingLogKey to reference the original billing that is being reversed and rebilled. There are a few enum properties with the possible values explained below:
Status
- 0 = Pending
- 1 = Processing
- 2 = Completed
- 3 = Failed
- 4 = Unposted batch (the billing is complete, but the batch needs to be posted for invoices to be created)
- 5 = Reversing invoices
- 6 = Batch deleted (the billing completed, but the batch was deleted without invoices being created)
AccountingMethod
- 0 = Cash
- 1 = Accrual
AutoPayOption
- 0 = Not defined (The system is likely not licensed for AutoPay)
- 1 = Bill all contacts (Bill both AutoPay and non-AutoPay contacts)
- 2 = Bill only contacts with AutoPay enrollments
- 3 = Bill only contacts without AutoPay enrollments
POST https://{{URL}}/api/BillingLog
{
"$type": "Asi.Soa.Commerce.DataContracts.BillingLogData, Asi.Contracts",
"BillingLogKey": "be2506c1-2324-4157-a1ae-bdba7a0dcbea",
"BillingRunName": "Rebill: Regular Membership Fees for 101",
"BillingCycleName": "Regular Membership Fees",
"BillingType": "I",
"BillingDate": "2025-09-09T15:32:43.8397624Z",
"EffectiveDate": "2025-09-01T00:00:00Z",
"Status": 5,
"AccountingMethod": 0,
"BillingPartyId": "101",
"AutoPayOption": 0,
"OriginalBillingLogKey": "a9f0db70-d684-481a-84cd-d8fa1cd8f404"
}
Step 3: Reverse and rebill the billing run
The reverse and rebill UI in iMIS will run a background task with 2 actions: Reverse open invoices via a BillingLogKey, and rebill contacts once the invoice reversals are complete. To set up a similar task execution to run via the API, the most important piece of information you will need is OriginalBillingLogKey of the billing you wish to reverse and rebill.
POST https://{{URL}}/api/TaskDefinition/_execute
{
"$type": "Asi.Soa.Communications.DataContracts.TaskAdhocRequest, Asi.Contracts",
"Task": {
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionData, Asi.Contracts",
"Priority": 0,
"TaskType": 2,
"Triggers": null,
"Evaluations": null,
"DataSources": null,
"Actions": {
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionDataCollection, Asi.Contracts",
"$values": [
{
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionAdhocReverseInvoiceData, Asi.Contracts",
"ActionTypeName": "ReverseInvoice",
"Description": "Reverse Invoice",
"ListOfInvoiceActionFundraisingAdjustmentData": null,
"ListOfInvoiceActionDuesReversalData": null,
"OriginalBillingLogKey": "a9f0db70-d684-481a-84cd-d8fa1cd8f404",
"ActionNotification": null
},
{
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionAdHocBillGenerationData, Asi.Contracts",
"ActionId": null,
"ActionTypeName": "GenerateMembershipRenewals",
"Description": "Regular Membership Fees",
"BillGenerationData": {
"$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
"IsRenewal": true,
"AdditionalOption": {
"$type": "Asi.Soa.Commerce.DataContracts.BillingAdditionalOptionsData, Asi.Contracts",
"OriginalBillingLogKey": "a9f0db70-d684-481a-84cd-d8fa1cd8f404"
},
"EffectiveDate": "2025-09-01T00:00:00Z",
"BillingCycleId": "Regular Membership Fees",
"BillingRunName": "Rebill: Regular Membership Fees",
"BillingLogKey": "be2506c1-2324-4157-a1ae-bdba7a0dcbea",
"AutoPayOption": 0
},
"ActionNotification": null,
"IsProcessAutomationAction": false,
"AutomaticallyPostBatch": true
}
]
},
"Notifications": null,
"UpdateInformation": null
},
"EntityTypeName": "TaskDefinition",
"OperationName": "TaskAdhocRequest"
}
Notes about properties in the bulk reverse and rebill:
- The
TaskDefinitionActionAdhocReverseInvoiceDataaction will automatically find any open invoices for the givenOriginalBillingLogKeythat have no payments and reverse those. Any invoices where even a partial payment or full payment has been applied will be left as-is. - If you created a BillingLog in the optional step above, use that
BillingLogKeyinTaskDefinitionActionAdHocBillGenerationData.BillGenerationDataas shown above. If that optional step was skipped, leaveBillingLogKeyoff and a new billing log will be created when the rebill action begins. - Populating
TaskDefinitionActionAdHocBillGenerationData.BillGenerationData.AdditionalOption.OriginalBillingLogKeytells iMIS to only include IDs billed in that original billing when generating new renewal invoices. - Setting
TaskDefinitionActionAdHocBillGenerationData.AutomaticallyPostBatchtotruetells iMIS to automatically post the resulting batch if one exists after the rebill step is complete. You can also manually post the batch afterward by getting the BatchId from the BillingLog and posting it via the BatchSummary endpoint. If "Do not require posting batch for single-member renewals" is enabled the batch will not be posted if it is an accounting batch.
Step 4: Monitor progress
Check the billing log status to track progress:
GET https://{{URL}}/api/BillingLog/be2506c1-2324-4157-a1ae-bdba7a0dcbea
The Status will progress from 5 (Reversing invoices) → 1 (Processing) → 2 (Completed).
Reverse and rebill a single contact
To reverse and rebill a single contact instead of an entire billing run, make two changes to the task request:
- Reverse action: Provide the specific invoice(s) in
ListOfInvoiceActionDuesReversalDatainstead of usingOriginalBillingLogKey. This targets only that contact's invoices rather than reversing every open invoice in the billing run. - Rebill action: Set
IndividualBillingPartyIdon theBillGenerationDatato the party ID of the contact to rebill.
Step 1: Find the contact's invoice(s)
Look up the contact's invoices from the billing run you want to reverse. You can find them by querying the InvoiceSummary:
GET https://{{URL}}/api/InvoiceSummary?BillToPartyId=101&Balance=gt:0
Note the InvoiceId for each invoice you want to reverse.
Step 2: Submit the reverse-and-rebill task
POST https://{{URL}}/api/TaskDefinition/_execute
{
"$type": "Asi.Soa.Communications.DataContracts.TaskAdhocRequest, Asi.Contracts",
"Task": {
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionData, Asi.Contracts",
"Priority": 0,
"TaskType": 2,
"Triggers": null,
"Evaluations": null,
"DataSources": null,
"Actions": {
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionDataCollection, Asi.Contracts",
"$values": [
{
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionAdhocReverseInvoiceData, Asi.Contracts",
"ActionTypeName": "ReverseInvoice",
"Description": "Reverse Invoice",
"ListOfInvoiceActionFundraisingAdjustmentData": null,
"ListOfInvoiceActionDuesReversalData": [
{
"$type": "Asi.Soa.Commerce.DataContracts.InvoiceActionDuesReversalData, Asi.Contracts",
"InvoiceId": "8158",
"AdjustmentDate": "2025-09-09T00:00:00",
"DoNotCancelMembership": true
}
],
"OriginalBillingLogKey": null,
"ActionNotification": null
},
{
"$type": "Asi.Soa.Communications.DataContracts.TaskDefinitionActionAdHocBillGenerationData, Asi.Contracts",
"ActionId": null,
"ActionTypeName": "GenerateMembershipRenewals",
"Description": "Regular Membership Fees",
"BillGenerationData": {
"$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
"IsRenewal": true,
"EffectiveDate": "2025-09-01T00:00:00Z",
"BillingCycleId": "Regular Membership Fees",
"IndividualBillingPartyId": "101",
"BillingRunName": "Rebill: Regular Membership Fees for 101",
"BillingLogKey": null,
"AutoPayOption": 0
},
"ActionNotification": null,
"IsProcessAutomationAction": false,
"AutomaticallyPostBatch": true
}
]
},
"Notifications": null,
"UpdateInformation": null
},
"EntityTypeName": "TaskDefinition",
"OperationName": "TaskAdhocRequest"
}
Key differences from the bulk reverse and rebill
- ListOfInvoiceActionDuesReversalData — Provide the specific invoice(s) to reverse. When using this, set
OriginalBillingLogKeyon the reverse action tonull.- IndividualBillingPartyId — Set this to the party ID of the single contact to rebill. This ensures only that contact receives a new invoice.
- AdditionalOption.OriginalBillingLogKey — Retains a reference to the original billing run, ensuring iMIS identifies the correct contacts for billing.
Multiple invoices for one contact
If the contact has multiple invoices from the same billing run, add an entry for each invoice in the
ListOfInvoiceActionDuesReversalDataarray.
Updated 5 days ago
