Payment return handling¶
clsPaymentReturn records that a previously-issued electronic payment was returned by the receiving bank, along with the NACHA return reason. It joins to PAYMENT_RETURN_REASON_GCODE for a culture-aware description of the reason and can create a backout or vendor-refund clsPaymentEvent once a returned payment has been reviewed. Returns are permanent, append-mostly records: DeleteSQL is intentionally disabled.
| Field | Value |
|---|---|
| Operation ID | OP-EFT-08 |
| Trigger | Reconciliation process creates a clsPaymentReturn referencing the original PaymentDetailSeqNum and the bank-reported return reason code |
| Inputs | PaymentDetailSeqNum, return type code, return reason code, return date |
| Outputs | Persisted PAYMENT_RETURN row; culture-aware return-reason description; PAYMENT_EVENT row of type BackoutEvent or VendorRefund once reviewed |
| Primary components | clsPaymentReturn.BeforeCreate/Insert/Retrieve, MarkReviewed, CreateBackoutPaymentEvent; clsPaymentReturnReasonCode(+Collection); clsReturnStatusCode; clsReturnTypeCode |
| Entry point | Business\SAIF.Business.Payment.EFT\clsPaymentReturn.vb |
Steps¶
- Create a new return record.
NewPaymentReturnfetches the next sequence value (SQL-008, DUAL) and links it to the originalPaymentDetailSeqNumfrom Payment detail, events, and allocation. - Classify the return using NACHA reference codes. The return reason code is validated against
clsPaymentReturnReasonCode/Collection(SQL-066, SQL-067) and classified per BR-EFT-03; return status and return type are validated againstclsReturnStatusCode(SQL-070, SQL-071) andclsReturnTypeCode(SQL-072, SQL-073) respectively (see Code table lookups). - Insert.
BeforeInsert/AfterInsertexecutesINSERT INTO PAYMENT_RETURN (...)(SQL-020, PAYMENT_RETURN). - On failure (
RowsAffected <> 1): adds anInsertErrormessage (BR-EFT-05). - Retrieve with culture-aware return-reason description. The single-record retrieval query joins
PAYMENT_RETURN_REASON_GCODEon the current session's culture/language so the return-reason description text is presented in the caller's language rather than a single hard-coded locale (SQL-064, PAYMENT_RETURN, BR-EFT-07). - Collection retrieval.
clsPaymentReturnCollectionretrieves multiple returns using the same culture-aware join, for reconciliation reporting (SQL-065). - Mark as reviewed.
MarkReviewedupdates the return row's status once an operator has reviewed and acted on it (SQL-086, PAYMENT_RETURN). - Create a backout or vendor-refund event.
CreateBackoutPaymentEventcreates aclsPaymentEventof typeBackoutEvent(internal accounting reversal) orVendorRefund(funds returned to the vendor), depending on the return's classification, using the same immutable event-insert mechanism documented in Payment detail, events, and allocation (SQL-019, PAYMENT_EVENT). - Update. Further updates to the return record (e.g., correcting the reason code before final processing) use the same standard
UPDATE PAYMENT_RETURNstatement as the review step (SQL-086). - No cross-reference to authorization revocation.
clsPaymentReturnnever reads from or writes toclsEFTAuthorizationbeyond the read-only culture-aware description join above — a payment return does not automatically revoke the customer's EFT authorization / consent; revocation, if warranted, is a separate, manually-initiated action. - Deletion is disabled.
DeleteSQLis overridden to always throw, with the source comment indicating a payment return "should not be deleted once created" — returns are a permanent audit record.
Process flow¶
flowchart TD
Start([Bank reports a returned payment]) --> Create[Create PaymentReturn record]
Create --> Classify[Classify by NACHA return reason code]
Classify --> Insert[INSERT PAYMENT_RETURN]
Insert --> Rows{RowsAffected = 1?}
Rows -->|No| Err([InsertError added])
Rows -->|Yes| Retrieve[Retrieve with culture-aware<br>reason description]
Retrieve --> Review{Reviewed?}
Review -->|No| Pending([Awaiting operator review])
Review -->|Yes| Mark[MarkReviewed]
Mark --> Event[CreateBackoutPaymentEvent:<br>BackoutEvent or VendorRefund]
Event --> NoRevoke([Authorization NOT revoked<br>automatically])
NoRevoke --> Done([Return processing complete])
Failure and edge-case behavior¶
- Because
clsPaymentReturnnever revokes the relatedclsEFTAuthorization, a recurring pattern of returns for the same customer/bank account will not automatically stop future auto-pay attempts unless a separate process explicitly callsRevokeAuthorizationin EFT authorization / consent.* DeleteSQLalways throws — a return record, once inserted, is permanent and can only be corrected via update, never removed.- The culture-aware reason-description join depends on the caller's active session culture; if no matching localized row exists in
PAYMENT_RETURN_REASON_GCODE, the description may render blank or fall back to a default language row (BR-EFT-07).*
Related documentation¶
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.Payment.EFT\clsPaymentReturn.vbBusiness\SAIF.Business.Payment.EFT\clsPaymentReturnCollection.vbBusiness\SAIF.Business.Payment.EFT\clsPaymentReturnReasonCode.vbBusiness\SAIF.Business.Payment.EFT\clsReturnStatusCode.vbBusiness\SAIF.Business.Payment.EFT\clsReturnTypeCode.vb