Task 1-2: Chuẩn hóa Order Status Check trước khi Credit
Phase: 1 - Idempotency Priority: High Depends on: task-1-1 Reference: docs/BountyHunter-Backend/details/feature-payment-marketplace/SPEC.md
Background
Sau audit (task-1-1), chuẩn hóa pattern status check thành một utility có thể reuse thay vì mỗi handler implement riêng.
Tasks
1. Tạo PaymentIdempotencyGuard utility
DI Note:
PaymentIdempotencyGuardlà@Component— inject vào mọi webhook handler qua constructor (@RequiredArgsConstructor). Không injectPaymentOrderRepositoryvào guard này — guard chỉ nhậncurrentStatus(đã query từ handler). Logger làprivate static final Logger LOGGER = LoggerFactory.getLogger(PaymentIdempotencyGuard.class);hoặc Lombok@Slf4j.
@Component
@Slf4j
public class PaymentIdempotencyGuard {
/**
* @return true nếu có thể tiếp tục process (status == PENDING)
* false nếu đã processed (idempotent skip)
*/
public boolean canProcess(String orderId, PaymentStatus currentStatus) {
if (currentStatus == PaymentStatus.PENDING) {
return true;
}
log.warn("[PAYMENT_IDEMPOTENCY] Order {} already in status={}, skipping", orderId, currentStatus);
return false;
}
}
2. Apply cho tất cả webhook handlers
- [ ]
confirmCardPayment→ inject và dùngpaymentIdempotencyGuard.canProcess(orderId, order.getStatus()) - [ ]
confirmCryptoPayment - [ ]
confirmNftTransfer(cả 3 branches — ADMIN, OWNER, default — đều check) - [ ]
mintCompressNftConfirm - [ ] Apple IAP confirm
- [ ] Google Play confirm
3. Đảm bảo coin credit trong transaction
- [ ] Status update + coin credit phải trong cùng 1
@Transactional— verify bằng cách check@Transactionalpropagation trên service methods - [ ] Nếu coin service dùng separate datasource → cần distributed transaction hoặc compensating transaction
Verification / Acceptance Criteria
- [ ]
PaymentIdempotencyGuard.javatồn tại và compile thành công - [ ] Tất cả 6 webhook handlers inject và gọi
canProcess()trước khi process - [ ] Khi
canProcess()trảfalse→ handler return ngay, không modify DB - [ ]
@Transactionalbao phủ đúng scope: status update + coin credit trong cùng transaction - [ ] Unit test
PaymentIdempotencyGuard: trảtruekhi PENDING,falsekhi SUCCESS/FAILED
Files to Create / Modify
application-core/service/payment/PaymentIdempotencyGuard.java(new)- Các webhook handler files (6 handlers từ task-1-1)