Supplier payments and deposit accounts
What it is
Two directions, two concepts:
- Outgoing payment configuration (
paymentConfigKey) -
How Payability pays the supplier — the method (ACH, wire, prepaid card, …) and its parameters. A supplier may have several.
- Deposit account (
depositAccountKey) -
The supplier’s bank account.
SupplierDetailsModel.depositAccountKeypoints at the primary one.
The tab also carries payment features (auto-payment settings), velocity limits and, for card programmes, JIT (just-in-time funding) simulation.
Where it lives
| Concern | Location |
|---|---|
Routes |
|
Components |
|
Services |
|
Models |
|
Store |
The |
Both PaymentConfigService and DepositAccountService are provided by explicit
token in AppModule ({ provide: X, useClass: X }) so specs can substitute them.
Routing note
new, edit/:paymentConfigKey and deposit-account-edit/:depositAccountKey each
carry their own NgxPermissionsGuard with the standard deny clause, in addition to
the parent’s. Editing a payment method is therefore double-gated. list is not.
Also note edit/:paymentConfigKey and new share
OutgoingPaymentAddComponent — the component distinguishes create from edit by the
presence of the route parameter.
Payment configuration endpoints
All on internalApiUrl:
| Endpoint | Purpose |
|---|---|
|
List a supplier’s payment configurations. |
|
One configuration. |
|
Create (body serialised with |
|
Update. |
|
Delete. |
|
Spending velocity limits for the supplier. |
|
Auto-payment / payment feature flags ( |
JIT simulation
PaymentConfigService exposes five simulation endpoints used to exercise
just-in-time card funding without real transactions:
POST suppliers/:key/jit/simulate/pending
POST suppliers/:key/jit/simulate/rejected
POST suppliers/:key/jit/simulate/charge
POST suppliers/:key/jit/simulate/cleared
POST suppliers/:key/jit/simulate/refund
These are operator/QA tools for the card programmes — see cards.
They post null bodies and are safe only on non-production environments; the
backend enforces that, not the client.
Deposit account endpoints
| Endpoint | Purpose |
|---|---|
|
Read. |
|
Create. |
|
Update. |
|
A second POST on the keyed URL — used for a document/action submission rather than creation. |
DepositAccountService is one of the few services that also reaches
documentsApiUrl — deposit-account supporting documents live in the documents
Lambda, not the internal API.
Manual bank accounts can be bulk imported: BatchImportService.addNewMBAccounts
posts a CSV to deposit_accounts/csv_upload. Similarly pre-funded cards go to
payment/configs/csv_upload. See bulk actions.
Routing-number validation
Bank routing numbers are validated with a status vocabulary rather than a boolean.
suppliers/enums/routing-number-validation-status.enum.ts:
export enum RoutingNumberValidationStatus {
INCORRECT_ROUTING_NUM,
VERIFIED,
PENDING_VERIFICATION,
INSUFFICIENT_FOR_NATIONAL_PAYMENT,
INSUFFICIENT_FOR_INTERNATIONAL_PAYMENT,
NONE,
}
Each status maps to a message and a severity via
RoutingNumberValidationStatusConfig and
RoutingNumberValidationStatusType (success / danger / warning).
The two INSUFFICIENT_FOR_* statuses are the interesting ones: the routing number
is valid but the bank cannot receive that payment type. National and international
are distinguished, so a supplier can be payable domestically and not by wire.
A form validator enforces verification
(supplier-payment/routing-num.validator.ts):
export function routingNumberStatus(value): ValidatorFn {
return (control) => {
const isVerified = value === 'VERIFIED';
return isVerified ? { routingNumNotVerified: { value: control.value } } : null;
};
}
|
The logic reads inverted: the error |
Plaid bank verification
supplier-payment-list/supplier-payment-plaid-information/supplier-plaid.service.ts
(+ mock) surfaces Plaid-derived bank information for a payment method. The app does
not embed the Plaid Link SDK — the data arrives through the internal API. The
transaction-level Plaid data appears separately as an underwriting report tab
(ExternalReports.PLAID). See
underwriting.
Payment history
outgoing-payment-add/payment-history.service.ts provides the history shown
alongside a payment configuration — prior payments made using that method.
Broader transaction views are separate tabs:
/suppliers/:key/transaction-summary
(suppliers/supplier/supplier-transaction-summary/) and
/suppliers/:key/transaction-details
(supplier-transaction-details/), with
suppliers/supplier/transaction-modal/ for individual transaction detail.
Store integration
Payment configurations are the one area that uses the actionId idiom rather than
per-operation flags. Actions in the supplier slice:
| Action | Effect |
|---|---|
|
Loads into |
|
Create. |
|
Update. Note the misspelled request constant. |
|
Delete. |
|
Write and clear entries in |
The caller generates an actionId, dispatches the operation, watches
paymentConfigsPending[actionId], then dispatches PC_CLEAR_STATUS. Forgetting the
clear leaves a stale status that the next render of the same actionId will pick up.
selectPaymentMethods is exported from supplier.actions.ts and is used by
AppComponent to tell EVA whether the supplier has an EFS card
(paymentType === 'EFS' or pcardAvailable) — see
iframe messaging.
Related supplier actions
Money-moving operations that are not payment configuration live in the Actions menu and are documented in lifecycle actions and transactions: add receivable, add chargeback, add bad-debt recovery, add write-off, adjust the Payability fee, add a fund-transfer request, and the marketplace payment/statement adjustments.
Batch-level payment release is processes and batches, and the pre-release treasury check is balance approval.
Gotchas
-
MANAGE_LINKING_PAYMENT_GATEWAYSis a permission in the enum; gateway linking on the supplier’s marketplace record is separate from payment configuration — see marketplaces. -
ADD_PAYMENT_GATEWAYin the supplier reducer resets the slice toinitialState(keeping only the mutatedsupplierModel), discarding the multi-supplier cache and every part-edit map. -
AutoPaymentServicebuilds its URL asinternalApiUrl + 'suppliers'and then concatenates/${supplierKey}/…, so the base has no trailing slash while other services in the same folder do include one. Match the file you are editing.