---
title: BillPaymentService
summary: API reference for BillPaymentService.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-24
library: SAIF.Services
reference_type: package
---

# BillPaymentService

Generates payments for approved legal bills — zero-payment print letters via `IDocumentService`/`PrintData.XPrintControl`, financial check transactions via `IFinancialTransactionService.CreateLegalCheckTransaction`, and partial-refund recovery transactions via `IFinancialDataApiClient.CreateRecoveryAsync` — and reverses (`ReturnBillPayment`) previously paid, non-amended bills by creating a recovery transaction through Guidewire's claim-financial data. It also compiles per-attorney pending-bill notification counts and moves bills between status codes, wrapping each mutating operation in `IUnitOfWork.Begin()`/`Commit()` transactions.

## Purpose
- Produces zero-payment letters (print batch + XML) for approved bills whose services net to a zero paid amount, then advances those bills to `Paid` status.
- Compiles the list of attorneys with pending-approval legal bills, for notification purposes.
- Generates financial check transactions for approved-and-ready-to-pay bills (`GenerateCheckTransactionsAsync`), handling top-level and adjusted/child bills differently, including invalid-payment-address rejection and partial-refund recovery for reduced adjusted payments.
- Bulk-transitions bill status codes (`UpdateBillStatus`) and creates the corresponding status-history entries.
- Reverses a paid bill's payment (`ReturnBillPayment`) by creating a recovery financial transaction and resetting paid amounts to zero, refusing to do so for amended bills.

## Context
- Namespace: `SAIF.Services.Legal.Bills`
- Assembly/package: `SAIF.Services` (packaged inside the `SAIF.SAIFCode.Core` NuGet package).

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| BillPaymentService (constructor) | `public BillPaymentService(IUnitOfWork unitOfWork, IUserProfileService userProfileService, ProviderContract.IProviderInformationService providerInformationService, ILegalQueryProvider legalQueryProvider, UtilDocument.IDocumentService documentService, IEnvironmentService environmentService, ILogService logService, IFinancialTransactionService financialTransactionService, IClaimDataApiClient gwclaimDataApiClient, IActivityDataApiClient activityDataApiClient, IFinancialDataApiClient financialDataApiClient, string developerEmails)` | Wires the unit of work, user-profile, provider-information, legal-query, document, environment, log, financial-transaction, claim-data/activity-data/financial-data API clients, and a development-team email address used for address-correction alerts. |
| GenerateZeroPaymentLetters | `public long GenerateZeroPaymentLetters(ZeroPaymentBatchArguments batchArguments)` | Within a transaction, creates an `XPrintControl`/`XDocument` print batch, generates a `ZeroPayment` record for each zero-paid service on ready-to-pay bills with an adjustment reason, advances those bills to `Paid`, writes the resulting XML to disk (with document-element renaming), and returns the count of zero-payment records produced. |
| GetAttorneysWithPendingLegalBills | `public IList<AttorneyNotificationRequest> GetAttorneysWithPendingLegalBills()` | Returns one `AttorneyNotificationRequest` per attorney who has pending-approval bills assigned, including their pending-bill count, for use in notification batch jobs. |
| GenerateCheckTransactionsAsync | `public async Task<FinancialTransactionControlStats> GenerateCheckTransactionsAsync(DateTime issueDate, ILogWriter controlReport)` | Moves `Approved` bills to `ReadyToPay`, then for each ready-to-pay bill either counts it as a zero-pay letter (already handled elsewhere), generates a check transaction (top-level bills), or generates an adjusted-bill transaction (child bills), accumulating counts/failures into the returned `FinancialTransactionControlStats`. |
| UpdateBillStatus | `public long UpdateBillStatus(string fromCode, string toCode)` | Transactionally transitions every bill with the given `fromCode` status to `toCode`, recording a status-history entry for each, and returns the number of bills updated. |
| ReturnBillPayment | `public async Task<long> ReturnBillPayment(long billId, IMessageContainer messageContainer)` | Reverses a paid, non-amended bill's payment by creating a recovery financial transaction against Guidewire claim financials, zeroing the bill's service paid amounts and setting status to `PaymentReturned`; adds an error and rolls back (returning `0`) if the bill is not found, is amended, or the recovery call fails. |

## Behavioral notes
- A static constructor calls `BillMappingHelper.MapBillService()`, registering the AutoMapper mappings this service relies on once per process.
- `GenerateCheckTransactionAsync`/`GenerateTransactionsForAdjustedBillAsync` open the unit of work **before** re-querying the bill by ID specifically to initialize the NHibernate lazy-load proxy and avoid `LazyInitializationException`, per an inline code comment.
- On `InvalidPaymentAddressException`, the bill is rejected for address correction (`RejectBillForAddressCorrection`) — its status is set to `ApprovedWithChange`, a comment is appended, and an email is sent to either the bill creator or the configured development team depending on environment — rather than aborting the whole batch.
- On any other exception during check-transaction generation, `ReportProgressOnAbort` writes progress statistics to the control report before the exception is rethrown, aborting the run.
- `GenerateTransactionsForAdjustedBillAsync` requires an adjusted/child bill to have exactly one service line and a resolvable parent bill/original service; missing any of these records a failure message and commits without generating a transaction.
- A negative change in the adjusted service's paid amount triggers a partial-refund recovery transaction (`CreatePartialRefundAsync`) instead of a check transaction.
- `ReturnBillPayment` looks up the existing Guidewire payment transaction for the bill via `IClaimDataApiClient.GetGWClaimFinancials` before creating a `RecoveryFinancialData` recovery request through `IFinancialDataApiClient.CreateRecoveryAsync`.

## Constraints and usage notes
- Only `unitOfWork`, `userProfileService`, `providerInformationService`, `legalQueryProvider`, `documentService`, `environmentService`, `logService`, `financialTransactionService`, and `developerEmails` are null-checked in the constructor via `Enforce.ArgumentNotNull`; `gwclaimDataApiClient`, `activityDataApiClient`, and `financialDataApiClient` are not validated for null.*
- `GenerateZeroPaymentLetters` writes directly to the file system (`batchArguments.FullXmlFileName`) as part of its side effects, outside the database transaction.*
- The class carries a `CA1506:AvoidExcessiveClassCoupling` suppression, reflecting its dependency on a large number of API clients and services.*

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `Services/SAIF.Services/Legal/Bills/BillPaymentService.cs`
