feat(tenpayv2): 新增部分接口

This commit is contained in:
RHQYZ
2022-01-25 13:24:49 +08:00
committed by GitHub
parent 122cd5186c
commit 6458d08381
234 changed files with 11734 additions and 891 deletions

View File

@@ -0,0 +1,58 @@
using System;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
/// <summary>
/// 为 <see cref="WechatTenpayClient"/> 提供回调通知事件敏感数据解密的扩展方法。
/// </summary>
public static class WechatTenpayClientEventDecryptionExtensions
{
/// <summary>
/// <para>反序列化得到 <see cref="WechatTenpayEvent"/> 对象。</para>
/// </summary>
/// <param name="client"></param>
/// <param name="callbackXml"></param>
/// <returns></returns>
public static WechatTenpayEvent DeserializeEvent(this WechatTenpayClient client, string callbackXml)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (string.IsNullOrEmpty(callbackXml)) throw new ArgumentNullException(callbackXml);
string callbackJson = Utilities.XmlUtility.ConvertToJson(callbackXml);
return client.JsonSerializer.Deserialize<WechatTenpayEvent>(callbackJson);
}
/// <summary>
/// 返回序列化并解密事件数据中被加密的信息。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="client"></param>
/// <param name="callback"></param>
/// <returns></returns>
public static T DecryptEventRequestInfo<T>(this WechatTenpayClient client, WechatTenpayEvent callback)
where T : WechatTenpayEvent.Types.IDecryptedRequestInfo, new()
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (callback == null) throw new ArgumentNullException(nameof(callback));
string key = Utilities.MD5Utility.Hash(client.Credentials.MerchantSecret).ToLower();
string plainJson;
try
{
string plainXml = Utilities.AESUtility.DecryptWithECB(
encodingKey: Convert.ToBase64String(Encoding.UTF8.GetBytes(key)),
encodingCipherText: callback.EncryptedRequestInfo
);
plainJson = Utilities.XmlUtility.ConvertToJson(plainXml);
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayEventDecryptionException("Decrypt event resource failed. Please see the `InnerException` for more details.", ex);
}
return client.JsonSerializer.Deserialize<T>(plainJson);
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Linq;
using System.Xml;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
/// <summary>
/// 为 <see cref="WechatTenpayClient"/> 提供回调通知事件签名验证的扩展方法。
/// </summary>
public static class WechatTenpayClientEventVerificationExtensions
{
/// <summary>
/// <para>验证回调通知事件签名。</para>
/// </summary>
/// <param name="client"></param>
/// <param name="callbackBody">微信回调通知中请求正文。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackBody)
{
return VerifyEventSignature(client, callbackBody, out _);
}
/// <summary>
/// <para>验证回调通知事件签名。</para>
/// </summary>
/// <param name="client"></param>
/// <param name="callbackBody">微信回调通知中请求正文。</param>
/// <param name="error"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackBody, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (callbackBody == null) throw new ArgumentNullException(nameof(callbackBody));
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(callbackBody);
XmlNode xmlNode = xmlDocument.ChildNodes.OfType<XmlNode>().Single();
string? signType = xmlNode["sign_type"]?.InnerText;
string? expectedSign = xmlNode["sign"]?.InnerText;
xmlNode["sign"]?.RemoveAll();
string xml = xmlDocument.InnerXml;
string json = Utilities.XmlUtility.ConvertToJson(xml);
string signData = Utilities.JsonUtility.ParseToSortedQueryString(json);
string actualSign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
error = null;
return string.Equals(expectedSign, actualSign, StringComparison.OrdinalIgnoreCase);
}
catch (Exception ex)
{
error = new Exceptions.WechatTenpayEventVerificationException("Verify signature of event failed. Please see the `InnerException` for more details.", ex);
return false;
}
}
}
}

View File

@@ -0,0 +1,164 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecuteDepositExtensions
{
/// <summary>
/// <para>异步调用 [POST] /deposit/unifiedorder 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_7&index=1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_8&index=3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateDepositUnifiedOrderResponse> ExecuteCreateDepositUnifiedOrderAsync(this WechatTenpayClient client, Models.CreateDepositUnifiedOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "unifiedorder");
return await client.SendRequestWithXmlAsync<Models.CreateDepositUnifiedOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/micropay 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_1&index=6 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateDepositMicroPayResponse> ExecuteCreateDepositMicroPayAsync(this WechatTenpayClient client, Models.CreateDepositMicroPayRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "micropay");
return await client.SendRequestWithXmlAsync<Models.CreateDepositMicroPayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/facepay 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_0&index=5 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateDepositFacePayResponse> ExecuteCreateDepositFacePayAsync(this WechatTenpayClient client, Models.CreateDepositFacePayRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "facepay");
return await client.SendRequestWithXmlAsync<Models.CreateDepositFacePayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/orderquery 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_2&index=7 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetDepositOrderResponse> ExecuteGetDepositOrderAsync(this WechatTenpayClient client, Models.GetDepositOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "orderquery");
return await client.SendRequestWithXmlAsync<Models.GetDepositOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/reverse 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_3&index=8 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ReverseDepositOrderResponse> ExecuteReverseDepositOrderAsync(this WechatTenpayClient client, Models.ReverseDepositOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "reverse");
return await client.SendRequestWithXmlAsync<Models.ReverseDepositOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/consume 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_4&index=9 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ConsumeDepositResponse> ExecuteConsumeDepositAsync(this WechatTenpayClient client, Models.ConsumeDepositRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "consume");
return await client.SendRequestWithXmlAsync<Models.ConsumeDepositResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/refund 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_5&index=10 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateDepositRefundResponse> ExecuteCreateDepositRefundAsync(this WechatTenpayClient client, Models.CreateDepositRefundRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "refund");
return await client.SendRequestWithXmlAsync<Models.CreateDepositRefundResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /deposit/refundquery 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_6&index=11 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetDepositRefundResponse> ExecuteGetDepositRefundAsync(this WechatTenpayClient client, Models.GetDepositRefundRequest 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
.CreateRequest(request, HttpMethod.Post, "deposit", "refundquery");
return await client.SendRequestWithXmlAsync<Models.GetDepositRefundResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecuteFraudExtensions
{
/// <summary>
/// <para>异步调用 [POST] /risk/getpublickey 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_7&index=4 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetRiskPublicKeyResponse> ExecuteGetRiskPublicKeyAsync(this WechatTenpayClient client, Models.GetRiskPublicKeyRequest 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
.CreateRequest(request, HttpMethod.Post, "risk", "getpublickey");
flurlReq.Url = Url.Parse("https://fraud.mch.weixin.qq.com/risk/getpublickey");
return await client.SendRequestWithXmlAsync<Models.GetRiskPublicKeyResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePAPExtensions
{
/// <summary>
/// <para>异步调用 [POST] /papay/preentrustweb 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_2.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePAPPayPreEntrustWebResponse> ExecuteCreatePAPPayPreEntrustWebAsync(this WechatTenpayClient client, Models.CreatePAPPayPreEntrustWebRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
if (request.Timestamp == null)
request.Timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds();
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "papay", "preentrustweb");
return await client.SendRequestWithXmlAsync<Models.CreatePAPPayPreEntrustWebResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [GET] /papay/h5entrustweb 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_4.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePAPPayH5EntrustWebResponse> ExecuteCreatePAPPayH5EntrustWebAsync(this WechatTenpayClient client, Models.CreatePAPPayH5EntrustWebRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
if (request.Timestamp == null)
request.Timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds();
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Get, "papay", "h5entrustweb");
return await client.SendRequestWithXmlAsync<Models.CreatePAPPayH5EntrustWebResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/contractorder 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_5.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreateContractOrderResponse> ExecuteCreateContractOrderAsync(this WechatTenpayClient client, Models.CreateContractOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "contractorder");
return await client.SendRequestWithXmlAsync<Models.CreateContractOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/pappayapply 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_8.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ApplyPAPPayResponse> ExecuteApplyPAPPayAsync(this WechatTenpayClient client, Models.ApplyPAPPayRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "pappayapply");
return await client.SendRequestWithXmlAsync<Models.ApplyPAPPayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /papay/deletecontract 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_9.shtml </para>
/// <para>REF" https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_9.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DeletePAPPayContractResponse> ExecuteDeletePAPPayContractAsync(this WechatTenpayClient client, Models.DeletePAPPayContractRequest 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
.CreateRequest(request, HttpMethod.Post, "papay", "deletecontract");
return await client.SendRequestWithXmlAsync<Models.DeletePAPPayContractResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /papay/querycontract 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_7.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPAPPayContractResponse> ExecuteGetPAPPayContractAsync(this WechatTenpayClient client, Models.GetPAPPayContractRequest 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
.CreateRequest(request, HttpMethod.Post, "papay", "querycontract");
return await client.SendRequestWithXmlAsync<Models.GetPAPPayContractResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePAPPartnerExtensions
{
/// <summary>
/// <para>异步调用 [POST] /papay/partner/preentrustweb 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_2.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePAPPayPartnerPreEntrustWebResponse> ExecuteCreatePAPPayPartnerPreEntrustWebAsync(this WechatTenpayClient client, Models.CreatePAPPayPartnerPreEntrustWebRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
if (request.Timestamp == null)
request.Timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds();
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "papay", "partner", "preentrustweb");
return await client.SendRequestWithXmlAsync<Models.CreatePAPPayPartnerPreEntrustWebResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [GET] /papay/partner/h5entrustweb 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_4.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePAPPayPartnerH5EntrustWebResponse> ExecuteCreatePAPPayPartnerH5EntrustWebAsync(this WechatTenpayClient client, Models.CreatePAPPayPartnerH5EntrustWebRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
if (request.Timestamp == null)
request.Timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds();
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Get, "papay", "partner", "h5entrustweb")
.SetQueryParam("appid", request.AppId)
.SetQueryParam("mch_id", request.MerchantId)
.SetQueryParam("sub_appid", request.SubAppId)
.SetQueryParam("sub_mch_id", request.SubMerchantId)
.SetQueryParam("plan_id", request.PlanId)
.SetQueryParam("contract_code", request.ContractCode)
.SetQueryParam("request_serial", request.RequestSerialNumber)
.SetQueryParam("contract_display_account", request.ContractDisplayAccount)
.SetQueryParam("notify_url", request.NotifyUrl)
.SetQueryParam("version", request.Version)
.SetQueryParam("sign", request.Signature)
.SetQueryParam("timestamp", request.Timestamp)
.SetQueryParam("clientip", request.ClientIp)
.SetQueryParam("deviceid", request.DeviceId)
.SetQueryParam("mobile", request.UserMobile)
.SetQueryParam("email", request.UserEmail)
.SetQueryParam("qq", request.UserQQ)
.SetQueryParam("openid", request.OpenId)
.SetQueryParam("creid", request.IDCardNumber)
.SetQueryParam("outerid", request.OuterId)
.SetQueryParam("return_appid", request.ReturnAppId);
return await client.SendRequestWithXmlAsync<Models.CreatePAPPayPartnerH5EntrustWebResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/partner/pappayapply 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_8.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ApplyPAPPayPartnerResponse> ExecuteApplyPAPPayPartnerAsync(this WechatTenpayClient client, Models.ApplyPAPPayPartnerRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "partner", "pappayapply");
return await client.SendRequestWithXmlAsync<Models.ApplyPAPPayPartnerResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /papay/partner/querycontract 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_7.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPAPPayPartnerContractResponse> ExecuteGetPAPPayPartnerContractAsync(this WechatTenpayClient client, Models.GetPAPPayPartnerContractRequest 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
.CreateRequest(request, HttpMethod.Post, "papay", "partner", "querycontract");
return await client.SendRequestWithXmlAsync<Models.GetPAPPayPartnerContractResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -8,6 +8,34 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePayExtensions
{
/// <summary>
/// <para>异步调用 [POST] /pay/unifiedorder 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1&index=1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_1&index=1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_1&index=1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_1&index=1 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_1 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePayUnifiedOrderResponse> ExecuteCreatePayUnifiedOrderAsync(this WechatTenpayClient client, Models.CreatePayUnifiedOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "unifiedorder");
return await client.SendRequestWithXmlAsync<Models.CreatePayUnifiedOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/micropay 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1 </para>
@@ -28,5 +56,202 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
return await client.SendRequestWithXmlAsync<Models.CreatePayMicroPayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/orderquery 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_02 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_2&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_2&index=2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_02 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_2&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_2&index=2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_2 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPayOrderResponse> ExecuteGetPayOrderAsync(this WechatTenpayClient client, Models.GetPayOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "orderquery");
return await client.SendRequestWithXmlAsync<Models.GetPayOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /secapi/pay/reverse 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ReversePayOrderResponse> ExecuteReversePayOrderAsync(this WechatTenpayClient client, Models.ReversePayOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "secapi", "pay", "reverse");
return await client.SendRequestWithXmlAsync<Models.ReversePayOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/closeorder 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_3&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_3&index=3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_3&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_3&index=3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter4_6.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_17.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ClosePayOrderResponse> ExecuteClosePayOrderAsync(this WechatTenpayClient client, Models.ClosePayOrderRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "closeorder");
return await client.SendRequestWithXmlAsync<Models.ClosePayOrderResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /secapi/pay/refund 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_4&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_4&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_4&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_4&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter4_3.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_13.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=9_4&index=5&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePayRefundResponse> ExecuteCreatePayRefundAsync(this WechatTenpayClient client, Models.CreatePayRefundRequest 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
.CreateRequest(request, HttpMethod.Post, "secapi", "pay", "refund");
return await client.SendRequestWithXmlAsync<Models.CreatePayRefundResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/refundquery 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_5&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_5&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_5&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_5&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter4_4.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_14.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=9_5&index=6&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPayRefundResponse> ExecuteGetPayRefundAsync(this WechatTenpayClient client, Models.GetPayRefundRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "refundquery");
return await client.SendRequestWithXmlAsync<Models.GetPayRefundResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/downloadbill 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_6&index=8 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_6&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_6&index=8 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_6&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter4_1.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_11.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=9_6&index=3&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DownloadPayBillResponse> ExecuteDownloadPayBillAsync(this WechatTenpayClient client, Models.DownloadPayBillRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "downloadbill");
return await client.SendRequestWithXmlAsync<Models.DownloadPayBillResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /pay/downloadfundflow 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_18&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_18&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_18&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_18&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_18&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_18&index=7 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DownloadPayFundFlowResponse> ExecuteDownloadPayFundFlowAsync(this WechatTenpayClient client, Models.DownloadPayFundFlowRequest 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
.CreateRequest(request, HttpMethod.Post, "pay", "downloadfundflow");
return await client.SendRequestWithXmlAsync<Models.DownloadPayFundFlowResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -11,6 +11,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
/// <summary>
/// <para>异步调用 [POST] /payitil/report 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_14&index=8 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_8&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_8&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_8&index=10 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_8&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_8&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_14&index=7 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_8 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_8 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_8&index=10 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/H5_sl.php?chapter=9_8&index=9 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_8&index=9 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>

View File

@@ -0,0 +1,93 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePayMarketingTransfersRedPackExtensions
{
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/sendredpack 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=13_4&index=3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.SendPayMarketingTransfersRedPackResponse> ExecuteSendPayMarketingTransfersRedPackAsync(this WechatTenpayClient client, Models.SendPayMarketingTransfersRedPackRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "sendredpack");
return await client.SendRequestWithXmlAsync<Models.SendPayMarketingTransfersRedPackResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/sendgroupredpack 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=13_5&index=4 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.SendPayMarketingTransfersGroupRedPackResponse> ExecuteSendPayMarketingTransfersGroupRedPackAsync(this WechatTenpayClient client, Models.SendPayMarketingTransfersGroupRedPackRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "sendgroupredpack");
return await client.SendRequestWithXmlAsync<Models.SendPayMarketingTransfersGroupRedPackResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/sendminiprogramhb 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_xcx.php?chapter=18_2&index=3 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=18_2&index=3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.SendPayMarketingTransfersMiniProgramRedPackResponse> ExecuteSendPayMarketingTransfersMiniProgramRedPackAsync(this WechatTenpayClient client, Models.SendPayMarketingTransfersMiniProgramRedPackRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "sendminiprogramhb");
return await client.SendRequestWithXmlAsync<Models.SendPayMarketingTransfersMiniProgramRedPackResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/gethbinfo 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_6&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_xcx.php?chapter=18_6&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=13_6&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=18_6&index=5 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPayMarketingTransfersRedPackInfoResponse> ExecuteGetPayMarketingTransfersRedPackInfoAsync(this WechatTenpayClient client, Models.GetPayMarketingTransfersRedPackInfoRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "gethbinfo");
return await client.SendRequestWithXmlAsync<Models.GetPayMarketingTransfersRedPackInfoResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePayMarketingTransfersTransferExtensions
{
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/promotion/transfers 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePayMarketingTransfersPromotionTransferResponse> ExecuteCreatePayMarketingTransfersPromotionTransferAsync(this WechatTenpayClient client, Models.CreatePayMarketingTransfersPromotionTransferRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "promotion", "transfers");
return await client.SendRequestWithXmlAsync<Models.CreatePayMarketingTransfersPromotionTransferResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /mmpaymkttransfers/gettransferinfo 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPayMarketingTransfersTransferInfoResponse> ExecuteGetPayMarketingTransfersTransferInfoAsync(this WechatTenpayClient client, Models.GetPayMarketingTransfersTransferInfoRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaymkttransfers", "gettransferinfo");
return await client.SendRequestWithXmlAsync<Models.GetPayMarketingTransfersTransferInfoResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecutePayServicePartnerTransfersExtensions
{
/// <summary>
/// <para>异步调用 [POST] /mmpaysptrans/pay_bank 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_2 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.CreatePayServicePartnerTransfersPayToBankResponse> ExecuteCreatePayServicePartnerTransfersPayToBankAsync(this WechatTenpayClient client, Models.CreatePayServicePartnerTransfersPayToBankRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaysptrans", "pay_bank");
return await client.SendRequestWithXmlAsync<Models.CreatePayServicePartnerTransfersPayToBankResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /mmpaysptrans/query_bank 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_3 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetPayServicePartnerTransfersPayToBankInfoResponse> ExecuteGetPayServicePartnerTransfersPayToBankInfoAsync(this WechatTenpayClient client, Models.GetPayServicePartnerTransfersPayToBankInfoRequest 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
.CreateRequest(request, HttpMethod.Post, "mmpaysptrans", "query_bank");
return await client.SendRequestWithXmlAsync<Models.GetPayServicePartnerTransfersPayToBankInfoResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecuteRiskExtensions
{
/// <summary>
/// <para>异步调用 [POST] /risk/getviolation 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/mch_bank.php?chapter=9_28&index=1&p=902 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.QueryRiskViolationResponse> ExecuteQueryRiskViolationAsync(this WechatTenpayClient client, Models.QueryRiskViolationRequest 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
.CreateRequest(request, HttpMethod.Post, "risk", "getviolation");
return await client.SendRequestWithXmlAsync<Models.QueryRiskViolationResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecuteSubMerchantExtensions
{
/// <summary>
/// <para>异步调用 [POST] /secapi/mch/addsubdevconfig 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/mch_bank.php?chapter=9_24_2&index=1&p=901 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/mch_bank.php?chapter=9_24_3&index=2&p=901 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.AddSubMerchantDevelopConfigResponse> ExecuteAddSubMerchantDevelopConfigAsync(this WechatTenpayClient client, Models.AddSubMerchantDevelopConfigRequest 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
.CreateRequest(request, HttpMethod.Post, "secapi", "mch", "addsubdevconfig");
return await client.SendRequestWithXmlAsync<Models.AddSubMerchantDevelopConfigResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /secapi/mch/querysubdevconfig 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/mch_bank.php?chapter=9_25&index=3&p=901 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetSubMerchantDevelopConfigResponse> ExecuteGetSubMerchantDevelopConfigAsync(this WechatTenpayClient client, Models.GetSubMerchantDevelopConfigRequest 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
.CreateRequest(request, HttpMethod.Post, "secapi", "mch", "querysubdevconfig");
return await client.SendRequestWithXmlAsync<Models.GetSubMerchantDevelopConfigResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -27,5 +27,25 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
return await client.SendRequestWithXmlAsync<Models.ToolsAuthCodeToOpenIdResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /tools/shorturl 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_9&index=10 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_9 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ToolsShortUrlResponse> ExecuteToolsShortUrlAsync(this WechatTenpayClient client, Models.ToolsShortUrlRequest 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
.CreateRequest(request, HttpMethod.Post, "tools", "shorturl");
return await client.SendRequestWithXmlAsync<Models.ToolsShortUrlResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
public static class WechatTenpayClientExecuteVehiclePartnerExtensions
{
/// <summary>
/// <para>异步调用 [POST] /vehicle/partnerpay/notification 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_992&index=1&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.NotifyVehiclePartnerPayResponse> ExecuteNotifyVehiclePartnerPayAsync(this WechatTenpayClient client, Models.NotifyVehiclePartnerPayRequest 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
.CreateRequest(request, HttpMethod.Post, "vehicle", "partnerpay", "notification");
return await client.SendRequestWithXmlAsync<Models.NotifyVehiclePartnerPayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /vehicle/partnerpay/payapply 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_982&index=2&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.ApplyVehiclePartnerPayResponse> ExecuteApplyVehiclePartnerPayAsync(this WechatTenpayClient client, Models.ApplyVehiclePartnerPayRequest 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
.CreateRequest(request, HttpMethod.Post, "vehicle", "partnerpay", "payapply");
return await client.SendRequestWithXmlAsync<Models.ApplyVehiclePartnerPayResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /vehicle/partnerpay/querystate 接口。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_93&index=9&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.GetVehiclePartnerPayStateResponse> ExecuteGetVehiclePartnerPayStateAsync(this WechatTenpayClient client, Models.GetVehiclePartnerPayStateRequest 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
.CreateRequest(request, HttpMethod.Post, "vehicle", "partnerpay", "querystate");
return await client.SendRequestWithXmlAsync<Models.GetVehiclePartnerPayStateResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@@ -0,0 +1,472 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Web;
using Flurl;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
/// <summary>
/// 为 <see cref="WechatTenpayClient"/> 提供调起支付签名的扩展方法。
/// </summary>
public static class WechatTenpayClientParameterExtensions
{
private const string BASE_URL = "https://api.mch.weixin.qq.com";
/// <summary>
/// <para>生成客户端小程序调起领取红包所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_xcx.php?chapter=18_3&index=4 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=18_3&index=4 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="packageString"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForJsapiSendBusinessRedPack(this WechatTenpayClient client, string packageString)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (packageString is null) throw new ArgumentNullException(nameof(packageString));
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string signType = Constants.SignTypes.MD5;
string signData = $"timeStamp={timestamp}&nonceStr={nonce}&package={packageString}&signType={signType}";
string sign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{
{ "timeStamp", timestamp },
{ "nonceStr", nonce },
{ "package", HttpUtility.UrlEncode(packageString) },
{ "signType", signType },
{ "paySign", sign }
});
}
/// <summary>
/// <para>生成客户端 JSAPI 调起支付所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_7&index=6 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=7_7&index=2&p=27 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="prepayId"></param>
/// <param name="signType"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForJsapiGetBrandPayRequest(this WechatTenpayClient client, string appId, string prepayId, string? signType)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (prepayId is null) throw new ArgumentNullException(nameof(prepayId));
signType = signType ?? Constants.SignTypes.MD5;
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string package = $"prepay_id={prepayId}";
string signData = $"appId={appId}&timeStamp={timestamp}&nonceStr={nonce}&package={package}&signType={signType}";
string sign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{
{ "appId", appId },
{ "timeStamp", timestamp },
{ "nonceStr", nonce },
{ "package", package },
{ "signType", signType },
{ "paySign", sign }
});
}
/// <summary>
/// <para>生成客户端 App 调起支付所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_12&index=2 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="merchantId"></param>
/// <param name="appId"></param>
/// <param name="prepayId"></param>
/// <param name="signType"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForAppGetBrandPayRequest(this WechatTenpayClient client, string merchantId, string appId, string prepayId, string? signType)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (prepayId is null) throw new ArgumentNullException(nameof(prepayId));
signType = signType ?? Constants.SignTypes.MD5;
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string partnerId = merchantId;
string package = "Sign=WXPay";
string signData = $"appid={appId}&timestamp={timestamp}&noncestr={nonce}&package={package}&partnerid={partnerId}&prepayid={prepayId}&signType={signType}";
string sign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{
{ "appid", appId },
{ "partnerid", partnerId },
{ "prepayid", prepayId },
{ "package", package },
{ "noncestr", nonce },
{ "timestamp", timestamp },
{ "sign", sign }
});
}
/// <summary>
/// <para>生成客户端 App 调起支付所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_12&index=2 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/deposit_sl.php?chapter=27_9&index=4 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="prepayId"></param>
/// <param name="signType"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForAppGetBrandPayRequest(this WechatTenpayClient client, string appId, string prepayId, string? signType)
{
return GenerateParametersForAppGetBrandPayRequest(client, merchantId: client.Credentials.MerchantId, appId: appId, prepayId: prepayId, signType: signType);
}
/// <summary>
/// <para>生成客户端小程序调起支付所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5 </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=7_7&index=5 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="prepayId"></param>
/// <param name="signType"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForMiniProgramRequestPayment(this WechatTenpayClient client, string appId, string prepayId, string? signType)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (prepayId is null) throw new ArgumentNullException(nameof(prepayId));
signType = signType ?? Constants.SignTypes.MD5;
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string package = $"prepay_id={prepayId}";
string signData = $"appId={appId}&timeStamp={timestamp}&nonceStr={nonce}&package={package}&signType={signType}";
string sign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{
{ "timeStamp", timestamp },
{ "nonceStr", nonce },
{ "package", package },
{ "signType", signType },
{ "paySign", sign }
});
}
/// <summary>
/// <para>生成客户端公众号唤起微信委托代扣的 URL。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_1.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="planId"></param>
/// <param name="contractCode"></param>
/// <param name="requestSerialNumber"></param>
/// <param name="contractDisplayAccount"></param>
/// <param name="notifyUrl"></param>
/// <param name="requireReturnWeb"></param>
/// <returns></returns>
public static string GenerateParameterizedUrlForMediaPlatformPAPPayEntrustWeb(this WechatTenpayClient client, string appId, int planId, string contractCode, long requestSerialNumber, string contractDisplayAccount, string notifyUrl, bool? requireReturnWeb)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string version = "1.0";
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "plan_id", planId.ToString() },
{ "contract_code", contractCode },
{ "request_serial", requestSerialNumber.ToString() },
{ "contract_display_account", contractDisplayAccount },
{ "notify_url", notifyUrl },
{ "version", version },
{ "timestamp", timestamp },
{ "return_web", requireReturnWeb.HasValue ? requireReturnWeb.Value ? "1" : "0" : null }
};
string sign = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, Constants.SignTypes.MD5);
return new Url(BASE_URL)
.AppendPathSegments("papay", "entrustweb")
.SetQueryParams(paramsMap)
.SetQueryParam("sign", sign)
.ToString();
}
/// <summary>
/// <para>生成客户端公众号唤起微信委托代扣的 URL。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_1.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="planId"></param>
/// <param name="contractCode"></param>
/// <param name="requestSerialNumber"></param>
/// <param name="contractDisplayAccount"></param>
/// <param name="notifyUrl"></param>
/// <param name="requireReturnWeb"></param>
/// <returns></returns>
public static string GenerateParameterizedUrlForMediaPlatformPAPPayPartnerEntrustWeb(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, int planId, string contractCode, long requestSerialNumber, string contractDisplayAccount, string notifyUrl, bool? requireReturnWeb)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string version = "1.0";
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "sub_appid", subAppId },
{ "sub_mch_id", subMerchantId },
{ "plan_id", planId.ToString() },
{ "contract_code", contractCode },
{ "request_serial", requestSerialNumber.ToString() },
{ "contract_display_account", contractDisplayAccount },
{ "notify_url", notifyUrl },
{ "version", version },
{ "timestamp", timestamp },
{ "return_web", requireReturnWeb.HasValue ? requireReturnWeb.Value ? "1" : "0" : null }
};
string sign = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, Constants.SignTypes.MD5);
return new Url(BASE_URL)
.AppendPathSegments("papay", "partner", "entrustweb")
.SetQueryParams(paramsMap)
.SetQueryParam("sign", sign)
.ToString();
}
/// <summary>
/// <para>生成客户端小程序唤起微信委托代扣页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_3.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="planId"></param>
/// <param name="contractCode"></param>
/// <param name="requestSerialNumber"></param>
/// <param name="contractDisplayAccount"></param>
/// <param name="notifyUrl"></param>
/// <param name="outerId"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForMiniProgramPAPPayEntrust(this WechatTenpayClient client, string appId, int planId, string contractCode, long requestSerialNumber, string contractDisplayAccount, string notifyUrl, string? outerId)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "plan_id", planId.ToString() },
{ "contract_code", contractCode },
{ "request_serial", requestSerialNumber.ToString() },
{ "contract_display_account", contractDisplayAccount },
{ "notify_url", notifyUrl },
{ "timestamp", timestamp },
{ "outerid", outerId }
};
paramsMap["sign"] = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, Constants.SignTypes.MD5);
return new ReadOnlyDictionary<string, string>(paramsMap!);
}
/// <summary>
/// <para>生成客户端小程序唤起微信委托代扣页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter5_3.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="planId"></param>
/// <param name="contractCode"></param>
/// <param name="requestSerialNumber"></param>
/// <param name="contractDisplayAccount"></param>
/// <param name="notifyUrl"></param>
/// <param name="clientIp"></param>
/// <param name="deviceId"></param>
/// <param name="userMobile"></param>
/// <param name="userEmail"></param>
/// <param name="userQQ"></param>
/// <param name="openId"></param>
/// <param name="idCardNumber"></param>
/// <param name="outerId"></param>
/// <returns></returns>
public static IDictionary<string, string> GenerateParametersForMiniProgramPAPPayEntrust(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, int planId, string contractCode, long requestSerialNumber, string contractDisplayAccount, string notifyUrl, string clientIp, string? deviceId, string? userMobile, string? userEmail, string? userQQ, string? openId, string? idCardNumber, string? outerId)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "sub_appid", subAppId },
{ "sub_mch_id", subMerchantId },
{ "plan_id", planId.ToString() },
{ "contract_code", contractCode },
{ "request_serial", requestSerialNumber.ToString() },
{ "contract_display_account", contractDisplayAccount },
{ "notify_url", notifyUrl },
{ "timestamp", timestamp },
{ "clientip", clientIp },
{ "deviceid", deviceId },
{ "mobile", userMobile },
{ "email", userEmail },
{ "qq", userQQ },
{ "openid", openId },
{ "creid", idCardNumber },
{ "outerid", outerId }
};
paramsMap["sign"] = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, Constants.SignTypes.MD5);
return new ReadOnlyDictionary<string, string>(paramsMap!);
}
/// <summary>
/// <para>生成客户端小程序唤起开通车主服务页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_101&index=10&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="openId"></param>
/// <param name="subOpenId"></param>
/// <param name="tradeScene"></param>
/// <param name="plateNumber"></param>
/// <param name="channelType"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IDictionary<string, string> GenerateParametersForMiniProgramVehiclePAPPayPartnerAuth(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, string? openId, string? subOpenId, string tradeScene, string? plateNumber, string? channelType)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string nonce = Guid.NewGuid().ToString("N");
string signType = Constants.SignTypes.HMAC_SHA256;
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "nonce_str", nonce },
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "sub_appid", subAppId },
{ "sub_mch_id", subMerchantId },
{ "sign_type", signType },
{ "openid", openId },
{ "sub_openid", subOpenId },
{ "trade_scene", tradeScene },
{ "plate_number", plateNumber },
{ "channel_type", channelType }
};
paramsMap["sign"] = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(paramsMap!);
}
/// <summary>
/// <para>生成客户端 App 唤起开通车主服务页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_101&index=10&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="openId"></param>
/// <param name="subOpenId"></param>
/// <param name="tradeScene"></param>
/// <param name="plateNumber"></param>
/// <param name="channelType"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IDictionary<string, string> GenerateParametersForAppVehiclePAPPayPartnerAuth(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, string? openId, string? subOpenId, string tradeScene, string? plateNumber, string? channelType)
{
if (client is null) throw new ArgumentNullException(nameof(client));
return GenerateParametersForMiniProgramVehiclePAPPayPartnerAuth(
client,
appId: appId,
subMerchantId: subMerchantId,
subAppId: subAppId,
openId: openId,
subOpenId: subOpenId,
tradeScene: tradeScene,
plateNumber: plateNumber,
channelType: channelType
);
}
/// <summary>
/// <para>生成客户端小程序唤起免密支付升级无感支付页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_102&index=11&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="openId"></param>
/// <param name="plateNumber"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IDictionary<string, string> GenerateParametersForMiniProgramVehiclePAPPayPartnerNoSensePayment(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, string? openId, string? plateNumber)
{
if (client is null) throw new ArgumentNullException(nameof(client));
string nonce = Guid.NewGuid().ToString("N");
string signType = Constants.SignTypes.HMAC_SHA256;
IDictionary<string, string?> paramsMap = new Dictionary<string, string?>()
{
{ "nonce_str", nonce },
{ "appid", appId },
{ "mch_id", client.Credentials.MerchantId },
{ "sub_appid", subAppId },
{ "sub_mch_id", subMerchantId },
{ "sign_type", signType },
{ "openid", openId },
{ "plate_number", plateNumber }
};
paramsMap["sign"] = Utilities.RequestSigner.Sign(paramsMap, client.Credentials.MerchantSecret, signType);
return new ReadOnlyDictionary<string, string>(paramsMap!);
}
/// <summary>
/// <para>生成客户端 App 唤起免密支付升级无感支付页面所需的参数字典。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/api/vehicle_v2_sl.php?chapter=20_101&index=10&p=202 </para>
/// </summary>
/// <param name="client"></param>
/// <param name="appId"></param>
/// <param name="subMerchantId"></param>
/// <param name="subAppId"></param>
/// <param name="openId"></param>
/// <param name="plateNumber"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IDictionary<string, string> GenerateParametersForAppVehiclePAPPayPartnerNoSensePayment(this WechatTenpayClient client, string appId, string subMerchantId, string? subAppId, string? openId, string? plateNumber)
{
if (client is null) throw new ArgumentNullException(nameof(client));
return GenerateParametersForMiniProgramVehiclePAPPayPartnerNoSensePayment(
client,
appId: appId,
subMerchantId: subMerchantId,
subAppId: subAppId,
openId: openId,
plateNumber: plateNumber
);
}
}
}