Event Flows
The Payments Service publishes payment lifecycle events to a Kinesis stream. Downstream services subscribe to this stream to react to payment status changes without polling the API. The service also consumes events from other services via SQS.
How Events Are Published
The kinesis-feeder Lambda bridges the DynamoDB Streams record for prod-payments to the prod-payments Kinesis stream. Every write to prod-payments that triggers a stream record is a potential event — but only records where the event_type field is non-empty are forwarded.
DynamoDB (prod-payments) │ DynamoDB Streams (new image on every write) ▼ kinesis-feeder (Lambda) │ unmarshal payment record from stream image │ if event_type == "" → skip (no Kinesis write) │ if event_type != "" → build fmsdk.Event │ event.ID = confirmation_id │ event.Type = event_type │ event.Source = "PaymentService" │ event.Data = payment object ▼ prod-payments Kinesis stream │ ├──► subscription-service.achhandler └──► payments-service.blocklist-handler
Most payments are written at submission time with an empty event_type and only trigger a Kinesis event on a subsequent status-update write (e.g. by the webhook processor or check-ach worker). Prenotes are the exception: the prenoter Lambda writes the record with event_type = PRENOTE_SUBMITTED directly at submission, so the submission write itself is forwarded to Kinesis.
|
Kinesis Event Types
These are the event_type values that appear in Kinesis records from this service. They correspond to the event_type field written to prod-payments when a payment’s status changes.
| Event Type | Trigger | Kinesis Consumer(s) |
|---|---|---|
|
A JPM or Usio subscription ACH payment is returned by the bank. Written by |
|
|
A Usio float ACH debit is returned by the bank. Written by |
|
|
A subscription ACH payment clears JPM internal review. Written by |
|
|
A subscription ACH payment is forwarded to the ACH network by JPM. Written by |
|
|
A float ACH debit payment clears. Written by |
|
|
A prenote (zero-dollar ACH) is submitted. Written at submission time. |
None (skipped by consumers) |
The Kinesis stream supports up to 20 consumers. Currently only 2 are registered. See the feeder.go comment for the current consumer list.
|
Event Payload Structure
Each event published to Kinesis is an fmsdk.Event (from github.com/floatme-corp/fmsdk/events) with the following structure:
{
"id": "<confirmation_id>", // payment's confirmation_id
"type": "<event_type>", // e.g. "SUBSCRIPTION_RETURNED"
"source": "PaymentService",
"version": "V2",
"data": {
// Payment object (same shape as GET /payments/{confirmation_id} response)
"confirmation_id": "...",
"user_id": "...",
"status": "FAILED",
"return_code": "R02",
"payment_method": "ach",
"payment_type": "debit",
"payment_provider":"usio",
"amount": 15.99,
"submit_date": "2025-01-15T20:00:00Z",
...
}
}
The data field is the full payment record serialized from api.Payment. Consumers can inspect data.return_code to determine the reason for a return.
DynamoDB Streams
Only prod-payments has a DynamoDB Stream enabled. The kinesis-feeder Lambda is the sole consumer of this stream.
| Table | Stream | Consumer |
|---|---|---|
|
New image on every write |
|
All other DynamoDB tables in this service do not have streams enabled.
Events Consumed from Other Services
The Payments Service consumes events published by other FloatMe services via SQS queues.
| Queue | Published By | Consumer Lambda |
|---|---|---|
Purpose |
|
External callers (typically float-service or subscription-service) |
|
Triggers a zero-dollar prenote submission to JPM or Usio for bank account validation. |
|
Other FloatMe services (bank account update flow) |
|
Removes a user from the ACH blocklist when they update their bank account. |
|
|
|
Related Pages
-
Payment Flow — When
event_typeis set and what triggers a Kinesis publish -
Payment Syncing — How
jpm-webhook-processorandcheck-ach-workerset theevent_typethat drives these events -
Blocklist — How
blocklist-handlerconsumesSUBSCRIPTION_RETURNEDandFLOAT_DEBIT_RETURNEDevents -
Infrastructure — SQS queue names, visibility timeouts, and Kinesis stream details