Internal payments tracking dashboard
Find a file
Adam Moussa 3583e2fc11 Add payroll notification Lambda for Gusto payroll via Dataddo
Queries Aurora for new payroll runs and contractor payments, sends
formatted Slack message with gross pay breakdown and total bank
withdrawal amount. Runs weekdays at 2pm ET, tracks notified payrolls
in DynamoDB to avoid duplicates.
2026-04-24 16:39:50 -04:00
scripts Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
src Add payroll notification Lambda for Gusto payroll via Dataddo 2026-04-24 16:39:50 -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 payroll notification Lambda for Gusto payroll via Dataddo 2026-04-24 16:39:50 -04:00
package.json Add payroll notification Lambda for Gusto payroll via Dataddo 2026-04-24 16:39:50 -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 Add payroll notification Lambda for Gusto payroll via Dataddo 2026-04-24 16:39:50 -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.