Internal payments tracking dashboard
Find a file
Adam Moussa fe7c9cebca Replace Dataddo/Aurora payroll pipeline with email-triggered notifications
SES receives Gusto payroll emails at payroll@int.seahaven.com, stores
to S3, Lambda parses and posts a combined Slack notification (employee
payroll + contractor payments in one message) after a 10-minute SQS
batching window.

Removes Aurora Serverless, notifyPayroll Lambda, and @aws-sdk/client-rds-data.
Adds mailparser, SQS delay queue, and processPayrollEmail Lambda.
2026-04-30 14:04:48 -04:00
.claude Add .claude configuration directory 2026-04-27 19:14:54 -04:00
scripts Log BoA submissions to DDB and surface in Slack App Home 2026-04-20 17:40:55 -04:00
src Replace Dataddo/Aurora payroll pipeline with email-triggered notifications 2026-04-30 14:04:48 -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 Replace Dataddo/Aurora payroll pipeline with email-triggered notifications 2026-04-30 14:04:48 -04:00
package.json Replace Dataddo/Aurora payroll pipeline with email-triggered notifications 2026-04-30 14:04:48 -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 Replace Dataddo/Aurora payroll pipeline with email-triggered notifications 2026-04-30 14:04:48 -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.