Blocklist
The blocklist prevents future payment processing for users whose ACH payments were returned with codes indicating a structural account problem (closed, frozen, or invalid). It is separate from fraud — a blocked user’s account simply cannot receive or send ACH payments until they provide a new bank account.
How the Blocklist Works
Two Lambdas manage the blocklist:
-
blocklist-handler— Consumes payment events from theprod-paymentsKinesis stream and auto-blocks users on specific return codes. -
blocklist-remover— Consumes SQS events and removes a user’s block when they update their bank account.
The blocklist-handler writes BLOCKED records to DynamoDB when a structural return code is received. The blocklist-remover writes NOTBLOCKED records when a user updates their bank account. A user’s current blocklist state is determined by the most recent record for their user_id.
Auto-Blocking Flow
The blocklist-handler Lambda receives all payment events from the prod-payments Kinesis stream. It acts only on SUBSCRIPTION_RETURNED and FLOAT_DEBIT_RETURNED event types, ignoring all others.
prod-payments Kinesis Stream │ event types: SUBSCRIPTION_RETURNED, FLOAT_DEBIT_RETURNED ▼ blocklist-handler (Lambda) │ decode payment event │ check return_code │ ├─ R02 / R03 / R04 / R16 ──► write BLOCKED record to blocklist DynamoDB │ AC04 / BE01 / AC01 / AC06 │ └─ all other codes ──► discard (no DynamoDB write)
Only SUBSCRIPTION_RETURNED and FLOAT_DEBIT_RETURNED events are processed. Other event types (e.g. FLOAT_CREDIT_*) are silently ignored.
Unblocking Flow
When a user updates their bank account, the caller publishes an event to the prod-payments-service-blocklist-remove SQS queue. The blocklist-remover Lambda processes this event and writes a NOTBLOCKED record for the user.
Caller (other FloatMe service) │ publish bank account updated event ▼ SQS (blocklist-remove queue) │ ▼ blocklist-remover (Lambda) │ parse user_id + account_id from event │ write NOTBLOCKED record ▼ Blocklist DynamoDB
The account_id (Plaid account ID) is stored as the trigger_id on the unblock record for audit purposes.
Return Code Reference
| Code | Provider | Meaning | Blocklist Action |
|---|---|---|---|
|
Usio (NACHA) |
Account closed |
|
|
Usio (NACHA) |
No account / unable to locate account |
|
|
Usio (NACHA) |
Invalid account number structure |
|
|
Usio (NACHA) |
Account frozen |
|
|
JPM |
Account closed (maps to R02) |
|
|
JPM |
No account / unable to locate account (maps to R03) |
|
|
JPM |
Invalid account number structure (maps to R04) |
|
|
JPM |
Account frozen (maps to R16) |
|
All other codes |
Any |
e.g. R01 (NSF), R09 (insufficient funds) |
Discarded — no DynamoDB write; user remains unblocked |
Only SUBSCRIPTION_RETURNED and FLOAT_DEBIT_RETURNED event types are evaluated for blocklisting. Returns on other payment types (e.g. float credits) do not trigger this logic.
|
API Endpoints
The blocklist status and history for a user are available via the REST API:
-
GET /{user_id}/payments/blocklists— current blocklist status -
GET /{user_id}/payments/blocklists/history— full blocklist history -
POST /{user_id}/payments/blocklist— manually add a user to the blocklist -
DELETE /{user_id}/payments/blocklist— manually remove a user from the blocklist
See API Specification for request/response schemas.
Related Pages
-
Payment Syncing — How payment return events flow from processors into the Kinesis stream
-
Event Flows — Kinesis event types published by the payments service
-
JPM Integration — JPM return code mappings (AC04, BE01, AC01, AC06)
-
Usio Integration — Usio NACHA return codes and return rate thresholds
-
Prenotes — Prenote returns can also carry blocklist-triggering codes