Skip to content

feat: add bank account webhook receiver (#487)#503

Open
numdinkushi wants to merge 1 commit into
SafeVault:mainfrom
numdinkushi:feature/487-bank-account-webhook-receiver
Open

feat: add bank account webhook receiver (#487)#503
numdinkushi wants to merge 1 commit into
SafeVault:mainfrom
numdinkushi:feature/487-bank-account-webhook-receiver

Conversation

@numdinkushi
Copy link
Copy Markdown

Summary

Adds a secure webhook receiver so Paystack and Stripe can push bank-connection status updates into VestRoll. The endpoint verifies each provider’s signature, maps webhook events to internal account states (pendingverified / disconnected), and persists changes on the new bank_accounts table.

Approach

  • POST /api/v1/finance/webhooks/bank — reads the raw body for signature verification, resolves the provider from headers or ?provider=, and returns structured success/error responses.
  • Provider verification — Paystack HMAC-SHA512 (x-paystack-signature); Stripe signed payload with replay protection (stripe-signature).
  • Status sync — event → status mapping per provider; updates existing rows by provider_account_id; sets verified_at / disconnected_at when applicable; skips no-op updates.
  • Persistence — Drizzle schema + migration 0001_add_bank_accounts for bank_accounts and related enums.

Type of Change

  • Feature
  • Bug Fix
  • Refactoring
  • Documentation
  • Tests
  • Infrastructure / CI

Linked Issues

Fixes #487

Key Changes

Area Change
API src/app/api/v1/finance/webhooks/bank/route.ts — webhook entrypoint
Service bank-webhook.service.ts — signature check, event parsing, DB updates
Security bank-webhook-signature.utils.ts — Paystack & Stripe verification
Utils bank-webhook.utils.ts — provider resolution, payload parsing, account ID extraction
Config bank-webhook.constants.ts — signature headers, event → status maps, env keys
Database bank_accounts table, enums (bank_account_status, bank_connection_provider), migration 0001_add_bank_accounts
Docs .env.examplePAYSTACK_WEBHOOK_SECRET, STRIPE_WEBHOOK_SECRET
Tests 17 unit/route tests covering happy paths, auth failures, and edge cases

Supported events (high level)

  • Paystack: customeridentification.*, dedicatedaccount.assign.*, transfer.*
  • Stripe: financial_connections.account.*, account.application.deauthorized

Test Plan

  • Run pnpm db:migrate and confirm bank_accounts exists
  • POST a Paystack webhook with valid x-paystack-signature → status updates for a seeded row
  • POST a Stripe webhook with valid stripe-signature → status updates for a seeded row
  • Reject requests with missing or invalid signatures (401)
  • Confirm unknown events / missing accounts return success with statusUpdated: false (no 500)
  • pnpm run test — bank webhook specs pass

Deployment Notes

  • Run database migration after deploy.
  • Set PAYSTACK_WEBHOOK_SECRET and/or STRIPE_WEBHOOK_SECRET in the target environment.
  • Configure provider dashboards to call:
    POST /api/v1/finance/webhooks/bank?provider=paystack (or stripe)

Checklist

  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • My changes generate no new linting/type-checking warnings.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have updated the documentation accordingly.

Screenshots / Recordings

N/A — backend API only.

Introduce Paystack and Stripe webhook handling to update linked bank
account status, with signature verification, schema migration, and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

Someone is attempting to deploy a commit to the vestroll's projects Team on Vercel.

A member of the Team first needs to authorize it.

@codeZe-us
Copy link
Copy Markdown
Contributor

@numdinkushi PR should point to dev branch not main branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Bank Account Webhook Receiver

2 participants