Payment instruments
Register bank and card instruments as owner-bound vault tokens, let provider events establish verification, and stop future use without erasing financial history.
A payment instrument is an owner-bound reference to a provider-vaulted bank account or card. It can be the source of a payment, the destination of a funding or refund, or the instrument behind an autopay enrollment.
Security boundary
LendEasy accepts a providerTokenRef—a vault token—never a raw account or card value. The server resolves the token to derive the masked display, rail capabilities, and type. Ordinary reads return masked metadata only; raw numbers are never stored, so no route can leak them.
| Accepted | Rejected |
|---|---|
providerTokenRef: "vault:ach:tok_sandbox_bank_44" |
Routing and account number |
authorizationRef evidence reference |
Card PAN or security code |
| Owner fixed by the nested resource path | Caller-asserted owner that disagrees with the path |
| Provider verification events | Screenshots or secret values in notes |
Lifecycle
Two axes matter at execution time: status (ACTIVE or INACTIVE) and verificationState (UNVERIFIED, VERIFIED, or FAILED). Payments, autopay, and funding all demand status: ACTIVE and verificationState: VERIFIED.
Add and manage
Use the end-to-end Add & verify a payment instrument recipe. The routes are:
POST /v1/customers/{customerId}/payment-instruments
GET /v1/customers/{customerId}/payment-instruments
GET /v1/customers/{customerId}/payment-instruments/{instrumentId}
PUT /v1/customers/{customerId}/payment-instruments/{instrumentId}
POST /v1/customers/{customerId}/payment-instruments/{instrumentId}/deactivate
GET /v1/customers/{customerId}/payment-instruments/{instrumentId}/sensitive
Create takes instrumentType (ACH_BANK or CARD), the providerTokenRef, and an optional authorizationRef (CREATE_LMS_PAYMENT_INSTRUMENT):
curl -X POST "$BASE/v1/customers/412/payment-instruments" \
-H "Authorization: Bearer $TOKEN" \
-H "LendEasy-Tenant: demo-lender" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: maya-checking-token-v1" \
-d '{
"instrumentType": "ACH_BANK",
"providerTokenRef": "vault:ach:tok_sandbox_bank_44",
"authorizationRef": "evd_BANK_AUTH_11"
}'
{ "resourceId": 704 }
A representative masked read is:
{
"instrumentId": 704,
"instrumentType": "ACH_BANK",
"maskedDisplay": "••6789",
"railCapabilities": ["ACH"],
"verificationState": "VERIFIED",
"accountValidationStatus": "VALIDATED",
"status": "ACTIVE",
"createdAt": "2026-08-11T16:10:00Z",
"lastModifiedAt": "2026-08-11T16:12:00Z"
}
Lists filter by status, instrumentType, and verificationState. PUT replaces the vault token or authorization reference; a new token must resolve to the same immutable instrumentType and refreshes the masked display and rail capabilities.
GET …/sensitive adds providerTokenRef and authorizationRef to the masked fields. It requires both READ_LMS_PAYMENT_INSTRUMENT and READ_LMS_PAYMENT_INSTRUMENT_SENSITIVE; every call is audited and the response is never cached.
Verification is not authorization
Verification answers whether the provider confirmed the instrument and owner. Authorization answers whether the customer permitted this debit or recurring series. A one-time payment carries one-time evidence; autopay carries its Reg E authorizationRef and enrollment terms. Both still require an eligible instrument at execution.
Execution-time gate
Before moving money, LendEasy checks:
- the owner in the resource path matches the payer or permitted recipient;
statusisACTIVEandverificationStateisVERIFIED;- the requested rail is in
railCapabilities; - required one-time or recurring authorization evidence exists;
- no
PAYMENT_HOLDorDISBURSEMENT_HOLDrestriction blocks the movement; - an optional
Idempotency-Keyguards the create against duplicate submission.
Returns and deactivation
Return-code policy distinguishes temporary funds conditions from structural account failures. Per-rail autopay failure policies decide, code by code, whether the instrument is kept or invalidated and whether autopay continues, enters review, or is cancelled; unknown codes fail closed to review. LendEasy never rewrites the state of historical payments that used the instrument.
POST …/deactivate takes a reasonCode and optional comment, stops future use, and cascades dependent autopay enrollments into review so operations can replace or cancel them. It is idempotent—deactivating an inactive instrument is a no-op. In-flight payments continue under their rail state.
/v1/external-parties/{partyId}/payment-instruments. The routes, permissions, and rules mirror the customer family exactly; a customer instrument cannot be used to fund an unrelated merchant.