Business Payment Methods
Overview
The business-payment-methods module manages the many-to-many relationship between a business and the global payment method catalog. Each record represents a payment method that a specific business has enabled, along with business-specific configuration such as display order, authorization requirements, and active/inactive state.
When a new business is created, the module automatically seeds a default set of payment methods based on the business's country.
Domain Concepts
Business Payment Method
A join entity between a business and a global paymentMethod. Key attributes:
| Field | Type | Description |
|---|---|---|
businessId | UUID | The owning business |
paymentMethodId | UUID | Reference to the global payment method catalog |
isActive | boolean | Whether this method is visible at checkout |
sortOrder | integer | Display order in POS UI |
requireAuthorization | boolean | Flags that the cashier must enter an authorization code |
requireReference | boolean | Flags that a reference/voucher number must be captured |
Global Payment Method Catalog
The paymentMethod table holds the master list of payment methods (Cash, Credit Card, BAC Card, etc.) with metadata:
name— display namepaymentGroup— logical group (e.g.electronicAndCardPayments,cashAndManual,bankRelated)generatesAccountsReceivable— whether this method creates an AR recordgeneratesAccountsPayable— whether this method creates an AP record
Hierarchy
This module sits in a 3-level hierarchy:
paymentMethod— Global master catalog (managed bypayment-methodsmodule)businessPaymentMethod— Business-level configuration (this module)documentPaymentMethod— Document-type configuration (managed bydocument-payment-methodsmodule)
Architecture
This module follows Hexagonal Architecture (ports & adapters):
domain/
business-payment-methods-repository.domain.ts ← Port (interface)
application/
business-payment-methods.service.ts ← Use cases
infrastructure/
business-payment-methods.repository.ts ← Adapter (Kysely)
interfaces/
business-payment-methods.controller.ts ← HTTP adapter
dtos/
create-business-payment-method.dto.ts
update-business-payment-method.dto.ts
query/
paginate-business-payment-methods.query.ts
Dependency Direction
Controller → Service → Repository Interface ← Repository Implementation
The service depends on the concrete BusinessPaymentMethodsRepository (project convention). The repository implements IBusinessPaymentMethodsRepository (domain port). NestJS DI handles the injection.
Security
All endpoints are protected by:
- Firebase AuthGuard (global) — validates ID tokens
- RolesGuard — enforces RBAC via CASL
- PermissionResource —
PolicyResource.BusinessPaymentMethod - PermissionAction — per-endpoint Create / Read / Update / Delete
Use Cases
1. Enable a Payment Method (createBusinessPaymentMethod)
Creates a single businessPaymentMethod record linking a business to a payment method.
Trigger: Manual configuration from the business settings UI.
2. List Active Payment Methods (getAllBusinessPaymentMethods)
Returns paginated, enriched records — each base record joined with paymentMethod.name, paymentGroup, and AR/AP flags. Only isActive = true records are returned. Supports sorting by sortOrder, createdAt, and isActive.
3. Get by ID (getBusinessPaymentMethodById)
Returns a single record. Returns 404 if not found.
4. Update Configuration (updateBusinessPaymentMethod)
Updates isActive, sortOrder, requireAuthorization, requireReference. Tracks updatedBy for audit.
5. Disable / Soft Delete (deleteBusinessPaymentMethod)
Sets isActive = false, tracking the updatedBy user for audit. The record is preserved.
Exposed as PATCH /business-payment-methods/disable-bc/:id.
6. Seed Defaults on Business Creation (handleBusinessCreateEvent)
Listens to OnCreateBusinessEvent. Seeds country-specific default payment methods:
| Country | Default Methods |
|---|---|
Guatemala (gt) | Cash, BAC Card, NeoNet Card, Credit Card, Debit Card, Accounts Receivable, Accounts Payable, Courtesy, Material Consumption |
| All others | Cash, Credit Card, Debit Card |
API Endpoints
All endpoints require Firebase Bearer token authentication and BusinessPaymentMethod RBAC permissions.
| Method | Path | Permission | Description |
|---|---|---|---|
POST | /business-payment-methods | Create | Enable a payment method for a business |
GET | /business-payment-methods | Read | List active methods (paginated, filterable by businessId) |
GET | /business-payment-methods/:id | Read | Get a single record by ID |
PATCH | /business-payment-methods/:id | Update | Update configuration fields |
PATCH | /business-payment-methods/disable-bc/:id | Delete | Soft-delete (disable) a method |
Example Requests
Enable a payment method
POST /business-payment-methods
Authorization: Bearer <token>
Content-Type: application/json
{
"businessId": "550e8400-e29b-41d4-a716-446655440000",
"paymentMethodId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"isActive": true,
"createdBy": "c3d4e5f6-a1b2-7890-abcd-ef1234567890"
}
List active methods for a business
GET /business-payment-methods?businessId=550e8400-e29b-41d4-a716-446655440000&size=20&page=1&orderBy=sortOrder&order=asc
Authorization: Bearer <token>
Update configuration
PATCH /business-payment-methods/bpm-uuid
Authorization: Bearer <token>
Content-Type: application/json
{
"sortOrder": 3,
"requireAuthorization": true,
"requireReference": false,
"updatedBy": "c3d4e5f6-a1b2-7890-abcd-ef1234567890"
}
Disable a payment method
PATCH /business-payment-methods/disable-bc/bpm-uuid?businessId=biz-uuid&userId=usr-uuid
Authorization: Bearer <token>
Design Decisions
Soft Delete via Dedicated Endpoint
The PATCH /disable-bc/:id endpoint performs a tracked soft-delete rather than a hard delete. This preserves historical transaction data where the payment method was used, and provides an audit trail of who disabled the method. The route name disable-bc stands for "disable business connection."
Country-Based Seeding
Guatemala (gt) receives an expanded default set that includes bank-specific card types (BAC, NeoNet) and internal accounting methods (AR, AP, Courtesy, Material Consumption) common in the local market.
findAll Always Filters isActive = true
The list endpoint only surfaces active payment methods since its primary consumer is the POS checkout UI. To inspect inactive records, query directly by ID.
JoinedBusinessPaymentMethod vs SelectableBusinessPaymentMethod
The findAll endpoint returns JoinedBusinessPaymentMethod[] — a superset of the base database type enriched with paymentMethodName, paymentGroup, generatesAccountsReceivable, and generatesAccountsPayable from the joined paymentMethod table. This avoids N+1 queries at the cost of a fixed inner join on every list call.
Update DTO Independence
The UpdateBusinessPaymentMethodDTO does not extend CreateBusinessPaymentMethodDTO. This prevents unintended mutation of immutable fields (businessId, paymentMethodId, createdBy) during updates. Only mutable configuration fields (sortOrder, requireAuthorization, requireReference, isActive) and the updatedBy audit field are exposed.
Bruno API Collection
Located at: api-client/flowpos/collections/business-payment-methods/
| File | Request |
|---|---|
business payment methods.yml | GET — List business payment methods |
business payment method.yml | POST — Create business payment method |
business payment method by Id.yml | GET — Get by ID |
business payment method_1.yml | PATCH — Update business payment method |
business payment method_2.yml | PATCH — Disable (soft delete) |
Environment variables required: BASE_URL, ID_TOKEN, businessId, paymentMethodId, userId, businessPaymentMethodId.