修复BSC币商C2C凭证校验
This commit is contained in:
parent
aac2b4dc76
commit
7609509f7f
@ -342,8 +342,10 @@ func (s *Service) verifyUSDTRechargeReceipt(ctx context.Context, command ledger.
|
||||
snapshot.ProviderAmountMinor = command.USDMinorAmount
|
||||
snapshot.ProviderOrderID = command.ExternalOrderNo
|
||||
snapshot.ReceiveAddress = strings.TrimSpace(receiveAddress)
|
||||
if chain == "trc20" && !isLikelyChainTransactionHash(command.ExternalOrderNo) {
|
||||
return s.verifyBinanceTRXDepositReceipt(ctx, command, snapshot)
|
||||
if !isLikelyChainTransactionHash(command.ExternalOrderNo) {
|
||||
// Binance Pay C2C 订单号不属于某条公链;后台选择 TRC20 或 BEP20 只表示运营记录的支付币种。
|
||||
// 因此所有非链上哈希都必须先走 Binance 账户入账事实,不能把 BEP20 的 C2C 订单号误送给 BSC 链上客户端。
|
||||
return s.verifyBinanceTransferReceipt(ctx, command, snapshot, binanceNetworkForReceiptChain(chain))
|
||||
}
|
||||
if client == nil {
|
||||
return ledger.CoinSellerRechargeReceiptVerification{}, xerr.New(xerr.Unavailable, "usdt "+chain+" client is not configured")
|
||||
@ -360,7 +362,7 @@ func (s *Service) verifyUSDTRechargeReceipt(ctx context.Context, command ledger.
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
func (s *Service) verifyBinanceTRXDepositReceipt(ctx context.Context, command ledger.VerifyCoinSellerRechargeReceiptCommand, snapshot ledger.CoinSellerRechargeReceiptVerification) (ledger.CoinSellerRechargeReceiptVerification, error) {
|
||||
func (s *Service) verifyBinanceTransferReceipt(ctx context.Context, command ledger.VerifyCoinSellerRechargeReceiptCommand, snapshot ledger.CoinSellerRechargeReceiptVerification, network string) (ledger.CoinSellerRechargeReceiptVerification, error) {
|
||||
if s.binance == nil {
|
||||
return ledger.CoinSellerRechargeReceiptVerification{}, xerr.New(xerr.Unavailable, "binance client is not configured")
|
||||
}
|
||||
@ -370,7 +372,7 @@ func (s *Service) verifyBinanceTRXDepositReceipt(ctx context.Context, command le
|
||||
AppCode: command.AppCode,
|
||||
ExternalID: command.ExternalOrderNo,
|
||||
Coin: ledger.PaidCurrencyUSDT,
|
||||
Network: "TRX",
|
||||
Network: network,
|
||||
ToAddress: snapshot.ReceiveAddress,
|
||||
AmountMinor: command.USDMinorAmount,
|
||||
OrderTimeMS: command.OrderDateMS,
|
||||
@ -392,6 +394,17 @@ func (s *Service) verifyBinanceTRXDepositReceipt(ctx context.Context, command le
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
func binanceNetworkForReceiptChain(chain string) string {
|
||||
// Binance Deposit History 使用交易所网络代码而不是后台 provider 名称;Pay C2C 不校验网络,
|
||||
// 但同一个入口也支持 off-chain Deposit History,因此这里必须保留准确映射。
|
||||
switch strings.ToLower(strings.TrimSpace(chain)) {
|
||||
case "bep20":
|
||||
return "BSC"
|
||||
default:
|
||||
return "TRX"
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) receiptSnapshot(command ledger.VerifyCoinSellerRechargeReceiptCommand) ledger.CoinSellerRechargeReceiptVerification {
|
||||
return ledger.CoinSellerRechargeReceiptVerification{
|
||||
ProviderCode: command.ProviderCode,
|
||||
|
||||
@ -467,10 +467,11 @@ func TestVerifyCoinSellerRechargeReceiptUSDTBEP20UsesReadOnlyClient(t *testing.T
|
||||
USDTBEP20Enabled: true,
|
||||
USDTBEP20Address: "0xPlatformBEP20ReceiveAddress",
|
||||
})
|
||||
txHash := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
receipt, err := svc.VerifyCoinSellerRechargeReceipt(context.Background(), ledger.VerifyCoinSellerRechargeReceiptCommand{
|
||||
AppCode: "lalu",
|
||||
ProviderCode: ledger.PaymentProviderUSDTBEP20,
|
||||
ExternalOrderNo: "0xreceiptbep20",
|
||||
ExternalOrderNo: txHash,
|
||||
USDMinorAmount: 150,
|
||||
})
|
||||
if err != nil {
|
||||
@ -479,7 +480,7 @@ func TestVerifyCoinSellerRechargeReceiptUSDTBEP20UsesReadOnlyClient(t *testing.T
|
||||
if !receipt.Verified || receipt.Status != "confirmed" || receipt.Chain != "bep20" || receipt.ProviderAmountMinor != 150 || receipt.ReceiveAddress != "0xPlatformBEP20ReceiveAddress" {
|
||||
t.Fatalf("bep20 receipt snapshot mismatch: %+v", receipt)
|
||||
}
|
||||
if bsc.lastTxHash != "0xreceiptbep20" || bsc.lastToAddress != "0xPlatformBEP20ReceiveAddress" || bsc.lastAmountMinor != 150 {
|
||||
if bsc.lastTxHash != txHash || bsc.lastToAddress != "0xPlatformBEP20ReceiveAddress" || bsc.lastAmountMinor != 150 {
|
||||
t.Fatalf("bep20 client request mismatch: %+v", bsc)
|
||||
}
|
||||
}
|
||||
@ -611,6 +612,51 @@ func TestVerifyCoinSellerRechargeReceiptUSDTTRC20PayKeepsConfiguredAddress(t *te
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyCoinSellerRechargeReceiptUSDTBEP20PayUsesBinance(t *testing.T) {
|
||||
bsc := &fakeTronUSDTClient{err: xerr.New(xerr.Internal, "bsc chain client should not be called")}
|
||||
binance := &fakeBinanceClient{record: walletservice.BinanceTransferRecord{
|
||||
Source: "pay_history",
|
||||
ID: "440537037787594752",
|
||||
TxID: "P_C2C_BEP20_RECEIPT",
|
||||
Coin: ledger.PaidCurrencyUSDT,
|
||||
Status: 1,
|
||||
Amount: "200.00000000",
|
||||
AmountMinor: 20000,
|
||||
RawJSON: `{"orderType":"C2C","orderId":"440537037787594752","amount":"200.00000000","currency":"USDT"}`,
|
||||
}}
|
||||
svc := walletservice.New(nil)
|
||||
svc.SetBSCUSDTClient(bsc)
|
||||
svc.SetBinanceClient(binance)
|
||||
svc.SetExternalRechargeConfig(walletservice.ExternalRechargeConfig{
|
||||
USDTBEP20Enabled: true,
|
||||
USDTBEP20Addresses: map[string]string{
|
||||
"yumi": "0xYumiConfiguredBSCAddress",
|
||||
},
|
||||
})
|
||||
receipt, err := svc.VerifyCoinSellerRechargeReceipt(context.Background(), ledger.VerifyCoinSellerRechargeReceiptCommand{
|
||||
AppCode: "yumi",
|
||||
ProviderCode: ledger.PaymentProviderUSDTBEP20,
|
||||
ExternalOrderNo: "440537037787594752",
|
||||
USDMinorAmount: 20000,
|
||||
OrderDateMS: 1784017140000,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("VerifyCoinSellerRechargeReceipt BEP20 Pay C2C failed: %v", err)
|
||||
}
|
||||
if !receipt.Verified || receipt.Status != "confirmed" || receipt.ProviderOrderID != "P_C2C_BEP20_RECEIPT" || receipt.ProviderAmountMinor != 20000 {
|
||||
t.Fatalf("BEP20 Pay C2C receipt snapshot mismatch: %+v", receipt)
|
||||
}
|
||||
if receipt.ReceiveAddress != "0xYumiConfiguredBSCAddress" {
|
||||
t.Fatalf("BEP20 Pay C2C must keep configured chain address: %+v", receipt)
|
||||
}
|
||||
if binance.calls != 1 || binance.req.Network != "BSC" || binance.req.ExternalID != "440537037787594752" || binance.req.AmountMinor != 20000 {
|
||||
t.Fatalf("BEP20 Pay C2C must use Binance transfer lookup: calls=%d req=%+v", binance.calls, binance.req)
|
||||
}
|
||||
if bsc.lastTxHash != "" {
|
||||
t.Fatalf("BEP20 Pay C2C order id must not call BSC chain client: %+v", bsc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyCoinSellerRechargeReceiptUSDTTRC20OffchainMissingBinanceAccount(t *testing.T) {
|
||||
binance := &fakeBinanceClient{err: xerr.New(xerr.Unavailable, "binance account is not configured")}
|
||||
svc := walletservice.New(nil)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user