Generating renewals
Using the LegacyBilling endpoint, you can generate renewals for a single contact or multiple contacts at once. While invoices can be created by simply adding subscription records, generating renewals is a more robust way to create an invoice for subscriptions. It can be used to create accrual invoices and it can bill multiple subscriptions into a single invoice.
To generate a renewal:
- Find or create a LegacyBillingCycle. The billing cycle will either need to list all subscription products to bill, or it will need to have the IncludeAllMembershipItems property set to true (in which case, it will bill all items listed in the customer type for a given contact.)
- Use the LegacyBilling API to generate the renewal.
- If the system is configured for persisted cash invoices, or the billing cycle is configured for the accrual accounting method, then post the batch created by the billing.
Example: Creating a billing cycle
This example shows how to create a non-dues billing cycle to be used to generate an invoice for the two subscription products: JOUR and INSIDMAG
POST https://{{URL}}/api/LegacyBillingCycle
{
"LegacyBillingCycleId": "Journals and Subscriptions",
"Name": "Journals and Subscriptions",
"AccountingMethod": 1,
"BillingCategories": {
"$values": [
{
"Name": "*ALL*",
"Value": "*ALL*"
}
]
},
"CustomerTypes": {
"$values": [
{
"Name": "*ALL*",
"Value": "*ALL*"
}
]
},"SubscriptionItemsToBill": {
"$values": [
{
"ItemClass": {
"ItemClassId": "SUB",
"Name": "Subscription"
},
"ItemCode": "JOUR",
"ItemId": "JOUR",
"Name": "Journal"
},
{
"Description": "",
"ItemClass": {
"ItemClassId": "SUB",
"Name": "Subscription"
},
"ItemCode": "INSIDMAG",
"ItemId": "INSIDMAG",
"Name": "Insider Magazine"
}
]
}
}
Example: Billing an individual
To bill a single contact, use the RunIndividual operation on the LegacyBilling endpoint
POST https://{{url}}/api/LegacyBilling/_exectue
{
"$type": "Asi.Soa.Core.DataContracts.GenericExecuteRequest, Asi.Contracts",
"OperationName": "RunIndividual",
"EntityTypeName": "LegacyBilling",
"Parameters": {
"$values": [
{
"$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
"IsRenewal": true,
"RunDate": "2025-12-01T00:00:00",
"EffectiveDate": "2026-01-01T00:00:00",
"BillingCycleId": "Journals and Subscriptions",
"IndividualBillingPartyId": "23215",
"BillingRunName": "Generate renewals for Demo Contact"
},
{
"$type": "System.String",
"$value": "23215"
}
]
}
}
Example: Billing in bulk
To generate an invoice for all contacts with the unbilled subscription, use the Run operation and do not pass in a particular PartyId.
POST https://{{url}}/api/LegacyBilling/_exectue
{
"$type": "Asi.Soa.Core.DataContracts.GenericExecuteRequest, Asi.Contracts",
"OperationName": "Run",
"EntityTypeName": "LegacyBilling",
"Parameters": {
"$values": [
{
"$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
"IsRenewal": true,
"RunDate": "2025-12-01T00:00:00",
"EffectiveDate": "2026-01-01T00:00:00",
"BillingCycleId": "Journals and Subscriptions",
"BillingRunName": "Generate renewals for Journals and Subscriptions"
}
]
}
}
Example: Posting a billing batch
After the POST operation to RunIndividual or Run on the LegacyBilling endpoint, you will get a result similar to this (some fields removed for readability).
{
"Messages": {
"$values": [
{
"Message": "Added Batch 251201-1 for billing run"
}
]
},
"HasMessages": true,
"LegacyBillingDataUsedByService": {
"IsRenewal": true,
"RunDate": "2025-12-01T00:00:00",
"EffectiveDate": "2026-01-01T00:00:00",
"BillingCycleId": "Journals and Subscriptions",
"BatchId": "251201-1",
"BillingRunName": "Generate renewals for Journals and Subscriptions",
"BillingLogKey": "60a3c7c4-4461-42f6-8be6-19b302a1e748"
}
}
A BatchId will be populated if persisted cash invoices have been enabled or if the billing cycle is configured to use the Accrual accounting method. If a value is populated, you should be able to post the batch via the BatchSummary endpoint.
POST https://{{URL}}/api/BatchSummary/_execute
{
"$type": "Asi.Soa.Core.DataContracts.GenericExecuteRequest, Asi.Contracts",
"OperationName": "Post",
"EntityTypeName": "BatchSummary",
"Parameters": {
"$values": [
{
"$type": "System.String",
"$value": "251201-1"
}
]
}
}
Once this is complete, you can find the generated invoice in one of two ways:
- GET the subscription again to find the InvoiceId
- GET on the InvoiceSummary endpoint
https://{{URL}}/api/InvoiceSummary?BillToPartyId=23215&SourceSystem=DUES&Balance=gt%3A0
Properties available in LegacyBillingData
This JSON shows all properties available in the LegacyBillingData. Note that the IsRenewal property must be set to true. The Rebill properties only apply when billing a real using the cash accounting method and persisted cash invoices have not yet been enabled.
{
"$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
"IsRenewal": true,
"IsRebill": true,
"AdditionalOption": {
"DoNotProrate": false,
"DoNotApplyCredits": false,
"UseQuery": false,
"ProcessSpecificChapter": false,
"QueryPathName": "$/QueryPathHere",
"QueryId": "Query GUID here"
},
"RunDate": "2025-12-01T00:00:00-05:00",
"EffectiveDate": "2026-01-01T00:00:00",
"BeginRebillDate": "2025-11-01T00:00:00",
"EndRebillDate": "2025-12-01T00:00:00",
"ChapterCode": "ChapterCode Value",
"BillingCycleId": "Regular Membership Fees",
"IndividualBillingPartyId": "23095",
"BillingRunName": "Billing run for Alex Morgan",
"AutoPayOption": 0
}
AutoPayOption values:
- 0 - Not defined (use the value on the billing cycle)
- 1 - Bill all contacts
- 2 - Bill only contacts with AutoPay enrollments
- 3 - Bill only contacts without AutoPay enrollments
Updated 3 days ago