Skip to content

Payment Service

@nx/payment is a thin orchestration layer that wires @nx/mq-pay (the multi-provider payment engine) into the BANA platform. It owns:

  1. Per-merchant payment provider credentials (encrypted in Configuration table).
  2. WebhookConfig registry — outbound HTTP webhooks fired when MQ-Pay state changes.
  3. The event-handler bridge that translates MQ-Pay events to webhook calls + WebSocket broadcasts.

It supports mode-based deployment via APP_ENV_MQ_PAY_MODE: FULL (single instance), API (REST + queue producer only), WORKER (queue consumer only).

1. Quick Reference

PropertyValue
Package@nx/payment
CodeSVC-00040-PAYMENT
TypeMicroservice (orchestration bridge)
RuntimeBun
Base ClassVerifierApplication
Locationpackages/payment
Base Path/v1/api/payment
Dev Port31040
Container Port3000 (external 31040)
Snowflake ID (FULL)4
Snowflake ID (API)8 (production split)
Snowflake IDs (WORKER)91, 92, … (one per worker pod)
DB Schemashared Configuration + WebhookConfig
Binding Namespace@nx/payment

2. Purpose & Scope

IncludedExcluded
Wire @nx/mq-pay providers (VNPAY QR MMS / PhonePOS / SmartPOS, SYSTEM)Direct provider integration code (lives in @nx/mq-pay)
Per-merchant credential management (AES-256-GCM encrypted)Multi-currency conversion
WebhookConfig CRUD (subscribers register their endpoints)Payment UX / checkout flow (sale's job)
Event-handler bridge: MQ-Pay events → WebhookDispatcher + WebSocketToken vault / card storage
Mode-based deployment for horizontal scalingCross-merchant settlement reconciliation
Real-time transaction/attempt WebSocket broadcasts

3. Tech Stack

External:

LibraryPurpose
@venizia/ignisIoC + DI
@venizia/ignis-helpersLogger, Redis helper
hono + @hono/zod-openapiHTTP + OpenAPI
@scalar/hono-api-referenceScalar viewer at /doc
drizzle-orm + pgDB
ioredisRedis

Internal:

PackagePurpose
@nx/coreSchemas, repositories, VerifierApplication, CryptoUtility, WebhookDispatcherService, MailComponent reuse
@nx/mq-payMulti-provider payment engine — auto-registered via MQPayComponent

4. Project Structure

packages/payment/
├── src/
│   ├── application.ts                    # VerifierApplication subclass
│   ├── index.ts                          # bootstrapApplication()
│   ├── migrate.ts                        # bootstrapMigration()
│   ├── common/
│   │   ├── keys.ts                       # BindingKeys (BASE = '@nx/payment')
│   │   ├── rest-paths.ts                 # 1 path: WEBHOOK_CONFIGS
│   │   ├── websocket.ts                  # PaymentWebSocketTopics + Rooms
│   │   └── types.ts
│   ├── components/
│   │   ├── payment.component.ts          # ApplicationPaymentComponent — MQ-Pay wiring
│   │   ├── websocket.component.ts        # ApplicationWebSocketComponent
│   │   └── index.ts
│   ├── controllers/
│   │   ├── webhook-config/               # WebhookConfigController + definitions
│   │   ├── permissions.ts                # PaymentPermissions aggregate
│   │   └── index.ts
│   ├── helpers/
│   │   └── webhook-event-handler/        # WebhookEventHandlerHelper (the bridge)
│   ├── services/
│   │   ├── payment-configuration.service.ts   # Encrypted provider creds load
│   │   ├── payment-socket-event.service.ts    # WS broadcast for transactions/attempts
│   │   └── index.ts
│   ├── datasources/                      # PostgresCoreDataSource
│   └── migrations/processes/             # 3 seeds (VNPAY QR, VNPAY PhonePOS, permissions)
├── package.json
└── tsconfig.json

5. Architecture

Detail: see Architecture.

6. Domain Snapshot

Full ERD + per-entity tables: see Domain Model.

7. Surface Summary

REST controllers — full reference rendered live from /v1/api/payment/doc/openapi.json (live spec — Scalar viewer at /doc, gateway portal):

ControllerBase pathNotes
WebhookConfigController/webhook-configsmerchant-scoped CRUD
(from @nx/mq-pay — conditional on mode FULL/API)various5 controllers: Transaction, TransactionItem, PaymentAttempt, PaymentResult, PaymentOperation

Async surface — full reference in API Events:

DirectionChannelNotes
InboundHTTP IPN (provider → MQ-Pay)VN Pay IPN endpoints (in @nx/mq-pay)
OutboundHTTP webhook (per WebhookConfig)Subscribers like sale receive event payloads
OutboundWebSocketTransaction + Attempt updates fanout to merchant rooms
InternalBullMQscheduler / confirmation queues (via MQ-Pay)

8. Components

ComponentFilePurpose
ApplicationPaymentComponentsrc/components/payment.component.tsMain wiring — registers repos/services/controllers, conditionally loads MQ-Pay when RUN_MODE=startup; binds VNPAY configs + WebhookEventHandlerHelper
ApplicationWebSocketComponentsrc/components/websocket.component.tsRedis-backed emitter for transaction/attempt updates

9. Services

ServiceFileOne-liner
PaymentConfigurationServiceservices/payment-configuration.service.tsLoad encrypted provider configs/credentials from Configuration table; AES-256-GCM decrypt
PaymentSocketEventServiceservices/payment-socket-event.service.tsBroadcast transaction/attempt events to merchant + transaction rooms

All other "payment services" (PaymentExecutionService, PaymentCancellationService, PaymentConfirmationService, PaymentRefundService, PaymentVerificationService, QueueProcessorService) live in @nx/mq-pay and are auto-registered by its component.

10. Helpers

HelperFilePurpose
WebhookEventHandlerHelperhelpers/webhook-event-handler/helper.tsThe bridge: implements IPaymentEventHandler. On MQ-Pay event, queries subscribed WebhookConfig rows, calls WebhookDispatcherService, fires WebSocket broadcast.

11. Repositories

RepositorySourceNotes
ConfigurationRepository@nx/corePer-merchant payment provider credentials (encrypted)
WebhookConfigRepository@nx/coreWebhook subscribers
MigrationRepository@nx/coreMigration state
(from @nx/mq-pay — auto)variousTransactionRepository, TransactionItemRepository, PaymentAttemptRepository, PaymentResultRepository
PermissionRepository@nx/corePermission catalogue (used at boot for seeds)

12. Entry Points

FilePurpose
src/index.tsService entry → bootstrapApplication()
src/migrate.tsMigration entry → bootstrapMigration()
src/application.tsApplication extends VerifierApplication

13. Configuration

Env vars + seeded data: see Configuration.

14. Operations

Deployment + observability + security + runbook: see Operations.

Concepts — why/how:

Reference — lookup:

  • API Events — webhooks + WebSocket
  • Configuration
  • Operations
  • REST endpoints — live OpenAPI at /v1/api/payment/doc/openapi.json (live spec — Scalar viewer at /doc, gateway portal)

Features — deep dives:

Decisions:

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.