feat(tenpayv3): 新增 ETC 扣费相关接口

This commit is contained in:
Fu Diwei
2023-04-03 17:41:40 +08:00
parent 183d1afa1e
commit 7d019e0fb7
33 changed files with 1198 additions and 9 deletions

View File

@@ -0,0 +1,9 @@
{
"appid": "wxcbda96de0b165486",
"sp_mchid": "10000098",
"sp_openid": "onqOjjmM1tad-3ROpncN-yUfa6ua",
"sub_mchid": "1900000109",
"contract_id": "aAfixCs13LsdKPpfZfDkk2189ssXjfx",
"bind_state": "DELETED",
"plate_number": "浙ASB945"
}

View File

@@ -0,0 +1,29 @@
{
"out_trade_no": "121775250124070332",
"sub_mchid": "1900000109",
"appid": "wxd678efh567hg6787",
"sub_appid": "wxd678efh567hg6999",
"contract_id": "wxd678ef4Fwxd678ef4Fwxd678ef4F21",
"description": "商品信息",
"attach": "自定义数据",
"goods_tag": "test",
"highway_info": {
"plate_number": "粤B888888",
"start_time": "2017-08-26T09:43:39+08:00",
"end_time": "2017-08-26T09:43:39+08:00",
"channel_type": "ETC",
"car_type": "CAR",
"entrance": "沿江深圳-大铲湾",
"exit": "广珠东线-珠海站",
"carrying_capacity": 3,
"carrying_range": "6-12"
},
"amount": {
"total": 888,
"currency": "CNY"
},
"device_info": {
"device_id": "POS1:1",
"device_ip": "123.12.12.123"
}
}

View File

@@ -0,0 +1,40 @@
{
"mchid": "1230000109",
"sub_mchid": "1900000109",
"appid": "wxd678efh567hg6787",
"sub_appid": "wxd678efh567hg6999",
"out_trade_no": "121775250124070332",
"transaction_id": "25012014070332333018",
"attach": "自定义数据",
"trade_type": "AUTH",
"bank_type": "CMC",
"success_time": "2017-08-26T10:43:39+08:00",
"trade_state": "SUCCESS",
"trade_state_desc": "请重新下单支付",
"payer": {
"openid": "oUpF8uMuAJOM2pxb1Q"
},
"amount": {
"total": 888,
"currency": "CNY",
"payer_total": 888,
"discount_total": 100
},
"device_info": {
"device_id": "POS1:1",
"device_ip": "123.12.12.123"
},
"promotion_detail": [
{
"promotion_id": "109519",
"name": "单品惠-6",
"scope": "SINGLE",
"type": "DISCOUNT",
"activity_id": "931386",
"amount": 5,
"wxpay_contribute": 0,
"merchant_contribute": 0,
"other_contribute": 5
}
]
}

View File

@@ -0,0 +1,9 @@
{
"appid": "wxcbda96de0b165486",
"sp_mchid": "10000098",
"sp_openid": "onqOjjmM1tad-3ROpncN-yUfa6ua",
"sub_mchid": "1900000109",
"contract_id": "aAfixCs13LsdKPpfZfDkk2189ssXjfx",
"bind_state": "DELETED",
"plate_number": "浙ASB945"
}

View File

@@ -0,0 +1,9 @@
{
"appid": "wxcbda96de0b165486",
"sp_mchid": "10000098",
"sp_openid": "onqOjjmM1tad-3ROpncN-yUfa6ua",
"sub_mchid": "1900000109",
"contract_id": "aAfixCs13LsdKPpfZfDkk2189ssXjfx",
"bind_state": "DELETED",
"plate_number": "浙ASB945"
}

View File

@@ -0,0 +1,40 @@
{
"mchid": "1230000109",
"sub_mchid": "1900000109",
"appid": "wxd678efh567hg6787",
"sub_appid": "wxd678efh567hg6999",
"out_trade_no": "121775250124070332",
"transaction_id": "25012014070332333018",
"attach": "自定义数据",
"trade_type": "AUTH",
"bank_type": "CMC",
"success_time": "2017-08-26T10:43:39+08:00",
"trade_state": "SUCCESS",
"trade_state_desc": "请重新下单支付",
"payer": {
"openid": "oUpF8uMuAJOM2pxb1Q"
},
"amount": {
"total": 888,
"currency": "CNY",
"payer_total": 888,
"discount_total": 100
},
"device_info": {
"device_id": "POS1:1",
"device_ip": "123.12.12.123"
},
"promotion_detail": [
{
"promotion_id": "109519",
"name": "单品惠-6",
"scope": "SINGLE",
"type": "DISCOUNT",
"activity_id": "931386",
"amount": 5,
"wxpay_contribute": 0,
"merchant_contribute": 0,
"other_contribute": 5
}
]
}

View File

@@ -0,0 +1,40 @@
{
"mchid": "1230000109",
"sub_mchid": "1900000109",
"appid": "wxd678efh567hg6787",
"sub_appid": "wxd678efh567hg6999",
"out_trade_no": "121775250124070332",
"transaction_id": "25012014070332333018",
"attach": "自定义数据",
"trade_type": "AUTH",
"bank_type": "CMC",
"success_time": "2017-08-26T10:43:39+08:00",
"trade_state": "SUCCESS",
"trade_state_desc": "请重新下单支付",
"payer": {
"openid": "oUpF8uMuAJOM2pxb1Q"
},
"amount": {
"total": 888,
"currency": "CNY",
"payer_total": 888,
"discount_total": 100
},
"device_info": {
"device_id": "POS1:1",
"device_ip": "123.12.12.123"
},
"promotion_detail": [
{
"promotion_id": "109519",
"name": "单品惠-6",
"scope": "SINGLE",
"type": "DISCOUNT",
"activity_id": "931386",
"amount": 5,
"wxpay_contribute": 0,
"merchant_contribute": 0,
"other_contribute": 5
}
]
}

View File

@@ -0,0 +1,14 @@
{
"sp_appid": "wx47c677487ce3ac47",
"sub_appid": "wxcc603d9f0d54eaf0",
"sub_mchid": "1510770601",
"openid": "ot35_4gNgXsUuh2sQY0lT9N08AU0",
"plan_id": "97619",
"etc_device_id": "xxxxxxx",
"plate_number": "藏ZZZZZZ",
"identify": {
"encrypted_real_name": "jUCOynVR0fvpLOX6jBeRlK/TErW6DqEM8JFHX4iL3Rlj2vqaEqktvw1KVjgmQ==",
"encrypted_credential_id": "l5CfRt85SAX3GxVYqGQm2Q8cfeFd1dWy40j4s7XpIds8Glw83HG3vN9Q==",
"credential_type": "ID_CARD"
}
}

View File

@@ -0,0 +1,3 @@
{
"preopen_id": "sdjf23kdsHJfdksj8djsK98HJio5hdI0"
}

View File

@@ -1073,6 +1073,50 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
await CreateMockClientUseSM2(autoEncrypt: true).ExecuteCreateTransferBatchAsync(reqB2);
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
}
[Fact(DisplayName = "测试用例:加密请求中的敏感数据([POST] /vehicle/etc/preopen")]
public async Task TestEncryptRequestSensitiveProperty_PreopenVehicleETCRequest()
{
static Models.PreopenVehicleETCRequest GenerateMockRequestModel()
{
return new Models.PreopenVehicleETCRequest()
{
Identify = new Models.PreopenVehicleETCRequest.Types.Identify()
{
EncryptedRealName = MOCK_PLAIN_STR,
EncryptedCredentialNumber = MOCK_PLAIN_STR
},
BankCardNumber = MOCK_PLAIN_STR
};
}
static void AssertMockRequestModel(Models.PreopenVehicleETCRequest request, Func<string, string> decryptor)
{
Assert.NotEqual(MOCK_PLAIN_STR, request.Identify!.EncryptedRealName!);
Assert.NotEqual(MOCK_PLAIN_STR, request.Identify!.EncryptedCredentialNumber!);
Assert.NotEqual(MOCK_PLAIN_STR, request.BankCardNumber!);
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Identify!.EncryptedRealName!));
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Identify!.EncryptedCredentialNumber!));
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.BankCardNumber!));
Assert.Equal(MOCK_CERT_SN, request.WechatpayCertificateSerialNumber!, ignoreCase: true);
}
var reqA1 = GenerateMockRequestModel();
CreateMockClientUseRSA(autoEncrypt: false).EncryptRequestSensitiveProperty(reqA1);
AssertMockRequestModel(reqA1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
var reqA2 = GenerateMockRequestModel();
CreateMockClientUseSM2(autoEncrypt: false).EncryptRequestSensitiveProperty(reqA2);
AssertMockRequestModel(reqA2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
var reqB1 = GenerateMockRequestModel();
await CreateMockClientUseRSA(autoEncrypt: true).ExecutePreopenVehicleETCAsync(reqB1);
AssertMockRequestModel(reqB1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
var reqB2 = GenerateMockRequestModel();
await CreateMockClientUseSM2(autoEncrypt: true).ExecutePreopenVehicleETCAsync(reqB2);
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
}
}
partial class TestCase_RequestEncryptionTests