You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue aims to address the implementation of Payments Ledger with Paystack Webhook Verification & Double-Entry Reconciliation.
The core objective is to: Turn the half-built Paystack integration into a trustworthy money path — signature-verified webhooks, an append-only double-entry ledger, an explicit payout state machine, and a reconciliation job that proves the platform's books match the provider's.
By completing this feature, we will ensure that the GuildWorkman protocol maintains its high standards for security, usability, and decentralized logic. This issue requires careful attention to the Backend architecture and adherence to the existing project conventions.
When picking up this issue, please ensure you document any new dependencies or architectural decisions made during development.
Component
Backend (Spring Boot / Java 17)
Difficulty
⚫ Very Hard
Current state
The payment path is currently a shell:
controllers/PaymentController.java is entirely commented out — there is no payment endpoint and no webhook receiver at all.
services/implmentations/TransactionServiceImpl.java and TransactionHistoryServiceImpl are empty @Service stubs, despite Transaction, TransactionHistory, and TransactionStatus models existing.
Payment state today therefore depends on the client calling back after a redirect, which is not a source of truth — a dropped callback silently loses a payment.
Money that can be lost by closing a browser tab is the problem this issue closes. Note that this is the fiat leg; the on-chain leg is tracked separately, and the reconciliation model here must leave room for both.
Tasks
Review the existing Spring Boot structure under backend-api/src/main/java
Implement the service and REST endpoints for: Payments Ledger with Paystack Webhook Verification & Double-Entry Reconciliation
Restore PaymentController as a real controller and add a webhook endpoint that verifies the Paystack x-paystack-signature HMAC over the raw request body, rejecting unverified payloads before any parsing
Make webhook handling idempotent by provider event id — Paystack retries, and a retry must never credit twice
Implement an append-only double-entry ledger (balanced debit/credit entries, no destructive updates) as the authoritative record, with Transaction/TransactionHistory derived from it
Model the payout lifecycle as an explicit state machine with documented legal transitions, covering success, failure, reversal, and refund
Implement a scheduled reconciliation job that pulls provider-side state and flags any divergence rather than silently correcting it
Ensure the webhook path is reachable without authentication but is protected by signature verification, and account for it explicitly in config/SecurityConfig.java
Add or adjust JPA entities, repositories, and schema migrations as needed
Write unit and integration tests (Spring Boot Test; MockWebServer for external RPC calls), including forged-signature, replayed-event, and out-of-order-event cases
Add caching for Maven dependencies in CI
Run ./mvnw verify and ./mvnw test to validate build and coverage
Acceptance Criteria
Feature accurately implements the objective: Turn the half-built Paystack integration into a trustworthy money path — signature-verified webhooks, an append-only double-entry ledger, an explicit payout state machine, and a reconciliation job that proves the platform's books match the provider's.
A webhook with a missing or forged signature is rejected and never mutates ledger state
The same provider event delivered twice produces exactly one ledger effect
Every ledger account balances: total debits equal total credits, asserted by test
A payment completes correctly even when the client never returns from the redirect
Illegal state transitions are rejected rather than silently applied
Reconciliation surfaces divergence between platform and provider state as an actionable signal
Any PR that introduces failing tests or compilation errors is automatically blocked
Endpoints/services are covered by tests including failure and concurrency paths
Public API is documented (OpenAPI) and errors follow a consistent response contract
Code is properly reviewed and approved by codeowners
Description
This issue aims to address the implementation of Payments Ledger with Paystack Webhook Verification & Double-Entry Reconciliation.
The core objective is to: Turn the half-built Paystack integration into a trustworthy money path — signature-verified webhooks, an append-only double-entry ledger, an explicit payout state machine, and a reconciliation job that proves the platform's books match the provider's.
By completing this feature, we will ensure that the GuildWorkman protocol maintains its high standards for security, usability, and decentralized logic. This issue requires careful attention to the Backend architecture and adherence to the existing project conventions.
When picking up this issue, please ensure you document any new dependencies or architectural decisions made during development.
Component
Backend (Spring Boot / Java 17)
Difficulty
⚫ Very Hard
Current state
The payment path is currently a shell:
controllers/PaymentController.javais entirely commented out — there is no payment endpoint and no webhook receiver at all.services/implmentations/TransactionServiceImpl.javaandTransactionHistoryServiceImplare empty@Servicestubs, despiteTransaction,TransactionHistory, andTransactionStatusmodels existing.Money that can be lost by closing a browser tab is the problem this issue closes. Note that this is the fiat leg; the on-chain leg is tracked separately, and the reconciliation model here must leave room for both.
Tasks
backend-api/src/main/javaPaymentControlleras a real controller and add a webhook endpoint that verifies the Paystackx-paystack-signatureHMAC over the raw request body, rejecting unverified payloads before any parsingTransaction/TransactionHistoryderived from itconfig/SecurityConfig.java./mvnw verifyand./mvnw testto validate build and coverageAcceptance Criteria
Estimated Time
4-6 days