Skip to main content

Testing Bank Transfers Locally

PartyBank bank transfers are confirmed by a real PiggyVest Business (PVB) webhook, not by the initiating request — so testing the flow locally means reproducing that webhook, not bypassing it.

How the mock webhook works​

  1. In any non-production environment (NODE_ENV !== 'production'), a real call to POST /partybank/event/:eventId/bank-transfer-details returns a successful mock transfer response and creates the transaction as Pending, exactly like production up to this point.
  2. The service then schedules a real, one-shot Google Cloud Scheduler job targeting POST /partybank/cron/transfer-webhook-simulation, with a 10-second delay — this reproduces the async timing of a genuine webhook rather than completing the transfer inline.
  3. When the job fires, the simulation endpoint validates it actually came from Cloud Scheduler (X-Cloudscheduler-Jobname + User-Agent: Google-Cloud-Scheduler headers), then runs the transaction through the same PartybankService.completeTransfer() used by the real PVB webhook — same balance decrement, same vendor-amount recalculation if applicable.
  4. The scheduler job deletes itself roughly a minute after running.

There is no fully-offline mock — this requires gcloud authenticated against the project and a SERVICE_URL Cloud Scheduler can actually reach (typically an ngrok tunnel in local dev).

Prerequisites​

gcloud auth login
gcloud config set project live-capital
gcloud services enable cloudscheduler.googleapis.com

Required environment variables:

NODE_ENV=development
GOOGLE_CLOUD_PROJECT=live-capital
GOOGLE_CLOUD_LOCATION=europe-west1
SERVICE_URL=https://your-ngrok-url.ngrok.io

Walking through a test transfer​

curl -X POST "https://your-ngrok-url.ngrok.io/v1/partybank/event/123/bank-transfer-details" \
-H "Authorization: Bearer <jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"description": "Test payment",
"accountNumber": "1234567890",
"bankCode": "044",
"recipient": "Test Recipient",
"bankName": "Access Bank",
"vendorId": 456
}'

Watch the logs for the sequence: mock transfer succeeds → scheduler job created → (~10s later) job triggers → simulation endpoint runs completeTransfer() → transaction flips to Completed.

Verify directly if needed:

SELECT reference, transactionStatus, transactionCompletedAt FROM transactions WHERE reference = '<ref>';
SELECT vendorId, amountPaid FROM vendors WHERE id = <vendor-id>; -- if vendorId was passed

Manual completion (no scheduler round-trip)​

PartybankService exposes manuallyCompleteTransfer(reference, walletReference, providerReference?, context?) and manuallyFailTransfer(reference, walletReference, reason, context?) — thin wrappers around the same completeTransfer() core function the real PVB webhook and the mock-webhook path above both use, so behavior (balance updates, vendor recalculation) is identical; it just skips the network round-trip.

There is no CLI or admin-UI entry point for these today — despite an older internal doc describing a yarn manual-transfer command, no such script exists in the repo. Using these methods currently means calling them directly (a one-off script, or the Node REPL against a running instance), not a documented command. If you need this regularly, wiring an admin/tooling-registry endpoint to it (see Admin & Internal Tooling) would be a natural way to expose it safely.

Troubleshooting​

  • "Failed to create scheduler job: Permission denied" — re-run gcloud auth login and confirm the account has roles/cloudscheduler.admin or roles/cloudscheduler.jobRunner.
  • Webhook simulation endpoint returns 401 — the request is missing the X-Cloudscheduler-Jobname / User-Agent: Google-Cloud-Scheduler headers; don't call this endpoint directly except to reproduce that exact header shape.
  • Job runs but transaction stays Pending — check gcloud scheduler jobs describe <job-name> --location=europe-west1 and confirm SERVICE_URL is actually reachable from Google's infrastructure (a stale/expired ngrok tunnel is the most common cause).
  • src/modules/partybank/partybank.controllers.ts — cronTransferWebhookSimulation
  • src/modules/partybank/partybank.service.ts — completeTransfer, manuallyCompleteTransfer, manuallyFailTransfer