Internal payments tracking dashboard
Find a file
Adam Moussa b242df15b5 Log BoA submissions to DDB and surface in Slack App Home
Capture response headers, body, and transactionId on every check-issue
API call; persist as boa_txn#<ts>#<action> records with 90-day TTL.
Add "Recent BoA Submissions" section to App Home showing the last 10
with click-to-copy transactionId.

Motivation: BoA support asked for a transactionId from a past
successful call and we had no way to recover it from CloudWatch
summary logs alone.

Also adds simulate-csv.cjs (dry-run preview) and stampli-uploader.sh
(launchd-invoked S3 uploader), and gitignores debug artifacts.
2026-04-20 17:40:55 -04:00
scripts Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
src Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
.gitignore Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
package-lock.json Add VPC/NAT for static IP, dedup payments by check number, SSM token 2026-04-09 14:27:34 -04:00
package.json Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
README.md Update integration code with correct BoA CashPro API specs and add README 2026-04-13 16:24:20 -04:00
template.yaml Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00

Payments Dashboard

AWS SAM application that ingests payment CSVs, syncs check data with Bank of America CashPro APIs, and surfaces an outstanding-payments dashboard in Slack.

Architecture

  • ProcessPaymentCsv - Lambda triggered by S3 CSV upload. Parses payments, upserts to DynamoDB, and submits new/cancelled checks to the CashPro Check Management API.
  • FetchBoaTransactions - Scheduled Lambda (weekdays 9am ET). Calls the CashPro Previous Day Transaction Inquiry API and matches cleared/returned checks back to DynamoDB records.
  • SlackAppHome - Lambda behind API Gateway. Renders the payments dashboard on the Slack App Home tab with outstanding aging buckets and drill-down modals.

All three Lambdas run inside a VPC with a NAT Gateway for a static outbound IP (required by BoA IP whitelisting).

BoA CashPro API Integration

Two separate CashPro APIs are used, each with its own OAuth credentials:

API Purpose Endpoint
Check Management Issue and cancel checks /cashpro/checkmanagement/v1/check-issues
Reporting (Transaction Inquiry) Fetch previous-day transactions /cashpro/reporting/v1/transaction-inquiries/previous-day

Authentication flow:

  1. POST to /authn/v1/client-authentication with applicationID, client_id, and client_secret
  2. Receive a Bearer access_token (valid 1 hour)
  3. Pass the token in the Authorization header for subsequent API calls

Base URLs:

  • Production: https://api.bofa.com
  • Sandbox: https://api-sb.bofa.com

SSM Parameters

All BoA credentials and config are stored in AWS SSM Parameter Store (SecureString):

Parameter Description
/payments-dashboard/boa-check-mgmt-app-id Check Management application ID
/payments-dashboard/boa-check-mgmt-client-id Check Management client ID
/payments-dashboard/boa-check-mgmt-token Check Management client secret
/payments-dashboard/boa-reporting-app-id Reporting application ID
/payments-dashboard/boa-account-info-client-id Reporting client ID
/payments-dashboard/boa-account-info-token Reporting client secret
/payments-dashboard/boa-account-number BoA account number
/payments-dashboard/boa-company-id CashPro company ID (check management)
/payments-dashboard/boa-bank-id BoA routing number
/payments-dashboard/slack-bot-token Slack Bot OAuth token

Scripts

Script Purpose
scripts/test-boa-sandbox.js One-off sandbox connectivity test for both CashPro APIs
scripts/seed-from-csv.js Seed DynamoDB from a local CSV file
scripts/seed-bank-status.js Seed bank clear status data into DynamoDB

Deployment

sam build
sam deploy --guided

The BOA_BASE_URL environment variable in template.yaml controls whether Lambdas hit production (https://api.bofa.com) or sandbox (https://api-sb.bofa.com). All other BoA config is read from SSM at runtime.