Tích hợp
1. Sister Service
| Sister | Hướng | Bề mặt | Auth | Kịch bản lỗi |
|---|---|---|---|---|
@nx/sale | → (payment dispatch) | HTTP webhook tới POST /v1/api/sale/webhooks/payment | none (Cilium network policy) | Retry theo WebhookConfig.metadata.maxRetries; dispatch lỗi được log |
@nx/sale (initiator) | ← (sale gọi) | HTTP — khởi tạo transaction qua controller @nx/mq-pay | JWT | sale xử lý lỗi |
@nx/identity | → (verify) | HTTP — JWKS tại /jw-certs | none | Cache cục bộ |
@nx/identity (Casbin) | → | HTTP — PolicyDefinitionService | JWT | Cache Redis |
@nx/signal | → | WebSocket emitter | — | best-effort |
2. Hệ thống bên ngoài
| Hệ thống | Hướng | Bề mặt | Auth | Ghi chú |
|---|---|---|---|---|
| VN Pay (QR MMS) | ↔ | HTTPS REST + IPN | Credential mã hóa theo merchant | Nhà cung cấp @nx/mq-pay |
| VN Pay (PhonePOS) | ↔ | HTTPS REST + IPN | Tương tự | |
| VN Pay (SmartPOS) | ↔ (placeholder) | HTTPS REST | Tương tự | Provider đã khai báo, tích hợp đang làm |
| PostgreSQL | ↔ | DB | password từ env | Schema: mq_pay, Configuration chia sẻ + WebhookConfig |
| Redis | ↔ | TCP | password từ env | BullMQ queue + cache |
3. Luồng cross-service quan trọng
3.1 Sale → Payment → Provider → Sale (vòng đời đầy đủ)
3.2 Đăng ký webhook subscriber
3.3 Topology triển khai theo Mode
Mỗi pod WORKER phải có
APP_ENV_NODE_ID(Snowflake worker ID) duy nhất để tránh xung đột id.
4. Chi tiết cầu nối MQ-Pay
@nx/mq-pay không phải là service riêng — nó là package bên thứ ba được tiêu thụ bởi @nx/payment qua MQPayComponent. Vòng đời:
| Bước | Diễn ra |
|---|---|
| Boot | ApplicationPaymentComponent.binding() đọc APP_ENV_MQ_PAY_MODE |
| Configure | Build IMQPayOptions với: mode, credentialGetter, vnpay configs (đã giải mã), eventHandler |
| Register | Gọi application.component(MQPayComponent) |
| Boot MQPayComponent | Xác minh mode; setup Redis/BullMQ; đăng ký TransactionRepository, v.v.; đăng ký có điều kiện controller (FULL/API) và worker (FULL/WORKER) |
| Đặt event handler | AppRegistry.setEventHandler(WebhookEventHandlerHelper) |
| Runtime | Worker emit event → AppRegistry.emit → WebhookEventHandlerHelper.handle |
AppRegistry là một singleton riêng (KHÔNG phải IGNIS DI) quản lý trạng thái xuyên suốt cho MQ-Pay (Redis, BullMQ, providers, event handler).
5. Tính ổn định của hợp đồng
| Bề mặt | Tính ổn định | Versioning |
|---|---|---|
Webhook payload (sự kiện mq-pay:*) | ổn định | chỉ thêm |
REST WebhookConfig (/webhook-configs) | ổn định | tiền tố URL /v1/ |
Bảng Configuration (row payment) | ổn định | namespace code thuộc payment |
| Endpoint MQ-Pay | ổn định | tiền tố URL /v1/ (đường dẫn controller thuộc @nx/mq-pay) |
Topic WebSocket observation/payment/* | ổn định | chỉ thêm |
6. Mối quan tâm xuyên suốt
| Mối quan tâm | Cách xử lý |
|---|---|
| Tin cậy | IPN ký bởi nhà cung cấp (xác minh trong MQ-Pay); webhook đến subscriber ký qua HMAC nếu WebhookConfig.signingMethod được đặt |
| Mã hóa khi lưu | Credential nhà cung cấp mã hóa AES-256-GCM trong Configuration.credential; key từ APP_ENV_APPLICATION_SECRET |
| Mã hóa khi truyền | TLS tại gateway; lưu lượng nội cluster plaintext |
| Điều phối Mode | Pod API + WORKER chia sẻ Redis (BullMQ) và PostgreSQL — phải dùng cùng khóa mã hóa |
| Webhook retry | WebhookDispatcherService theo WebhookConfig.metadata.maxRetries (mặc định 3) với exponential backoff |