Đặc tả: Payment & Marketplace Feature
Module: webmarketplace (port 8084)
Status: Production
1. Tổng quan
Feature này bao phủ toàn bộ payment lifecycle: mua coin, mua NFT, presale/genesis orders và webhook confirmation từ các payment gateways.
2. Phạm vi
In-scope APIs
CoinController (/api/coin)
| Endpoint |
Method |
Gateway |
Mô tả |
/buy-by-card |
POST |
Fincode/SBPS |
Mua coin bằng credit card |
/buy-by-apple |
POST |
Apple IAP |
Mua coin qua Apple In-App Purchase |
/buy-by-google |
POST |
Google Play |
Mua coin qua Google Play Billing |
/buy-by-crypto |
POST |
Slash |
Mua coin bằng crypto |
/order-status |
GET |
- |
Kiểm tra trạng thái order |
PaymentController (/api/payment)
| Endpoint |
Method |
Mô tả |
/select-payment-app |
POST |
User chọn payment app |
/generate-hash |
POST |
Generate hash cho SBPS |
/sbps-webhook |
POST |
SBPS webhook receiver |
UserController (/api/users trong webmarketplace)
| Endpoint |
Method |
Mô tả |
/buy-by-card |
POST |
Mua NFT/product bằng card |
/buy-by-crypto |
POST |
Mua NFT/product bằng crypto |
/buy-nft/{productId} |
POST |
Mua NFT cụ thể |
/confirm-buy-by-bth |
POST |
Confirm mua bằng BTH token |
/buy-genesis-* |
POST |
Genesis NFT pre-order flows |
WebHookController (/api/webhook)
| Endpoint |
Method |
Gateway |
Mô tả |
/confirm-card-payment |
POST |
Fincode |
Xác nhận thanh toán card |
/confirm-crypto-payment |
POST |
Slash |
Xác nhận thanh toán crypto |
/nft-transfer-confirm |
POST |
Node server |
Xác nhận NFT transfer |
/nft-lock-confirm |
POST |
Node server |
Xác nhận NFT lock |
/sell-gacha-nft-confirm |
POST |
Node server |
Xác nhận bán gacha NFT |
/confirm-burn-nft |
POST |
Node server |
Xác nhận burn NFT ticket |
/confirm-transfer-currency |
POST |
Node server |
Xác nhận transfer currency token |
/nft-ownership-change |
POST |
Node server |
Thay đổi NFT ownership |
/mint-compress-nft-confirm |
POST |
Node server |
Xác nhận mint compressed NFT |
/transfer-compress-nft-confirm |
POST |
Node server |
Xác nhận transfer compressed NFT |
/nft-solana-change |
POST |
Node server |
Solana NFT ownership change |
3. User stories
| ID |
Role |
Story |
Acceptance |
| PAY-US-01 |
User |
Mua coin bằng card → nhận coin ngay hoặc chờ webhook confirm |
Order tạo, coin credited sau confirm |
| PAY-US-02 |
User |
Mua coin bằng Apple IAP → hệ thống verify với Apple → coin credited |
Apple receipt verified |
| PAY-US-03 |
User |
Mua NFT bằng native token → on-chain confirm → NFT transferred |
Ownership updated sau confirm |
| PAY-US-04 |
User |
Thanh toán timeout → order tự expire, không bị trừ tiền |
Batch job cleanup đúng |
| PAY-US-05 |
System |
Webhook từ Fincode → confirm order đúng 1 lần (idempotent) |
Double webhook không double credit |
4. Functional requirements
| ID |
Requirement |
Chi tiết |
| PAY-F-01 |
Orchestration |
PaymentService là orchestration layer, delegate sang gateway-specific service |
| PAY-F-02 |
Gateway isolation |
PaymentCreditCardService, PaymentCryptoService, PaymentNativeTokenService, PaymentAppleService, PaymentGoogleService |
| PAY-F-03 |
Idempotent webhook |
Webhook endpoint phải check order status trước khi confirm (không double credit) |
| PAY-F-04 |
Presale/genesis |
Support pre-order flow với cancel/confirm lifecycle |
| PAY-F-05 |
Signature validation |
Fincode webhook validate Fincode-Signature header |
| PAY-F-06 |
Timeout handling |
Batch jobs expire pending orders: CardCheckoutExpiredConfig, CryptoCheckoutExpiredConfig, NativeTokenCheckoutExpiredConfig |
| PAY-F-07 |
NFT transfer confirm |
3 types: to admin wallet, to owner, to user (switch by transferType) |
| PAY-F-08 |
Compressed NFT |
Support Solana compressed NFT mint/transfer confirm |
5. Business rules
- Fincode webhook: kiểm tra
Fincode-Signature header match paymentFincodeSettingService.getSignature().
- SBPS webhook:
@RequestParam form-encoded payload.
- Apple/Google: server-side receipt verification với Apple/Google servers.
- NFT transfer types:
TRANSFER_NFT_TO_ADMIN_WALLET, TRANSFER_NFT_OWNER, default TRANSFER_TO_USER.
- Compress NFT mint fail:
status=false hoặc leafIndex=Unknown → handle mint fail.
6. Data contracts
Request - buy-by-card
{
"order_id": "<orderId>",
"product_id": "<productId>",
"amount": 1000,
"card_token": "<fincodeCardToken>",
"payment_method": "CARD"
}
Response - buy-by-card
{
"order_id": "<orderId>",
"status": "PENDING | SUCCESS | FAILED",
"checkout_url": "<url>",
"payment_id": "<paymentId>"
}
{
"id": "<paymentId>",
"status": "CAPTURED",
"amount": 1000,
"order_id": "<orderId>"
}
Response - Apple IAP
{
"order_id": "<orderId>",
"product_id": "<productId>"
}
7. Acceptance criteria
- [ ]
buy-by-card tạo pending order → Fincode webhook confirm → coin credited
- [ ]
buy-by-apple verify receipt với Apple → SUCCESS → coin credited
- [ ]
buy-by-google verify receipt với Google Play → coin credited
- [ ]
buy-by-crypto tạo Slash invoice → webhook confirm → coin/NFT credited
- [ ] Fincode webhook với sai signature →
FINCODE_SIGNATURE_IS_INVALID (không process)
- [ ] Double webhook cùng paymentId → idempotent, không double credit
- [ ] Pending order quá TTL → batch job expire, không credit
- [ ] NFT transfer confirm với 3 transfer types đúng routing
8. Constraints
webmarketplace module port 8084, không có Tomcat config (minimal).
- Webhook endpoints phải whitelist trong
SecurityConfig (không cần JWT).
- Fincode signature so sánh exact string match.
9. Code references
webmarketplace/
controllers/
coin/CoinController.java
payment/PaymentController.java
webhook/WebHookController.java
nft_rental/NftRentalController.java
user/UserController.java (marketplace ops)
application-core/
service/payment/PaymentService.java
service/payment_card/PaymentCreditCardService.java
service/payment_crypto/PaymentCryptoService.java
service/payment_native_token/PaymentNativeTokenService.java
service/payment_apple/PaymentAppleService.java
service/payment_google/PaymentGoogleService.java
service/payment_fincode/
service/transfer_nft/TransferNftService.java
service/lock_nft/LockNftService.java
batch/
job/
card_payment_expired/CardCheckoutExpiredConfig.java
card_payment_confirm/CardPaymentConfirmConfig.java
crypto_payment_expired/CryptoCheckoutExpiredConfig.java
genesis_nft/NativeTokenCheckoutExpiredConfig.java
genesis_nft/ExpiredPreOrderGenesisNftConfig.java