Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
224 lines
19 KiB
Markdown
224 lines
19 KiB
Markdown
# Kiểm Tra Bảo Mật Module Thanh Toán GoodGo Platform - Danh Sách File
|
|
|
|
## Tổng Quan
|
|
Danh sách file toàn diện cho đợt kiểm tra bảo mật các thực thể Order & Escrow trong module thanh toán.
|
|
Vị trí: `/Users/velikho/Desktop/WORKING/goodgo-platform-ai/apps/api/src/modules/payments/`
|
|
|
|
---
|
|
|
|
## 1. TẦNG DOMAIN - CÁC THỰC THỂ
|
|
|
|
### Các Thực Thể Cốt Lõi
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `domain/entities/order.entity.ts` | **THỰC THỂ ORDER** - Quản lý vòng đời đơn hàng với máy trạng thái (CREATED→PAYMENT_PENDING→PAYMENT_CONFIRMED→ESCROW_HELD→SHIPPED→DELIVERED→ESCROW_RELEASED→COMPLETED). Xác thực các chuyển trạng thái. Phát sự kiện: OrderCreatedEvent, OrderPaidEvent, OrderCancelledEvent. Các trường quan trọng: buyerId, sellerId, listingId, amount (Money VO), platformFee, sellerPayout. |
|
|
| `domain/entities/escrow.entity.ts` | **THỰC THỂ ESCROW** - Quản lý vòng đời escrow (PENDING→HELD→RELEASED/DISPUTED/REFUNDED). Lưu trữ số tiền escrow, phí và netPayout đã tính. Phát: EscrowHeldEvent, EscrowReleasedEvent, EscrowDisputedEvent. Xác thực chuyển trạng thái. |
|
|
| `domain/entities/payment.entity.ts` | **THỰC THỂ PAYMENT** - Quản lý giao dịch thanh toán (PENDING→PROCESSING→COMPLETED/FAILED/REFUNDED). Lưu trữ userId, provider (VNPAY/MOMO/ZALOPAY), type, amount, callbackData, idempotencyKey. Phát: PaymentCreatedEvent, PaymentCompletedEvent, PaymentFailedEvent, PaymentRefundedEvent. |
|
|
|
|
### Các Value Object
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `domain/value-objects/money.vo.ts` | **VALUE OBJECT MONEY** - Bọc các số tiền dưới dạng bigint theo VND. Xác thực: amount > 0, giới hạn tối đa 999_999_999_999. Dùng cho tất cả các số tiền tài chính. |
|
|
| `domain/value-objects/platform-fee.vo.ts` | **VALUE OBJECT PHÍ NỀN TẢNG** - Tính phí nền tảng 5%. Các phương thức: `fromOrderAmount()` (tự động tính 5%), `create()` (số tiền tường minh). Xác thực fee >= 0. |
|
|
|
|
---
|
|
|
|
## 2. TẦNG DOMAIN - REPOSITORY (Giao Diện)
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `domain/repositories/order.repository.ts` | **GIAO DIỆN ORDER REPOSITORY** - Định nghĩa các phương thức CRUD + truy vấn: findById, findByIdempotencyKey, findByBuyerId, findBySellerId, save, update. Bảo vệ idempotency. |
|
|
| `domain/repositories/escrow.repository.ts` | **GIAO DIỆN ESCROW REPOSITORY** - Định nghĩa: findById, findByOrderId, save, update. Quan hệ một escrow trên một order. |
|
|
| `domain/repositories/payment.repository.ts` | **GIAO DIỆN PAYMENT REPOSITORY** - Định nghĩa: findById, findByProviderTxId, findByIdempotencyKey, findByUserId, save, update, **updateIfStatus** (cập nhật có điều kiện nguyên tử để xử lý race condition). |
|
|
|
|
---
|
|
|
|
## 3. TẦNG DOMAIN - SỰ KIỆN
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `domain/events/order-created.event.ts` | Phát khi tạo order - chứa orderId, buyerId, sellerId, listingId, amount |
|
|
| `domain/events/order-paid.event.ts` | Phát khi thanh toán được xác nhận - chứa orderId, buyerId, amount |
|
|
| `domain/events/order-cancelled.event.ts` | Phát khi order bị hủy - chứa orderId, buyerId, sellerId |
|
|
| `domain/events/escrow-held.event.ts` | Phát khi escrow được giữ - chứa escrowId, orderId, amount |
|
|
| `domain/events/escrow-released.event.ts` | Phát khi escrow được giải phóng - chứa escrowId, orderId, netPayout |
|
|
| `domain/events/escrow-disputed.event.ts` | Phát khi escrow bị tranh chấp - chứa escrowId, orderId, reason |
|
|
| `domain/events/payment-created.event.ts` | Phát khi tạo thanh toán - chứa paymentId, userId, provider, amount |
|
|
| `domain/events/payment-completed.event.ts` | Phát khi thanh toán hoàn tất - chứa paymentId, userId, provider |
|
|
| `domain/events/payment-failed.event.ts` | Phát khi thanh toán thất bại - chứa paymentId, userId, provider |
|
|
| `domain/events/payment-refunded.event.ts` | Phát khi thanh toán được hoàn tiền - chứa paymentId, userId, provider, amount |
|
|
|
|
---
|
|
|
|
## 4. TẦNG CƠ SỞ HẠ TẦNG - REPOSITORY (Triển Khai)
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/repositories/prisma-order.repository.ts` | **TRIỂN KHAI ORDER REPOSITORY** - Triển khai Prisma ORM. Lưu trữ: id, buyerId, sellerId, listingId, status, amountVND, platformFeeVND, sellerPayoutVND, idempotencyKey, metadata. Xử lý lưu trữ order. |
|
|
| `infrastructure/repositories/prisma-escrow.repository.ts` | **TRIỂN KHAI ESCROW REPOSITORY** - Triển khai Prisma ORM. Lưu trữ: id, orderId, amountVND, feeVND, status, heldAt, releasedAt, disputeReason, disputedAt. Xử lý lưu trữ escrow. |
|
|
| `infrastructure/repositories/prisma-payment.repository.ts` | **TRIỂN KHAI PAYMENT REPOSITORY** - Prisma ORM. Lưu trữ: id, userId, transactionId, provider, type, amountVND, status, providerTxId, callbackData, idempotencyKey. **QUAN TRỌNG: `updateIfStatus()` sử dụng mệnh đề WHERE có điều kiện để ngăn race condition nguyên tử** (Dòng 84-109). |
|
|
|
|
---
|
|
|
|
## 5. TẦNG CƠ SỞ HẠ TẦNG - DỊCH VỤ CỔNG THANH TOÁN
|
|
|
|
### Giao Diện Cổng Thanh Toán
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/services/payment-gateway.interface.ts` | **GIAO DIỆN GATEWAY** - Định nghĩa hợp đồng IPaymentGateway: createPaymentUrl(), verifyCallback(), refund(). CallbackVerifyResult bao gồm: isValid, orderId, providerTxId, isSuccess, rawData. Nhạy cảm về bảo mật. |
|
|
|
|
### Dịch Vụ VNPay
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/services/vnpay.service.ts` | **CỔNG THANH TOÁN VNPAY** - Triển khai IPaymentGateway. **XÁC MINH CALLBACK (Dòng 72-105)**: Trích xuất secure hash, loại bỏ khỏi dữ liệu, sắp xếp các tham số, tạo HMAC-SHA512, dùng crypto.timingSafeEqual() để so sánh thời gian cố định. Số tiền nhân 100 cho VND cents. Trả về isValid, orderId (vnp_TxnRef), providerTxId (vnp_TransactionNo), isSuccess (responseCode === '00'). Hỗ trợ hoàn tiền. |
|
|
|
|
### Dịch Vụ MoMo
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/services/momo.service.ts` | **CỔNG THANH TOÁN MOMO** - Triển khai IPaymentGateway. **XÁC MINH CALLBACK (Dòng 102-147)**: Trích xuất chữ ký từ dữ liệu, xây dựng lại chữ ký thô với accessKey, amount, extraData, IPN/redirect URLs, orderId, v.v. Dùng HMAC-SHA256, so sánh thời gian cố định qua crypto.timingSafeEqual(). Kiểm tra thành công: resultCode === '0'. Hỗ trợ hoàn tiền. Amount dưới dạng Number (không phải bigint trong API). |
|
|
|
|
### Dịch Vụ ZaloPay
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/services/zalopay.service.ts` | **CỔNG THANH TOÁN ZALOPAY** - Triển khai IPaymentGateway. **XÁC MINH CALLBACK (Dòng 98-144)**: Dữ liệu được truyền dưới dạng chuỗi JSON trong trường 'data'. MAC được xác minh qua HMAC-SHA256 với key2. Phân tích dữ liệu JSON để trích xuất app_trans_id và zp_trans_id. **LƯU Ý BẢO MẬT**: Xử lý lỗi phân tích JSON một cách duyên dáng. Dùng so sánh thời gian cố định. Hỗ trợ hoàn tiền (key1). |
|
|
|
|
### Factory Cổng Thanh Toán
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `infrastructure/services/payment-gateway.factory.ts` | **GATEWAY FACTORY** - Trả về instance gateway phù hợp (VNPay/MoMo/ZaloPay) dựa trên enum provider. |
|
|
|
|
---
|
|
|
|
## 6. TẦNG ỨNG DỤNG - COMMAND
|
|
|
|
### Các Order Command
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `application/commands/create-order/create-order.command.ts` | **CREATE ORDER COMMAND** - Đầu vào: buyerId, sellerId, listingId, amountVND, idempotencyKey. Đối tượng payload. |
|
|
| `application/commands/create-order/create-order.handler.ts` | **CREATE ORDER HANDLER** - Kiểm tra idempotency qua findByIdempotencyKey. Xác thực amount (Money VO). Tính phí nền tảng (5%) và seller payout. Tạo OrderEntity + EscrowEntity (trạng thái PENDING). Lưu cả hai. Phát sự kiện. |
|
|
| `application/commands/cancel-order/cancel-order.command.ts` | **CANCEL ORDER COMMAND** - Đầu vào: orderId, userId, reason. |
|
|
| `application/commands/cancel-order/cancel-order.handler.ts` | **CANCEL ORDER HANDLER** - Xác minh người dùng sở hữu order, xác thực chuyển trạng thái qua entity.markCancelled(), lưu, phát sự kiện. |
|
|
|
|
### Các Escrow Command
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `application/commands/hold-escrow/hold-escrow.command.ts` | **HOLD ESCROW COMMAND** - Đầu vào: orderId. Chỉ dành cho Admin. |
|
|
| `application/commands/hold-escrow/hold-escrow.handler.ts` | **HOLD ESCROW HANDLER (Dòng 23-67)** - Lấy order + escrow theo orderId. Gọi escrow.hold() để chuyển trạng thái. Cập nhật cả hai thực thể. Phát EscrowHeldEvent. **LƯU Ý BẢO MẬT**: Không có Redis lock - tiềm ẩn race condition nếu có nhiều yêu cầu đồng thời. |
|
|
| `application/commands/release-escrow/release-escrow.command.ts` | **RELEASE ESCROW COMMAND** - Đầu vào: orderId. Chỉ dành cho Admin. |
|
|
| `application/commands/release-escrow/release-escrow.handler.ts` | **RELEASE ESCROW HANDLER (Dòng 24-45)** - Lấy order + escrow theo orderId. Gọi escrow.release() để chuyển trạng thái. Cập nhật cả hai thực thể. Phát EscrowReleasedEvent với netPayout. **LƯU Ý BẢO MẬT**: Không có Redis lock - tiềm ẩn race condition. |
|
|
|
|
### Các Payment Command
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `application/commands/create-payment/create-payment.command.ts` | **CREATE PAYMENT COMMAND** - Đầu vào: userId, provider, type, amountVND, description, returnUrl, ipAddress, transactionId, idempotencyKey. |
|
|
| `application/commands/create-payment/create-payment.handler.ts` | **CREATE PAYMENT HANDLER** - Kiểm tra idempotency. Xác thực amount (Money VO). Lấy payment gateway. Gọi createPaymentUrl(). Tạo PaymentEntity (trạng thái PENDING). Lưu. Phát PaymentCreatedEvent. Trả về paymentUrl để frontend chuyển hướng. |
|
|
| `application/commands/refund-payment/refund-payment.command.ts` | **REFUND PAYMENT COMMAND** - Đầu vào: paymentId, reason, userId. Lệnh dành cho Admin. |
|
|
| `application/commands/refund-payment/refund-payment.handler.ts` | **REFUND PAYMENT HANDLER** - Xác minh thanh toán tồn tại, gọi gateway.refund() với các tham số đặc thù nhà cung cấp, cập nhật trạng thái thanh toán thành REFUNDED, phát PaymentRefundedEvent. |
|
|
|
|
### Handler Callback (QUAN TRỌNG)
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `application/commands/handle-callback/handle-callback.command.ts` | **HANDLE CALLBACK COMMAND** - Đầu vào: provider (enum PaymentProvider), callbackData (Record<string, string>). |
|
|
| `application/commands/handle-callback/handle-callback.handler.ts` | **HANDLE CALLBACK HANDLER (Dòng 32-110)** - **FILE BẢO MẬT QUAN TRỌNG**. Lấy gateway, gọi verifyCallback() (xác thực chữ ký). Nếu không hợp lệ: ném ValidationException. Nếu hợp lệ: **Dùng `paymentRepo.updateIfStatus()` với WHERE có điều kiện ['PENDING', 'PROCESSING']** (Dòng 48-55) - cập nhật nguyên tử để ngăn xử lý trùng lặp. Nếu cập nhật trả về null: kiểm tra xem thanh toán có tồn tại không (đã xử lý - phản hồi idempotent). Nếu thành công: gọi payment.emitCompleted(), ngược lại payment.emitFailed(). Phát sự kiện. **BẢO VỆ RACE CONDITION MẠNH qua cập nhật có điều kiện**. |
|
|
|
|
---
|
|
|
|
## 7. TẦNG ỨNG DỤNG - QUERY
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `application/queries/get-order-status/get-order-status.query.ts` | Query: Đầu vào orderId, userId (để phân quyền). |
|
|
| `application/queries/get-order-status/get-order-status.handler.ts` | Lấy order, xác minh quyền sở hữu (buyer/seller), trả về trạng thái + chi tiết. |
|
|
| `application/queries/get-payment-status/get-payment-status.query.ts` | Query: Đầu vào paymentId, userId. |
|
|
| `application/queries/get-payment-status/get-payment-status.handler.ts` | Lấy thanh toán, xác minh quyền sở hữu, trả về trạng thái + chi tiết. |
|
|
| `application/queries/list-transactions/list-transactions.query.ts` | Query: Đầu vào userId, status (tùy chọn), limit, offset. |
|
|
| `application/queries/list-transactions/list-transactions.handler.ts` | Liệt kê các thanh toán của người dùng với phân trang, lọc theo status nếu được cung cấp. |
|
|
|
|
---
|
|
|
|
## 8. TẦNG TRÌNH BÀY - CONTROLLER
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `presentation/controllers/orders.controller.ts` | **ORDERS CONTROLLER** - Các route: POST / (tạo order), GET /:id (trạng thái), POST /:id/cancel (hủy), POST /:id/escrow/hold (admin), POST /:id/escrow/release (admin). Xác thực: JwtAuthGuard, RolesGuard cho các thao tác admin. Chuyển đổi DTO thành command. |
|
|
| `presentation/controllers/payments.controller.ts` | **PAYMENTS CONTROLLER** - Các route: POST / (tạo thanh toán), POST /callback/:provider (webhook - **Throttle + EndpointRateLimit**), GET /:id (trạng thái), GET (danh sách), POST /:id/refund (admin hoàn tiền). **QUAN TRỌNG: Endpoint callback có giới hạn tốc độ (Throttle + EndpointRateLimitGuard)** - ngăn chặn lũ lụt callback. |
|
|
|
|
---
|
|
|
|
## 9. TẦNG TRÌNH BÀY - DTO
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `presentation/dto/create-order.dto.ts` | DTO: sellerId, listingId, amountVND (string), idempotencyKey (tùy chọn). |
|
|
| `presentation/dto/cancel-order.dto.ts` | DTO: reason (string). |
|
|
| `presentation/dto/create-payment.dto.ts` | DTO: provider (enum), type (enum), amountVND (string), description, returnUrl, transactionId (tùy chọn), idempotencyKey (tùy chọn). |
|
|
| `presentation/dto/refund-payment.dto.ts` | DTO: reason (string). |
|
|
| `presentation/dto/list-transactions.dto.ts` | DTO: status (tùy chọn), limit, offset. |
|
|
|
|
---
|
|
|
|
## 10. MODULE & CÁC FILE KIỂM THỬ
|
|
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `payments.module.ts` | **CÀI ĐẶT MODULE** - Đăng ký các repository, service, handler, controller. |
|
|
| `index.ts` (cấp module) | Xuất API công khai. |
|
|
| `infrastructure/repositories/index.ts` | Xuất các triển khai repository. |
|
|
| `infrastructure/services/index.ts` | Xuất các dịch vụ gateway. |
|
|
| `application/index.ts` | Xuất các handler command/query. |
|
|
| `domain/repositories/index.ts` | Xuất các giao diện repository. |
|
|
| `domain/entities/index.ts` | Xuất các thực thể. |
|
|
| `domain/value-objects/index.ts` | Xuất các VO. |
|
|
| `domain/events/index.ts` | Xuất các sự kiện domain. |
|
|
| `presentation/controllers/index.ts` | Xuất các controller. |
|
|
| `presentation/dto/index.ts` | Xuất các DTO. |
|
|
|
|
### Các File Kiểm Thử
|
|
| File | Mô tả |
|
|
|------|-------|
|
|
| `domain/__tests__/order.entity.spec.ts` | Kiểm thử đơn vị thực thể Order - máy trạng thái, các chuyển trạng thái |
|
|
| `domain/__tests__/escrow.entity.spec.ts` | Kiểm thử đơn vị thực thể Escrow - hold, release, dispute, refund |
|
|
| `domain/__tests__/payment.entity.spec.ts` | Kiểm thử đơn vị thực thể Payment |
|
|
| `domain/__tests__/money.vo.spec.ts` | Kiểm thử xác thực Money VO |
|
|
| `domain/__tests__/platform-fee.vo.spec.ts` | Kiểm thử tính toán phí nền tảng |
|
|
| `domain/__tests__/payment-events.spec.ts` | Kiểm thử phát sự kiện domain |
|
|
| `application/__tests__/create-order.handler.spec.ts` | Kiểm thử handler tạo order |
|
|
| `application/__tests__/create-payment.handler.spec.ts` | Kiểm thử handler tạo thanh toán |
|
|
| `application/__tests__/handle-callback.handler.spec.ts` | Kiểm thử xử lý callback |
|
|
| `application/__tests__/handle-callback-edge-cases.handler.spec.ts` | Kiểm thử các trường hợp biên callback (race condition, idempotency) |
|
|
| `application/__tests__/get-payment-status.handler.spec.ts` | Kiểm thử query trạng thái thanh toán |
|
|
| `application/__tests__/refund-payment.handler.spec.ts` | Kiểm thử lệnh hoàn tiền |
|
|
| `application/__tests__/list-transactions.handler.spec.ts` | Kiểm thử query danh sách giao dịch |
|
|
| `infrastructure/__tests__/vnpay.service.spec.ts` | Kiểm thử gateway VNPay - xác minh chữ ký |
|
|
| `infrastructure/__tests__/momo.service.spec.ts` | Kiểm thử gateway MoMo - xác minh HMAC-SHA256 |
|
|
| `infrastructure/__tests__/zalopay.service.spec.ts` | Kiểm thử gateway ZaloPay - phân tích JSON + xác minh MAC |
|
|
| `infrastructure/__tests__/payment-gateway.factory.spec.ts` | Kiểm thử mẫu factory |
|
|
|
|
---
|
|
|
|
## TÓM TẮT KẾT QUẢ BẢO MẬT
|
|
|
|
### ✅ CÁC BIỆN PHÁP BẢO MẬT MẠNH
|
|
1. **Xác Minh Chữ Ký Callback**: Cả 3 nhà cung cấp (VNPay, MoMo, ZaloPay) đều xác minh chữ ký HMAC sử dụng `crypto.timingSafeEqual()` để so sánh thời gian cố định
|
|
2. **Ngăn Chặn Race Condition Nguyên Tử**: `paymentRepo.updateIfStatus()` sử dụng mệnh đề WHERE có điều kiện để cập nhật nguyên tử chỉ khi ở trạng thái PENDING/PROCESSING
|
|
3. **Bảo Vệ Idempotency**: Order + Payment kiểm tra idempotencyKey để ngăn chặn các thao tác trùng lặp
|
|
4. **Giới Hạn Tốc Độ**: Endpoint callback có decorator Throttle + EndpointRateLimit
|
|
5. **Phân Quyền**: Tất cả endpoint yêu cầu JwtAuthGuard; các thao tác admin yêu cầu RolesGuard
|
|
6. **Xác Thực Số Tiền**: Money VO xác thực: 0 < amount ≤ 999_999_999_999 VND
|
|
7. **Xác Thực Máy Trạng Thái**: Order + Escrow thực thi các chuyển trạng thái hợp lệ
|
|
|
|
### ⚠️ VẤN ĐỀ BẢO MẬT (CẦN KIỂM TRA)
|
|
1. **Race Condition Hold/Release Escrow**: Không có Redis lock trên các handler hold-escrow/release-escrow - các yêu cầu đồng thời có thể gây ra sự không nhất quán trạng thái
|
|
2. **Không Có Cơ Chế Khóa Phân Tán**: Các thao tác escrow không được bảo vệ trước các yêu cầu đồng thời từ các máy chủ khác nhau
|
|
3. **Idempotency Xử Lý Callback**: Mặc dù paymentRepo.updateIfStatus() ngăn xử lý hai lần, kiểm tra idempotency không xác minh tính nhất quán của chữ ký callback
|
|
4. **Bí Mật Nhà Cung Cấp Thanh Toán**: Các khóa được tải từ ConfigService - xác minh mã hóa biến môi trường khi lưu trữ
|
|
5. **Phân Quyền Hoàn Tiền**: Chỉ kiểm tra vai trò ADMIN - không có xác thực logic nghiệp vụ (ví dụ: thời hạn hoàn tiền, số tiền hoàn tiền tối đa)
|
|
6. **Race Update Order/Escrow**: Mặc dù hold là nguyên tử đối với thanh toán, cập nhật order + escrow trong handler được thực hiện tuần tự (2 lần gọi DB), không nguyên tử
|
|
|
|
---
|
|
|
|
## CÁC FILE KHÔNG TÌM THẤY / NGOÀI PHẠM VI
|
|
- ❌ **Sử Dụng Redis Lock**: Không tìm thấy Redis lock trong module thanh toán. MỐI LO NGẠI: Quan trọng cho escrow hold/release.
|
|
- ❌ **Tiện Ích Thanh Toán Dùng Chung**: Không có module tiện ích thanh toán bên ngoài nào được tham chiếu
|
|
- ❌ **Mã Hóa Dữ Liệu Thanh Toán**: Không có mã hóa cấp trường cho dữ liệu thanh toán nhạy cảm (mặc dù dịch vụ field-encryption tồn tại trong module shared)
|