feat(tenpayv3): 新增平台收付通注销提现相关接口

This commit is contained in:
Fu Diwei
2025-09-24 10:52:07 +08:00
parent d5aa9e3f2b
commit dff1f69fb1
17 changed files with 725 additions and 21 deletions

View File

@@ -1011,6 +1011,18 @@
- 按日下载提现异常文件:`GetMerchantFundWithdrawBill` - 按日下载提现异常文件:`GetMerchantFundWithdrawBill`
- 平台收付通(下载账单)
- 申请交易账单:`GetBillTradeBill`
- 申请资金账单:`GetBillFundflowBill`
- 获取分账账单文件下载地址:`GetProfitSharingBill`
- 申请二级商户资金账单:`GetEcommerceBillFundflowBill`
- 下载账单:`DownloadBillFile`
- 平台收付通(注销申请) - 平台收付通(注销申请)
- 提交注销申请单:`CreateEcommerceAccountCancelApplication` - 提交注销申请单:`CreateEcommerceAccountCancelApplication`
@@ -1027,31 +1039,15 @@
- 提交已注销商户号可用余额提现申请单:`CreateMerchantOperateRiskWithdrawlApply` - 提交已注销商户号可用余额提现申请单:`CreateMerchantOperateRiskWithdrawlApply`
- 平台收付通(跨境付款 - 平台收付通(注销提现
- 查询订单剩余可出境余额:`GetFundsToOverseaTransactionAvailableAbroadAmountByTransactionId` - 提交注销提现申请:`CreateEcommerceAccountCancelWithdrawApplication`
- 申请资金出境:`CreateFundsToOverseaOrder` - 商户申请单号查询申请单状态:`GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumber`
- 查询出境结果:`GetFundsToOverseaOrderByOutOrderId` - 微信支付申请单号查询申请单状态:`GetEcommerceAccountCancelWithdrawApplicationByApplymentId`
- 获取购付汇账单文件下载链接:`GetFundsToOverseaBillDownloadUrl` - 平台代商户确认注销:`ConfirmEcommerceAccountCancelWithdrawApplication`
- 申请资金出境退回:`CreateFundsToOverseaReturnOrder`
- 查询出境退回结果:`GetFundsToOverseaReturnOrderByOutReturnNumber`
- 平台收付通(下载账单)
- 申请交易账单:`GetBillTradeBill`
- 申请资金账单:`GetBillFundflowBill`
- 获取分账账单文件下载地址:`GetProfitSharingBill`
- 申请二级商户资金账单:`GetEcommerceBillFundflowBill`
- 下载账单:`DownloadBillFile`
- 平台收付通(商家转账) - 平台收付通(商家转账)

View File

@@ -87,6 +87,94 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
return await client.SendFlurlRequestAsync<Models.UploadEcommerceAccountCancelApplicationMediaResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false); return await client.SendFlurlRequestAsync<Models.UploadEcommerceAccountCancelApplicationMediaResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
} }
/// <summary>
/// <para>异步调用 [POST] /ecommerce/account/apply-cancel-withdraw 接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://pay.weixin.qq.com/doc/v3/partner/4013892756 ]]>
/// </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateEcommerceAccountCancelWithdrawApplicationResponse> ExecuteCreateEcommerceAccountCancelWithdrawApplicationAsync(this WechatTenpayClient client, Models.CreateEcommerceAccountCancelWithdrawApplicationRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateFlurlRequest(request, HttpMethod.Post, "ecommerce", "account", "apply-cancel-withdraw");
return await client.SendFlurlRequestAsJsonAsync<Models.CreateEcommerceAccountCancelWithdrawApplicationResponse>(flurlReq, data: request, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// <para>异步调用 [GET] /ecommerce/account/apply-cancel-withdraw/out-request-no/{out_request_no} 接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://pay.weixin.qq.com/doc/v3/partner/4013892759 ]]>
/// </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberResponse> ExecuteGetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberAsync(this WechatTenpayClient client, Models.GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateFlurlRequest(request, HttpMethod.Get, "ecommerce", "account", "apply-cancel-withdraw", "out-request-no", request.OutRequestNumber);
return await client.SendFlurlRequestAsJsonAsync<Models.GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberResponse>(flurlReq, data: request, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// <para>异步调用 [GET] /ecommerce/account/apply-cancel-withdraw/applyment-id/{applyment_id} 接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://pay.weixin.qq.com/doc/v3/partner/4013892765 ]]>
/// </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetEcommerceAccountCancelWithdrawApplicationByApplymentIdResponse> ExecuteGetEcommerceAccountCancelWithdrawApplicationByApplymentIdAsync(this WechatTenpayClient client, Models.GetEcommerceAccountCancelWithdrawApplicationByApplymentIdRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateFlurlRequest(request, HttpMethod.Get, "ecommerce", "account", "apply-cancel-withdraw", "applyment-id", request.ApplymentId);
return await client.SendFlurlRequestAsJsonAsync<Models.GetEcommerceAccountCancelWithdrawApplicationByApplymentIdResponse>(flurlReq, data: request, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// <para>异步调用 [POST] /ecommerce/account/apply-cancel-withdraw/confirm 接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://pay.weixin.qq.com/doc/v3/partner/4013892772 ]]>
/// </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ConfirmEcommerceAccountCancelWithdrawApplicationResponse> ExecuteConfirmEcommerceAccountCancelWithdrawApplicationAsync(this WechatTenpayClient client, Models.ConfirmEcommerceAccountCancelWithdrawApplicationRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateFlurlRequest(request, HttpMethod.Post, "ecommerce", "account", "apply-cancel-withdraw", "confirm");
return await client.SendFlurlRequestAsJsonAsync<Models.ConfirmEcommerceAccountCancelWithdrawApplicationResponse>(flurlReq, data: request, cancellationToken: cancellationToken).ConfigureAwait(false);
}
#endregion #endregion
#region Applyments #region Applyments

View File

@@ -0,0 +1,54 @@
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /ecommerce/account/apply-cancel-withdraw/confirm 接口的请求。</para>
/// </summary>
public class ConfirmEcommerceAccountCancelWithdrawApplicationRequest : WechatTenpayRequest
{
/// <summary>
/// 获取或设置微信二级商户号。
/// </summary>
[Newtonsoft.Json.JsonProperty("sub_mchid")]
[System.Text.Json.Serialization.JsonPropertyName("sub_mchid")]
public string SubMerchantId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置微信支付注销提现申请单号。与字段 <see cref="OutRequestNumber"/> 二选一。
/// </summary>
[Newtonsoft.Json.JsonProperty("applyment_id")]
[System.Text.Json.Serialization.JsonPropertyName("applyment_id")]
public string? ApplymentId { get; set; }
/// <summary>
/// 获取或设置商户注销申请单号。与字段 <see cref="ApplymentId"/> 二选一。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_request_no")]
[System.Text.Json.Serialization.JsonPropertyName("out_request_no")]
public string? OutRequestNumber { get; set; }
/// <summary>
/// 获取或设置平台确认操作人标识。
/// </summary>
[Newtonsoft.Json.JsonProperty("operator_identification")]
[System.Text.Json.Serialization.JsonPropertyName("operator_identification")]
public string? OperatorIdentification { get; set; }
/// <summary>
/// 获取或设置注销确认时间。
/// </summary>
[Newtonsoft.Json.JsonProperty("confirm_time")]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.Common.Rfc3339DateTimeOffsetConverter))]
[System.Text.Json.Serialization.JsonPropertyName("confirm_time")]
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.Common.Rfc3339DateTimeOffsetConverter))]
public DateTimeOffset ConfirmTime { get; set; }
/// <summary>
/// 获取或设置注销协议版本号。
/// </summary>
[Newtonsoft.Json.JsonProperty("cancel_contract_version")]
[System.Text.Json.Serialization.JsonPropertyName("cancel_contract_version")]
public string CancelContractVersion { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,29 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /ecommerce/account/apply-cancel-withdraw/confirm 接口的响应。</para>
/// </summary>
public class ConfirmEcommerceAccountCancelWithdrawApplicationResponse : WechatTenpayResponse
{
/// <summary>
/// 获取或设置微信二级商户号。
/// </summary>
[Newtonsoft.Json.JsonProperty("sub_mchid")]
[System.Text.Json.Serialization.JsonPropertyName("sub_mchid")]
public string SubMerchantId { get; set; } = default!;
/// <summary>
/// 获取或设置微信支付注销提现申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("applyment_id")]
[System.Text.Json.Serialization.JsonPropertyName("applyment_id")]
public string ApplymentId { get; set; } = default!;
/// <summary>
/// 获取或设置商户注销申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_request_no")]
[System.Text.Json.Serialization.JsonPropertyName("out_request_no")]
public string OutRequestNumber { get; set; } = default!;
}
}

View File

@@ -0,0 +1,177 @@
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /ecommerce/account/apply-cancel-withdraw 接口的请求。</para>
/// </summary>
[WechatTenpaySensitive]
public class CreateEcommerceAccountCancelWithdrawApplicationRequest : WechatTenpayRequest
{
public static class Types
{
public class Payee
{
public static class Types
{
public class BankAccount
{
/// <summary>
/// 获取或设置开户名称(需使用平台公钥/证书加密)。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountName { get; set; } = string.Empty;
/// <summary>
/// 获取或设置开户银行名称。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_bank")]
[System.Text.Json.Serialization.JsonPropertyName("account_bank")]
public string AccountBank { get; set; } = string.Empty;
/// <summary>
/// 获取或设置开户银行支行名称。
/// </summary>
[Newtonsoft.Json.JsonProperty("bank_branch_name")]
[System.Text.Json.Serialization.JsonPropertyName("bank_branch_name")]
public string? BankBranchName { get; set; }
/// <summary>
/// 获取或设置开户银行支行联行号。
/// </summary>
[Newtonsoft.Json.JsonProperty("bank_branch_id")]
[System.Text.Json.Serialization.JsonPropertyName("bank_branch_id")]
public string? BankBranchId { get; set; }
/// <summary>
/// 获取或设置银行账号(需使用平台公钥/证书加密)。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountNumber { get; set; } = string.Empty;
}
public class Identify
{
/// <summary>
/// 获取或设置证件类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_type")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_type")]
public string IdentityType { get; set; } = string.Empty;
/// <summary>
/// 获取或设置证件姓名(需使用平台公钥/证书加密)。
/// </summary>
[Newtonsoft.Json.JsonProperty("identification_name")]
[System.Text.Json.Serialization.JsonPropertyName("identification_name")]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdName { get; set; } = string.Empty;
/// <summary>
/// 获取或设置证件号码(需使用平台公钥/证书加密)。
/// </summary>
[Newtonsoft.Json.JsonProperty("identification_no")]
[System.Text.Json.Serialization.JsonPropertyName("identification_no")]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
}
}
/// <summary>
/// 获取或设置账户类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_type")]
[System.Text.Json.Serialization.JsonPropertyName("account_type")]
public string AccountType { get; set; } = string.Empty;
/// <summary>
/// 获取或设置银行账户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("bank_account_info")]
[System.Text.Json.Serialization.JsonPropertyName("bank_account_info")]
public Types.BankAccount? BankAccount { get; set; }
/// <summary>
/// 获取或设置证件信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("identity_info")]
[System.Text.Json.Serialization.JsonPropertyName("identity_info")]
public Types.Identify? Identify { get; set; }
}
public class ProofMedia
{
/// <summary>
/// 获取或设置申请材料类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("proof_media_type")]
[System.Text.Json.Serialization.JsonPropertyName("proof_media_type")]
public string Type { get; set; } = string.Empty;
/// <summary>
/// 获取或设置申请材料 MediaId。
/// </summary>
[Newtonsoft.Json.JsonProperty("proof_media")]
[System.Text.Json.Serialization.JsonPropertyName("proof_media")]
public string MediaId { get; set; } = string.Empty;
}
}
/// <summary>
/// 获取或设置微信二级商户号。
/// </summary>
[Newtonsoft.Json.JsonProperty("sub_mchid")]
[System.Text.Json.Serialization.JsonPropertyName("sub_mchid")]
public string SubMerchantId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置商户注销申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_request_no")]
[System.Text.Json.Serialization.JsonPropertyName("out_request_no")]
public string OutRequestNumber { get; set; } = string.Empty;
/// <summary>
/// 获取或设置提取资金类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("withdraw")]
[System.Text.Json.Serialization.JsonPropertyName("withdraw")]
public string? WithdrawType { get; set; }
/// <summary>
/// 获取或设置收款信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("payee_info")]
[System.Text.Json.Serialization.JsonPropertyName("payee_info")]
public Types.Payee? Payee { get; set; }
/// <summary>
/// 获取或设置申请材料列表。
/// </summary>
[Newtonsoft.Json.JsonProperty("proof_medias")]
[System.Text.Json.Serialization.JsonPropertyName("proof_medias")]
public IList<Types.ProofMedia>? ProofMediaList { get; set; }
/// <summary>
/// 获取或设置其他补充材料 MediaId 列表。
/// </summary>
[Newtonsoft.Json.JsonProperty("additional_materials")]
[System.Text.Json.Serialization.JsonPropertyName("additional_materials")]
public IList<string>? AdditionalMaterialMediaIdList { get; set; }
/// <summary>
/// 获取或设置备注。
/// </summary>
[Newtonsoft.Json.JsonProperty("remark")]
[System.Text.Json.Serialization.JsonPropertyName("remark")]
public string? Remark { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /ecommerce/account/apply-cancel-withdraw 接口的响应。</para>
/// </summary>
public class CreateEcommerceAccountCancelWithdrawApplicationResponse : WechatTenpayResponse
{
/// <summary>
/// 获取或设置微信支付注销提现申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("applyment_id")]
[System.Text.Json.Serialization.JsonPropertyName("applyment_id")]
public string ApplymentId { get; set; } = default!;
/// <summary>
/// 获取或设置商户注销申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_request_no")]
[System.Text.Json.Serialization.JsonPropertyName("out_request_no")]
public string OutRequestNumber { get; set; } = default!;
}
}

View File

@@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /ecommerce/account/apply-cancel-withdraw/applyment-id/{applyment_id} 接口的请求。</para>
/// </summary>
public class GetEcommerceAccountCancelWithdrawApplicationByApplymentIdRequest : WechatTenpayRequest
{
/// <summary>
/// 获取或设置微信支付注销提现申请单号。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string ApplymentId { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,9 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /ecommerce/account/apply-cancel-withdraw/applyment-id/{applyment_id} 接口的响应。</para>
/// </summary>
public class GetEcommerceAccountCancelWithdrawApplicationByApplymentIdResponse : GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberResponse
{
}
}

View File

@@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /ecommerce/account/apply-cancel-withdraw/out-request-no/{out_request_no} 接口的请求。</para>
/// </summary>
public class GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberRequest : WechatTenpayRequest
{
/// <summary>
/// 获取或设置商户注销申请单号。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string OutRequestNumber { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,133 @@
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /ecommerce/account/apply-cancel-withdraw/out-request-no/{out_request_no} 接口的响应。</para>
/// </summary>
public class GetEcommerceAccountCancelWithdrawApplicationByOutRequestNumberResponse : WechatTenpayResponse
{
public static class Types
{
public class WithdrawResult
{
/// <summary>
/// 获取或设置出款子账户类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_account_type")]
[System.Text.Json.Serialization.JsonPropertyName("out_account_type")]
public string OutAccountType { get; set; } = default!;
/// <summary>
/// 获取或设置付款状态。
/// </summary>
[Newtonsoft.Json.JsonProperty("pay_state")]
[System.Text.Json.Serialization.JsonPropertyName("pay_state")]
public string PayState { get; set; } = default!;
/// <summary>
/// 获取或设置付款状态描述。
/// </summary>
[Newtonsoft.Json.JsonProperty("state_description")]
[System.Text.Json.Serialization.JsonPropertyName("state_description")]
public string PayStateDescription { get; set; } = default!;
}
public class Account
{
/// <summary>
/// 获取或设置出款子账户类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_account_type")]
[System.Text.Json.Serialization.JsonPropertyName("out_account_type")]
public string OutAccountType { get; set; } = default!;
/// <summary>
/// 获取或设置账户金额(单位:分)。
/// </summary>
[Newtonsoft.Json.JsonProperty("amount")]
[System.Text.Json.Serialization.JsonPropertyName("amount")]
public int? Amount { get; set; }
}
}
/// <summary>
/// 获取或设置微信二级商户号。
/// </summary>
[Newtonsoft.Json.JsonProperty("sub_mchid")]
[System.Text.Json.Serialization.JsonPropertyName("sub_mchid")]
public string SubMerchantId { get; set; } = default!;
/// <summary>
/// 获取或设置微信支付注销提现申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("applyment_id")]
[System.Text.Json.Serialization.JsonPropertyName("applyment_id")]
public string ApplymentId { get; set; } = default!;
/// <summary>
/// 获取或设置商户注销申请单号。
/// </summary>
[Newtonsoft.Json.JsonProperty("out_request_no")]
[System.Text.Json.Serialization.JsonPropertyName("out_request_no")]
public string OutRequestNumber { get; set; } = default!;
/// <summary>
/// 获取或设置注销状态。
/// </summary>
[Newtonsoft.Json.JsonProperty("cancel_state")]
[System.Text.Json.Serialization.JsonPropertyName("cancel_state")]
public string CancelState { get; set; } = default!;
/// <summary>
/// 获取或设置注销状态描述。
/// </summary>
[Newtonsoft.Json.JsonProperty("cancel_state_description")]
[System.Text.Json.Serialization.JsonPropertyName("cancel_state_description")]
public string CancelStateDescription { get; set; } = default!;
/// <summary>
/// 获取或设置提取资金类型。
/// </summary>
[Newtonsoft.Json.JsonProperty("withdraw")]
[System.Text.Json.Serialization.JsonPropertyName("withdraw")]
public string? WithdrawType { get; set; }
/// <summary>
/// 获取或设置提现状态。
/// </summary>
[Newtonsoft.Json.JsonProperty("withdraw_state")]
[System.Text.Json.Serialization.JsonPropertyName("withdraw_state")]
public string? WithdrawState { get; set; }
/// <summary>
/// 获取或设置提现状态描述。
/// </summary>
[Newtonsoft.Json.JsonProperty("withdraw_state_description")]
[System.Text.Json.Serialization.JsonPropertyName("withdraw_state_description")]
public string? WithdrawStateDescription { get; set; }
/// <summary>
/// 获取或设置提现结果列表。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_withdraw_result")]
[System.Text.Json.Serialization.JsonPropertyName("account_withdraw_result")]
public Types.WithdrawResult[]? WithdrawResultList { get; set; }
/// <summary>
/// 获取或设置更新时间。
/// </summary>
[Newtonsoft.Json.JsonProperty("modify_time")]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.Common.Rfc3339DateTimeOffsetConverter))]
[System.Text.Json.Serialization.JsonPropertyName("modify_time")]
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.Common.Rfc3339DateTimeOffsetConverter))]
public DateTimeOffset? ModifyTime { get; set; }
/// <summary>
/// 获取或设置账户信息列表。
/// </summary>
[Newtonsoft.Json.JsonProperty("account_info")]
[System.Text.Json.Serialization.JsonPropertyName("account_info")]
public Types.Account[]? AccountList { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
{
"applyment_id": "X202410241010125346",
"out_request_no": "P202410241010125346",
"sub_mchid": "1900000109",
"operator_identification": "id1102",
"confirm_time": "2015-05-20T13:29:35+08:00",
"cancel_contract_version": "V20241213"
}

View File

@@ -0,0 +1,5 @@
{
"applyment_id": "X202410241010125346",
"sub_mchid": "1900000109",
"out_request_no": "P202410241010125346"
}

View File

@@ -0,0 +1,30 @@
{
"sub_mchid": "1900000109",
"out_request_no": "P202410241010125346",
"withdraw": "APPLY_WITHDRAW",
"payee_info": {
"account_type": "ACCOUNT_TYPE_CORPORATE",
"bank_account_info": {
"account_name": "AOZdYGISxo4y44/UgZ69bdu9X+tfMUJ9dl+LetjM45/zMbrYu+wWZ8gn4CTdo+D/m9MrPg+V4sm73oxqdQu/hj7aWyDl4GQtPXVdaztB9jVbVZh3QFzV+BEmytMNQp9dt1uWJktlfdDdLR3AMWyMB377xd+m9bSr/ioDTzagEcGe+vLYiKrzcroQv3OR0p3ppFYoQ3IfYeU/04S4t9rNFL+kyblK2FCCqQ11NdbbHoCrJc7NV4oASq6ZFonjTtgjjgKsadIKHXtb3JZKGZjduGdtkRJJp0/0eow96uY1Pk7Rq79Jtt7+I8juwEc4P4TG5xzchG/5IL9DBd+Z0zZXkw==",
"account_bank": "工商银行",
"bank_branch_id": "402713354941",
"bank_branch_name": "施秉县农村信用合作联社城关信用社",
"account_number": "d+xT+MQCvrLHUVDWv/8MR/dB7TkXM2YYZlokmXzFsWs35NXUot7C0NcxIrUF5FnxqCJHkNgKtxa6RxEYyba1+VBRLnqKG2fSy/Y5qDN08Ej9zHCwJjq52Wg1VG8MRugli9YMI1fI83KGBxhuXyemgS/hqFKsfYGiOkJqjTUpgY5VqjtL2N4l4z11T0ECB/aSyVXUysOFGLVfSrUxMPZy6jWWYGvT1+4P633f+R+ki1gT4WF/2KxZOYmli385ZgVhcR30mr4/G3HBcxi13zp7FnEeOsLlvBmI1PHN4C7Rsu3WL8sPndjXTd75kPkyjqnoMRrEEaYQE8ZRGYoeorwC+w=="
},
"identity_info": {
"id_doc_type": "IDENTIFICATION_TYPE_ID_CARD",
"identification_name": "pVd1HJ6zyvPedzGaV+X3qtmrq9bb9tPROvwia4ibL+F6mfjbzQIzfb3HHLEjZ4YiR/cJiCrZxnAqi+pjeKIEdkwzXRAI7FUhrfPK3SNjaBTEu9GmsugMIA9r3x887Q+ODuC8HH2nzAn7NGpE/e3yiHgWhk0ps5k5DP/2qIdGdONoDzZelrxCl/NWWNUyB93K9F+jC1JX2IMttdY+aQ6zBlw0xnOiNW6Hzy7UtC+xriudjD5APomty7/mYNxLMpRSvWKIjOv/69bDnuC4EL5Kz4jBHLiCyOb+tI0m2qhZ9evAM+Jv1z0NVa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==",
"identification_no": "AOZdYGISxo4y44/UgZ69bdu9X+tfMUJ9dl+LetjM45/zMbrYu+wWZ8gn4CTdo+D/m9MrPg+V4sm73oxqdQu/hj7aWyDl4GQtPXVdaztB9jVbVZh3QFzV+BEmytMNQp9dt1uWJktlfdDdLR3AMWyMB377xd+m9bSr/ioDTzagEcGe+vLYiKrzcroQv3OR0p3ppFYoQ3IfYeU/04S4t9rNFL+kyblK2FCCqQ11NdbbHoCrJc7NV4oASq6ZFonjTtgjjgKsadIKHXtb3JZKGZjduGdtkRJJp0/0eow96uY1Pk7Rq79Jtt7+I8juwEc4P4TG5xzchG/5IL9DBd+Z0zZXkw=="
}
},
"proof_medias": [
{
"proof_media_type": "WITHDRAWAL_APPLICATION",
"proof_media": "jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ"
}
],
"additional_materials": [
"jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ"
],
"remark": "特殊理由"
}

View File

@@ -0,0 +1,4 @@
{
"applyment_id": "X202410241010125346",
"out_request_no": "P202410241010125346"
}

View File

@@ -0,0 +1,24 @@
{
"applyment_id": "X202410241010125346",
"out_request_no": "P202410241010125346",
"cancel_state": "FUND_PROCESSING",
"cancel_state_description": "资金处理中",
"withdraw": "APPLY_WITHDRAW",
"withdraw_state": "WITHDRAW_PROCESSING",
"withdraw_state_description": "提现处理中",
"account_withdraw_result": [
{
"out_account_type": "BASIC_ACCOUNT",
"pay_state": "PAY_SUCCEED",
"state_description": "付款成功"
}
],
"modify_time": "2015-05-20T13:29:35+08:00",
"sub_mchid": "1900000109",
"account_info": [
{
"out_account_type": "BASIC_ACCOUNT",
"amount": 101
}
]
}

View File

@@ -0,0 +1,24 @@
{
"applyment_id": "X202410241010125346",
"out_request_no": "P202410241010125346",
"cancel_state": "FUND_PROCESSING",
"cancel_state_description": "资金处理中",
"withdraw": "APPLY_WITHDRAW",
"withdraw_state": "WITHDRAW_PROCESSING",
"withdraw_state_description": "提现处理中",
"account_withdraw_result": [
{
"out_account_type": "BASIC_ACCOUNT",
"pay_state": "PAY_SUCCEED",
"state_description": "付款成功"
}
],
"modify_time": "2015-05-20T13:29:35+08:00",
"sub_mchid": "1900000109",
"account_info": [
{
"out_account_type": "BASIC_ACCOUNT",
"amount": 101
}
]
}

View File

@@ -399,6 +399,77 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
} }
} }
[Fact(DisplayName = "测试用例:加密请求中的敏感数据([POST] /ecommerce/account/apply-cancel-withdraw")]
public async Task TestEncryptRequestSensitiveProperty_CreateEcommerceAccountCancelWithdrawApplicationRequest()
{
static Models.CreateEcommerceAccountCancelWithdrawApplicationRequest GenerateMockRequestModel()
{
return new Models.CreateEcommerceAccountCancelWithdrawApplicationRequest()
{
Payee = new Models.CreateEcommerceAccountCancelWithdrawApplicationRequest.Types.Payee()
{
BankAccount = new Models.CreateEcommerceAccountCancelWithdrawApplicationRequest.Types.Payee.Types.BankAccount()
{
AccountName = MOCK_PLAIN_STR,
AccountNumber = MOCK_PLAIN_STR
},
Identify = new Models.CreateEcommerceAccountCancelWithdrawApplicationRequest.Types.Payee.Types.Identify()
{
IdName = MOCK_PLAIN_STR,
IdNumber = MOCK_PLAIN_STR
}
}
};
}
static void AssertMockRequestModel(Models.CreateEcommerceAccountCancelWithdrawApplicationRequest request, Func<string, string> decryptor)
{
Assert.NotEqual(MOCK_PLAIN_STR, request.Payee!.BankAccount!.AccountName!);
Assert.NotEqual(MOCK_PLAIN_STR, request.Payee!.BankAccount!.AccountNumber!);
Assert.NotEqual(MOCK_PLAIN_STR, request.Payee!.Identify!.IdName!);
Assert.NotEqual(MOCK_PLAIN_STR, request.Payee!.Identify!.IdNumber!);
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Payee!.BankAccount!.AccountName!));
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Payee!.BankAccount!.AccountNumber!));
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Payee!.Identify!.IdName!));
Assert.Equal(MOCK_PLAIN_STR, decryptor.Invoke(request.Payee!.Identify!.IdNumber!));
Assert.Equal(MOCK_CERT_SN, request.WechatpaySerialNumber!, ignoreCase: true);
}
if (!string.IsNullOrEmpty(TestConfigs.WechatMerchantRSACertificatePrivateKey))
{
using (var client = CreateMockClientUseRSA(autoEncrypt: false))
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceAccountCancelWithdrawApplicationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
if (!string.IsNullOrEmpty(TestConfigs.WechatMerchantSM2CertificatePrivateKey))
{
using (var client = CreateMockClientUseSM2(autoEncrypt: false))
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceAccountCancelWithdrawApplicationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
[Fact(DisplayName = "测试用例:加密请求中的敏感数据([POST] /ecommerce/applyments")] [Fact(DisplayName = "测试用例:加密请求中的敏感数据([POST] /ecommerce/applyments")]
public async Task TestEncryptRequestSensitiveProperty_CreateEcommerceApplymentRequest() public async Task TestEncryptRequestSensitiveProperty_CreateEcommerceApplymentRequest()
{ {