Architecture

System Context

The Payments Service runs as 16 AWS Lambda functions. It exposes a REST API behind API Gateway and participates in the broader FloatMe platform as both an event producer (Kinesis) and consumer (DynamoDB Streams, SQS, EventBridge).

Payment Service

system context payment service

Payment Syncing

The payment syncing subsystem reconciles ACH payment statuses after initial submission through three independent mechanisms: JPM webhook callbacks, daily ACH status polling, and Usio transaction syncing.

system context payment syncing

Inbound Traffic

Source Description

prod-payments-service-api (API Gateway)

IAM-authenticated requests from internal FloatMe services. All callers sign requests with AWS Signature V4.

webhooks.floatme.io (API Gateway)

Webhook callbacks from JPM for payment status changes. Handled by the jpm-webhook-handler Lambda.

prod-payments-service-jpm-webhooks (SQS)

Work queue for JPM webhook events. Consumed by jpm-webhook-processor.

prod-payments-service-check-ach (SQS)

Daily ACH status polling jobs enqueued by check-ach-scheduler. Consumed by check-ach-worker.

prod-payments-service-usio-sync (SQS)

Usio transaction sync jobs. Consumed by usio-syncer.

prod-payments-service-usio-refresh (SQS)

Usio token refresh jobs. Consumed by usio-refresh-worker.

prod-payments-service-prenotes (SQS)

Prenote submission jobs. Consumed by prenoter.

prod-payments-service-blocklist-remove (SQS)

Blocklist removal events triggered when a user updates their bank account. Consumed by blocklist-remover.

prod-payments-service-debit-fixer (SQS)

One-off debit card repair jobs. Consumed by debit-card-fixer.

prod-payments DynamoDB Streams

Change events from the payments table. Consumed by kinesis-feeder to publish Kinesis events.

prod-payments (Kinesis)

Payment lifecycle events consumed by blocklist-handler to auto-blocklist users on specific return codes.

EventBridge (schedule)

CloudWatch rules trigger check-ach-scheduler (daily 15:30 UTC), usio-scheduler (every 30 min), usio-refresh-scheduler (daily 15:00 UTC), jpm-syncer (daily 13:00 UTC), and balance-reporter (daily 13:00 UTC + hourly).

Outbound Traffic

Destination Description

JPM (mTLS + JWS)

ACH payment submission, prenote submission, and ACH status polling from check-ach-worker. All requests use mTLS authentication and JWS-signed bodies.

Usio

Pinless debit/credit token charges, ACH payment submission, and transaction data syncing.

prod-payments (Kinesis)

Payment lifecycle events published by kinesis-feeder after transforming DynamoDB stream records. Consumed by float-service, subscription-service, and blocklist-handler.

Plaid

Bank account and routing number retrieval for ACH setup.

Slack

Daily and hourly Usio merchant account balance reports sent by balance-reporter.

Lambda Functions

Function Trigger Responsibility

api

API Gateway (IAM)

Primary REST API. Handles payment submission, debit card management, bank account operations, refunds, prenote requests, fraud checks, and blocklist management. See API Specification.

jpm-webhook-handler

API Gateway (webhooks.floatme.io)

Receives JPM payment status webhook callbacks. Validates the request and enqueues the event to SQS for async processing.

jpm-webhook-processor

SQS (jpm-webhooks)

Dequeues JPM webhook events and updates the corresponding payment record status in DynamoDB.

check-ach-scheduler

EventBridge (daily, 15:30 UTC)

Queries DynamoDB for payments in ACHSENT status and enqueues them to the check-ach queue for status polling.

check-ach-worker

SQS (check-ach)

Polls JPM and Usio APIs for the current status of an ACH payment. Marks cleared or returned payments and triggers downstream status updates.

usio-scheduler

EventBridge (every 30 min, prod only)

Enqueues Usio transaction sync jobs by date range and merchant account to the usio-sync queue.

usio-syncer

SQS (usio-sync)

Fetches transactions from the Usio API for a given date range and merchant account. Stores results in DynamoDB.

usio-refresh-scheduler

EventBridge (daily, 15:00 UTC)

Queries DynamoDB for debit cards that need Usio token refreshes and enqueues refresh jobs.

usio-refresh-worker

SQS (usio-refresh)

Refreshes Usio pinless debit/credit tokens and updates both the new prod-payments single table and the legacy pinless-default-card table.

prenoter

SQS (prenotes)

Submits ACH prenotes to JPM or Usio in batch. See Prenotes.

kinesis-feeder

DynamoDB Streams (prod-payments)

Transforms DynamoDB stream change records from the payments table into structured Kinesis events on the prod-payments stream.

blocklist-handler

Kinesis (prod-payments)

Consumes payment events from the Kinesis stream. On specific ACH return codes (R02, R03, R04, R16 and JPM equivalents), auto-blocklists the user. See Blocklist.

blocklist-remover

SQS (blocklist-remove)

Removes a user from the blocklist when they update their bank account.

jpm-syncer

EventBridge (daily, 13:00 UTC)

Syncs JPM transaction data to DynamoDB.

balance-reporter

EventBridge (daily 13:00 UTC + hourly, prod only)

Reports Usio merchant account balances to Slack.

debit-card-fixer

SQS (debit-fixer)

Repairs debit card records in bulk. Triggered manually by enqueuing jobs via scripts/debit-fixer.

Data Storage

DynamoDB

Storage spans two regions. The prod-payments single table lives in the primary region and holds payment records, v2 debit card records, and v2 bank account records. The named legacy tables — pinless-default-card (legacy debit card tokens), bank-accounts (KMS-encrypted ACH credentials), bank-account-history (bank account change log), and usio-debit-refunds (refund records) — live in us-east-1. Debit card and bank account writes currently target both the single table and the legacy tables as part of an ongoing migration.

See DynamoDB Tables for the full schema, key structure, and access pattern reference.

Event Flow

The kinesis-feeder Lambda transforms DynamoDB stream change records from prod-payments into structured events on the prod-payments Kinesis stream. Downstream consumers (float-service, subscription-service, blocklist-handler) react to payment status changes without polling.

See Event Flows for the full publish/consume topology, event types, and payload structure. See Payment Syncing for the ACH polling and JPM webhook flows that drive those status changes.

External Service Integrations

Service Integration

JPM (JP Morgan Chase)

ACH payment processor for subscription payments. The API Lambda submits payments, check-ach-worker polls for status, and the jpm-webhook-handler/jpm-webhook-processor pair processes status callback webhooks. See JPM Integration.

Usio

Pinless debit/credit and ACH processor for float and subscription payments. The API Lambda submits payments; usio-syncer pulls transaction data; usio-refresh-worker keeps tokens fresh. See Usio Integration.

Plaid

Bank account and routing number retrieval. Invoked during the bank account setup flow.

AWS KMS

Bank account and routing numbers are KMS-encrypted before storage. Decrypted at payment submission time.

AWS Secrets Manager

JPM mTLS certificates and Usio API credentials are stored in Secrets Manager and loaded once per Lambda cold start.

User Service

User profile data queried during payment and fraud check flows.

GrowthBook

Feature flags controlling payment routing behavior. Fetched at Lambda startup.