---
title: Payment request
summary: Creates, retrieves, updates, and deletes centralized bill payment requests and manages the collection queue used to drive payment processing.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.Bill
reference_type: package
operation_id: OP-CB-04
trigger: clsCBPBillPaymentRequest.NewCbpBillPaymentRequest / GetCbpBillPaymentRequest, or collection retrieval by process code
---

# Payment request

Payment request manages the centralized bill payment request (CBP) queue: each request represents one payment to be processed for a payee, tracked through a process-code lifecycle (New, Selected, In process, Error, Posted, Complete). The collection supports retrieval filtered by process code and claim, and each request enforces the same rows-affected concurrency contract used across the rest of this library.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CB-04 |
| **Trigger** | Caller calls `clsCBPBillPaymentRequest.NewCbpBillPaymentRequest(inDataportal)` to create a request or `GetCbpBillPaymentRequest(inDataportal, seqNum)` to load one; collections are retrieved by process code and optional claim filter |
| **Inputs** | `BillPaymentSeqNum` (retrieve/create key); process code; claim ID (for claim-scoped retrieval); payee and payment fields; `IDataPortalInfo` |
| **Outputs** | New or populated `clsCBPBillPaymentRequest`; persisted `CBP_BILL_PAYMENT_REQUEST` row; filtered `clsCBPBillPaymentRequestCollection`; broken rules and DB-contention errors on failure |
| **Primary components** | `clsCBPBillPaymentRequest.Create`, `clsCBPBillPaymentRequest.BeforeInsert`/`AfterInsert`, `clsCBPBillPaymentRequest.BeforeRetrieve`/`AfterRetrieve`, `clsCBPBillPaymentRequest.BeforeUpdate`/`AfterUpdate`, `clsCBPBillPaymentRequestCollection.BeforeRetrieve`/`AfterRetrieve`, `clsCBPBillPaymentRequestCollection.AddNew` |
| **Entry point** | `Business\SAIF.Business.Claim.Bill\clsCBPBillPaymentRequest.vb` |

## Steps

1. **Create a new payment request.** `Create()` allocates a new sequence number via `GetNextSeqNum("BILL_PAYMENT_SEQ")`, sets the process code to `"N"` (New), and stamps the update user from the data-portal user.
2. **Insert the request.** `BeforeInsert()` builds a non-query insert into `CBP_BILL_PAYMENT_REQUEST` with all request columns, using `SYSDATE` for `UPDATE_DATE` and `0` for the initial `UPDATE_NUM` ([SQL-002](../sql/SQL-002-saif-business-claim-bill.md), [CBP_BILL_PAYMENT_REQUEST](../database-tables.md#cbp_bill_payment_request)).
   - `AfterInsert()`: if rows affected is not exactly `1`, add `"Insert Failed"` under key `"InsertError"` ([BR-004](../business-rules.md#br-004-optimistic-concurrency-updates-fail-if-rowsaffected-does-not-equal-1)); otherwise `MarkOld()`.
3. **Retrieve a single request.** `BeforeRetrieve()` selects from `CBP_BILL_PAYMENT_REQUEST` where `BILL_PAYMENT_SEQ_NUM = :BillPaymentSeqNum` ([SQL-021](../sql/SQL-021-saif-business-claim-bill.md), [CBP_BILL_PAYMENT_REQUEST](../database-tables.md#cbp_bill_payment_request)). `AfterRetrieve()` reads the first row and calls `Fill(...)`, then `MarkOld()`.
4. **Update the request.** `BeforeUpdate()` updates `CBP_BILL_PAYMENT_REQUEST`, incrementing `UPDATE_NUM` and setting `UPDATE_DATE = SYSDATE` ([SQL-031](../sql/SQL-031-saif-business-claim-bill.md), [CBP_BILL_PAYMENT_REQUEST](../database-tables.md#cbp_bill_payment_request)).
   - `AfterUpdate()`: if rows affected is not exactly `1`, add an error under key `"UpdateError"` using `clsConstants.Messages.DBContentionError` ([BR-004](../business-rules.md#br-004-optimistic-concurrency-updates-fail-if-rowsaffected-does-not-equal-1)); otherwise `MarkOld()`.
5. **Delete the request.** The criteria's delete SQL removes the row from `CBP_BILL_PAYMENT_REQUEST` by sequence number ([SQL-041](../sql/SQL-041-saif-business-claim-bill.md), [CBP_BILL_PAYMENT_REQUEST](../database-tables.md#cbp_bill_payment_request)).
6. **Map process codes.** `clsCBPBillPaymentRequestCollection.GetProcessCodeMap` maps `"N"`, `"S"`, `"I"`, `"E"`, `"P"`, `"C"` to `New`, `Selected`, `InProcess`, `Error`, `Posted`, `Complete` respectively.
7. **Retrieve the request queue.** `clsCBPBillPaymentRequestCollection.BeforeRetrieve()` sets the collection retrieve SQL and binds `ProcessCode` and `RushClaimID`. The retrieve SQL selects from `CBP_BILL_PAYMENT_REQUEST` where `PROCESS_CODE = :ProcessCode` and `(CLAIM_ID = :RushClaimID or :RushClaimID = 0)`, with `payee_type_code like decode(:RushClaimID, 0, '%', 'W')`, ordered by MCO, provider, worker, and bill ([SQL-022](../sql/SQL-022-saif-business-claim-bill.md), [CBP_BILL_PAYMENT_REQUEST](../database-tables.md#cbp_bill_payment_request)).
   - `AfterRetrieve()` loads each row into a `clsCBPBillPaymentRequest.Load(...)` item and adds it to the collection.
   - When `RushClaimID` is `0`, the claim filter is bypassed and the payee-type filter is relaxed to match all payee types; a non-zero `RushClaimID` narrows the queue to worker-payee (`'W'`) requests for that claim.*
8. **Add a request to the collection (`AddNew`).** Creates a new child item through the factory, adds it to the collection, sets it as the current item, and returns its newly allocated sequence number.
9. **List and locate requests.** The collection exposes an integer indexer and a `BillPaymentSeqNum` indexer, plus `CurrentItem`, `Remove`, `Contains`, `ContainsDeleted`, `Where`, and `ToList` for in-memory querying — no additional database access.
10. **Save the collection.** `Save()` calls `ApplyEdit()` then `MyBase.Save()`, cascading insert/update/delete to each dirty child request per steps 2–5.

## Process flow

The following diagram visualizes payment-request creation and the process-code driven retrieval queue.

```mermaid
flowchart TD
	Start([Caller creates or retrieves<br>a payment request]) --> Which{Create or retrieve?}
	Which -->|Create| Alloc[Allocate BILL_PAYMENT_SEQ;<br>set ProcessCode = N]
	Alloc --> Insert[Insert CBP_BILL_PAYMENT_REQUEST]
	Insert --> InsRows{RowsAffected = 1?}
	InsRows -->|No| InsFail([Insert Failed])
	InsRows -->|Yes| Ready([Request ready for processing])
	Which -->|Retrieve single| Select[Select by BillPaymentSeqNum]
	Select --> Fill[Fill fields; MarkOld]
	Which -->|Retrieve queue| Queue[Select by ProcessCode<br>and optional RushClaimID]
	Queue --> Load[Load each row into collection]
	Fill --> Edit[Caller edits request<br>e.g. advances ProcessCode]
	Load --> Edit
	Edit --> Update[Update CBP_BILL_PAYMENT_REQUEST]
	Update --> UpdRows{RowsAffected = 1?}
	UpdRows -->|No| Contention([DB contention error])
	UpdRows -->|Yes| Done([Save returns success])
```

## Failure and edge-case behavior

- Insert and update failures use distinct error keys (`"InsertError"` vs. `"UpdateError"`) but the same underlying concurrency contract ([BR-004](../business-rules.md#br-004-optimistic-concurrency-updates-fail-if-rowsaffected-does-not-equal-1)).
- No object-level business rules are registered on `clsCBPBillPaymentRequest` (`AddBusinessRules` defines none), so field-level validation for payment requests is not enforced by this class.*
- A `RushClaimID` of `0` is a sentinel meaning "no claim filter," not a literal claim ID of zero; callers must pass `0` deliberately to retrieve the full unfiltered queue for a process code.*
- The process-code map does not define a default/unknown mapping, so an unrecognized code value is not shown to resolve to a fallback enum member in the traced source.*

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources

- `Business\SAIF.Business.Claim.Bill\clsCBPBillPaymentRequest.vb`
- `Business\SAIF.Business.Claim.Bill\clsCBPBillPaymentRequestCollection.vb`
