Partner Implementation Guide for Engineers
Comprehensive Report
This document serves as an in-depth guide for integrating a new partner module into the system, focusing on clarity, best practices, and compliance with existing project architecture.
Recap of FNZ Monorepo Communication Layer
Our FNZ monorepo is structured to separate concerns clearly between:
- Core (common tooling / shared infrastructure)
- Types (shared TypeScript definitions)
- Backend (infrastructure not accessible to contractors)
- Partner Packages (e.g.,
@fnz/partner-xyz
), where external contractors implement custom logic.
We employ a ZeroMQ-based pub/sub approach with a central ZeroMQ broker (in a Docker container) to decouple each partner’s code from the backend. Communication flows through standardized topics (METHOD_REQUEST
, METHOD_REPLY
, etc.). Contractors implement the partner side (listening and replying to requests) while the backend initiates requests or processes replies, all via @fnz/core’s MessengerService.
Package Overview
1. @fnz/core
- Node.js package containing:
- MessengerService (ZeroMQ pub/sub, correlation-based requests, optional exponential retry).
- Other shared backend infrastructure.
- Contractors can import from
@fnz/core
to utilize the messenger logic (subscribe to request topics, publish replies, etc.).
2. @fnz/types
- Node.js package containing TypeScript type definitions used across FNZ.
- Ensures consistent typings for shared models, request/response shapes, etc.
3. @fnz/backend
- Our private backend (NestJS / Node.js), which contractors do not have direct access to.
- The backend uses
@fnz/core
’s MessengerService to send commands to partners and handle replies. - Manages system-level logic (e.g., orchestrating high-level flows, storing data in our DB, etc.).
4. @fnz/partner-xyz
- Your partner package (NestJS or Node.js app) that you, the contractor, develop.
- Imports
@fnz/core
for the MessengerService and@fnz/types
for any shared type definitions. - Responds to commands from the backend, publishes relevant replies, can also initiate commands if your use case demands it.
- Completely decoupled from
@fnz/backend
aside from the message flows through the ZeroMQ broker.
Communication Flow via ZeroMQ
We have a central Docker container running a ZeroMQ forwarder (in Python). This forwarder has two main ports:
- 5555: XSUB (listens for publisher messages)
- 5556: XPUB (allows subscribers to receive messages)
The MessengerService in @fnz/core
is configured with:
- frontendAddress (e.g.,
tcp://broker:5555
) - backendAddress (e.g.,
tcp://broker:5556
)
When @fnz/backend
or @fnz/partner-xyz
want to send a message:
- They publish on
frontendAddress
(port 5555). - The broker forwards it along to all subscribers listening on
backendAddress
(port 5556).
Mermaid Diagram
Below is a high-level diagram illustrating the relationships:

1. Required Packages
You will primarily need the following packages to begin the integration process:
@fnz/core
: Provides essential system functionalities and utilities.@fnz/types
: Includes type definitions for interfaces and data structures.@fnz/partner-***
: Specific partner implementation package to handle partner-specific logic.
2. Setting Up a New Partner Module
Step 1: Clone and Rename
- Navigate to the
@fnz/partner-dummy
directory and duplicate it to create a new partner folder, e.g.,@fnz/partner-abc
. - Inside the new directory, update the
package.json
file:{
"name": "@fnz/partner-abc",
...
}
Step 2: Add to Workspace
Update the root package.json
file by adding your new partner package to the workspaces
array.
Step 3: Implement Contract Methods
Start implementing partner-specific logic in /src/payments.payments.service.ts
and /src/refunds/refunds.service.ts
.
You must implement these contract methods:
-
initialisePayment()
- Prepares the payment process for initialization.
- Sets the payment to
initiated
state.
-
createPayment()
- Creates the payment object and transitions it to either
processing
orsuccess
.
- Creates the payment object and transitions it to either
-
processPaymentWebhook()
- Handles webhook updates for payments received from the partner.
-
createRefund()
- Initiates a partial or complete refund process.
-
processRefundWebhook()
- Handles webhook updates related to refunds.
3. Database Integration
To ensure proper functionality, make the following database updates:
-
Partners Table Add an entry for the new partner in the
partners
table. There should only be one partner entry per agent. -
Payment Methods and Bindings
- Create new payment methods if required, and store them
payment_methods
table. - Insert these rows using a migration script, saved in the
migrations/
folder.
- Create new payment methods if required, and store them
For example:
npx prisma migrate dev --name add-id-payment-methods
4. Testing the Module
Testing ensures the partner module operates as expected. While the service can be plugged into the zeroMQ interface, a HTTP interface is exposed for testing purposes.
Use the HTTP interface for testing.
Step 1: Write Unit Tests
- Use
jest-ts
to write tests in thetests/
directory. - Mock API calls to isolate and validate module logic.
Step 2: Validate Core Flows
Test these critical workflows:
-
Payment Initialization and Creation
- Validate that
initialisePayment
transitions the payment toinitiated
. - Verify that
createPayment
transitions the payment toprocessing
orsuccess
.
- Validate that
-
Refund Creation and Webhook Handling
- Ensure
createRefund
properly initiates a refund. - Confirm
processRefundWebhook
handles webhook updates correctly.
- Ensure
-
Payment Webhook Handling
- Check that
processPaymentWebhook
processes webhook notifications as expected.
- Check that
Step 3: Run Tests
Execute the tests with:
npm run test
6. Worked example: Implementing Partner "Doku"
Scenario
"Doku" supports bank transfers and direct debit.
Steps
-
Understand the Flows Review bank transfer and direct debit flows here.
-
Sequence Diagram Create a diagram outlining the steps for payment and refund handling.
-
Clone and Implement Clone the
@fnz/partner-dummy
directory to@fnz/partner-doku
. Implement the required contract methods (initialisePayment
,createPayment
, etc.) in both the payment and refund services.In the
.env
file, populate the following variables:NODE_ENV=development
DATABASE_URL="postgresql://local:local@localhost:5432/partner-dummy?schema=public"
PORT=8282
MESSENGER_SERVICE_ID=partner_dummy_001
PARTNER_CODE=dummy -
Test the Implementation Write unit tests to validate the following:
- Payment creation and refund flows.
- Webhook handling.
- Partial or full refund processing.
- Payment initialization and completion.
-
Database Updates
- Add Doku to the
partners
table. - Create relevant payment methods and bindings.
- Add Doku to the