From f93d6139d1dfd539bd61bb181441f17bd6c2dbf0 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sun, 27 Aug 2023 18:53:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(wxapi):=20=E6=96=B0=E5=A2=9E=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E8=99=9A=E6=8B=9F=E6=94=AF=E4=BB=98=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/WechatApi/README.md | 9 +- .../Events/XPay/XPayCoinPayNotifyEvent.cs | 119 ++++++ .../XPay/XPayGoodsDeliverNotifyEvent.cs | 127 ++++++ ...WechatApiClientExecuteWxaGameExtensions.cs | 8 +- .../WechatApiClientExecuteXPayExtensions.cs | 364 ++++++++++++++++++ .../Abstractions/WxaGameRequestBase.cs | 2 +- .../Models/WxaGame/WxaGameCancelPayRequest.cs | 2 +- .../Models/WxaGame/WxaGamePayResponse.cs | 2 +- .../XPay/Abstractions/XPayRequestBase.cs | 56 +++ .../XPay/XPayCancelCurrencyPayRequest.cs | 34 ++ .../XPay/XPayCancelCurrencyPayResponse.cs | 15 + .../XPay/XPayCreateWithdrawOrderRequest.cs | 29 ++ .../XPay/XPayCreateWithdrawOrderResponse.cs | 22 ++ .../Models/XPay/XPayCurrencyPayRequest.cs | 41 ++ .../Models/XPay/XPayCurrencyPayResponse.cs | 29 ++ .../Models/XPay/XPayDownloadBillRequest.cs | 27 ++ .../Models/XPay/XPayDownloadBillResponse.cs | 15 + .../XPay/XPayNotifyProvideGoodsRequest.cs | 27 ++ .../XPay/XPayNotifyProvideGoodsResponse.cs | 9 + .../Models/XPay/XPayPresentCurrencyRequest.cs | 27 ++ .../XPay/XPayPresentCurrencyResponse.cs | 29 ++ .../Models/XPay/XPayQueryOrderRequest.cs | 27 ++ .../Models/XPay/XPayQueryOrderResponse.cs | 154 ++++++++ .../XPay/XPayQueryPublishGoodsRequest.cs | 13 + .../XPay/XPayQueryPublishGoodsResponse.cs | 49 +++ .../XPay/XPayQueryUploadGoodsRequest.cs | 13 + .../XPay/XPayQueryUploadGoodsResponse.cs | 77 ++++ .../XPay/XPayQueryUserBalanceRequest.cs | 13 + .../XPay/XPayQueryUserBalanceResponse.cs | 59 +++ .../XPay/XPayQueryWithdrawOrderRequest.cs | 20 + .../XPay/XPayQueryWithdrawOrderResponse.cs | 60 +++ .../Models/XPay/XPayRefundOrderRequest.cs | 69 ++++ .../Models/XPay/XPayRefundOrderResponse.cs | 36 ++ .../XPay/XPayStartPublishGoodsRequest.cs | 35 ++ .../XPay/XPayStartPublishGoodsResponse.cs | 9 + .../XPay/XPayStartUploadGoodsRequest.cs | 63 +++ .../XPay/XPayStartUploadGoodsResponse.cs | 9 + .../Settings/Credentials.cs | 6 + .../WechatApiClientOptions.cs | 5 + .../XPay/XPayCoinPayNotifyEvent.json | 21 + .../XPay/XPayGoodsDeliverNotifyEvent.json | 22 ++ .../XPay/XPayCancelCurrencyPayRequest.json | 9 + .../XPay/XPayCancelCurrencyPayResponse.json | 5 + .../XPay/XPayCreateWithdrawOrderRequest.json | 5 + .../XPay/XPayCreateWithdrawOrderResponse.json | 6 + .../XPay/XPayCurrencyPayRequest.json | 10 + .../XPay/XPayCurrencyPayResponse.json | 7 + .../XPay/XPayDownloadBillRequest.json | 4 + .../XPay/XPayDownloadBillResponse.json | 5 + .../XPay/XPayNotifyProvideGoodsRequest.json | 5 + .../XPay/XPayPresentCurrencyRequest.json | 7 + .../XPay/XPayPresentCurrencyResponse.json | 7 + .../XPay/XPayQueryOrderRequest.json | 6 + .../XPay/XPayQueryOrderResponse.json | 25 ++ .../XPay/XPayQueryPublishGoodsRequest.json | 3 + .../XPay/XPayQueryPublishGoodsResponse.json | 12 + .../XPay/XPayQueryUploadGoodsRequest.json | 3 + .../XPay/XPayQueryUploadGoodsResponse.json | 16 + .../XPay/XPayQueryUserBalanceRequest.json | 5 + .../XPay/XPayQueryUserBalanceResponse.json | 11 + .../XPay/XPayQueryWithdrawOrderRequest.json | 4 + .../XPay/XPayQueryWithdrawOrderResponse.json | 11 + .../XPay/XPayRefundOrderRequest.json | 12 + .../XPay/XPayRefundOrderResponse.json | 8 + .../XPay/XPayStartPublishGoodsRequest.json | 8 + .../XPay/XPayStartUploadGoodsRequest.json | 12 + .../TestCase_RequestSignatureTests.cs | 37 +- 67 files changed, 1980 insertions(+), 16 deletions(-) create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayCoinPayNotifyEvent.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayGoodsDeliverNotifyEvent.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteXPayExtensions.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/Abstractions/XPayRequestBase.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsResponse.cs create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayCoinPayNotifyEvent.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayGoodsDeliverNotifyEvent.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayNotifyProvideGoodsRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderResponse.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartPublishGoodsRequest.json create mode 100644 test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartUploadGoodsRequest.json diff --git a/docs/WechatApi/README.md b/docs/WechatApi/README.md index 7a34ca68..cef611fb 100644 --- a/docs/WechatApi/README.md +++ b/docs/WechatApi/README.md @@ -38,10 +38,11 @@ var options = new WechatApiClientOptions() AppSecret = "微信 AppSecret", ImmeDeliveryAppKey = "即时配送相关服务 AppKey,不用则不填", ImmeDeliveryAppSecret = "即时配送相关服务 AppSecret,不用则不填", - MidasOfferId = "米大师(虚拟支付 1.0)相关服务 OfferId,不用则不填", - MidasOfferIdV2 = "米大师(虚拟支付 2.0)相关服务 OfferId,不用则不填", - MidasAppKey = "米大师(虚拟支付 1.0)相关服务 AppKey,不用则不填", - MidasAppKeyV2 = "米大师(虚拟支付 2.0)相关服务 AppKey,不用则不填" + VirtualPaymentAppKey = "虚拟支付相关服务 AppKey,不用则不填", + MidasOfferId = "米大师 1.0 相关服务 OfferId,不用则不填", + MidasAppKey = "米大师 1.0 相关服务 AppKey,不用则不填", + MidasOfferIdV2 = "米大师 2.0 相关服务 OfferId,不用则不填", + MidasAppKeyV2 = "米大师 2.0 相关服务 AppKey,不用则不填" }; var client = new WechatApiClient(options); ``` diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayCoinPayNotifyEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayCoinPayNotifyEvent.cs new file mode 100644 index 00000000..3b8b8dde --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayCoinPayNotifyEvent.cs @@ -0,0 +1,119 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Events +{ + /// + /// 表示 EVENT.xpay_coin_pay_notify 事件的数据。 + /// https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html + /// + public class XPayCoinPayNotifyEvent : WechatApiEvent, WechatApiEvent.Serialization.IJsonSerializable, WechatApiEvent.Serialization.IXmlSerializable + { + public static class Types + { + public class WechatpayInfo + { + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("MchOrderNo")] + [System.Text.Json.Serialization.JsonPropertyName("MchOrderNo")] + [System.Xml.Serialization.XmlElement("MchOrderNo")] + public string MerchantOrderNumber { get; set; } = default!; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("TransactionId")] + [System.Text.Json.Serialization.JsonPropertyName("TransactionId")] + [System.Xml.Serialization.XmlElement("TransactionId")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置支付时间戳。 + /// + [Newtonsoft.Json.JsonProperty("PaidTime")] + [System.Text.Json.Serialization.JsonPropertyName("PaidTime")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("PaidTime")] + public long PayTimestamp { get; set; } + } + + public class CoinInfo + { + /// + /// 获取或设置数量。 + /// + [Newtonsoft.Json.JsonProperty("Quantity")] + [System.Text.Json.Serialization.JsonPropertyName("Quantity")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("Quantity")] + public int Quantity { get; set; } + + /// + /// 获取或设置原始价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("OrigPrice")] + [System.Text.Json.Serialization.JsonPropertyName("OrigPrice")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("OrigPrice")] + public int OriginalPrice { get; set; } + + /// + /// 获取或设置实付价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("ActualPrice")] + [System.Text.Json.Serialization.JsonPropertyName("ActualPrice")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("ActualPrice")] + public int ActualPrice { get; set; } + + /// + /// 获取或设置透传信息。 + /// + [Newtonsoft.Json.JsonProperty("Attach")] + [System.Text.Json.Serialization.JsonPropertyName("Attach")] + [System.Xml.Serialization.XmlElement("Attach", IsNullable = true)] + public string? Attachment { get; set; } + } + } + + /// + /// 获取或设置用户 OpenId。 + /// + [Newtonsoft.Json.JsonProperty("OpenId")] + [System.Text.Json.Serialization.JsonPropertyName("OpenId")] + [System.Xml.Serialization.XmlElement("OpenId")] + public string OpenId { get; set; } = default!; + + /// + /// 获取或设置业务订单号。 + /// + [Newtonsoft.Json.JsonProperty("OutTradeNo")] + [System.Text.Json.Serialization.JsonPropertyName("OutTradeNo")] + [System.Xml.Serialization.XmlElement("OutTradeNo")] + public string OutTradeNumber { get; set; } = default!; + + /// + /// 获取或设置虚拟支付环境。 + /// + [Newtonsoft.Json.JsonProperty("Env")] + [System.Text.Json.Serialization.JsonPropertyName("Env")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("Env")] + public int Environment { get; set; } + + /// + /// 获取或设置微信支付信息。 + /// + [Newtonsoft.Json.JsonProperty("WeChatPayInfo")] + [System.Text.Json.Serialization.JsonPropertyName("WeChatPayInfo")] + [System.Xml.Serialization.XmlElement("WeChatPayInfo", IsNullable = true)] + public Types.WechatpayInfo? WechatpayInfo { get; set; } + + /// + /// 获取或设置代币信息。 + /// + [Newtonsoft.Json.JsonProperty("CoinInfo")] + [System.Text.Json.Serialization.JsonPropertyName("CoinInfo")] + [System.Xml.Serialization.XmlElement("CoinInfo", IsNullable = true)] + public Types.CoinInfo? CoinInfo { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayGoodsDeliverNotifyEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayGoodsDeliverNotifyEvent.cs new file mode 100644 index 00000000..ec034e7b --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Events/XPay/XPayGoodsDeliverNotifyEvent.cs @@ -0,0 +1,127 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Events +{ + /// + /// 表示 EVENT.xpay_goods_deliver_notify 事件的数据。 + /// https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html + /// + public class XPayGoodsDeliverNotifyEvent : WechatApiEvent, WechatApiEvent.Serialization.IJsonSerializable, WechatApiEvent.Serialization.IXmlSerializable + { + public static class Types + { + public class WechatpayInfo + { + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("MchOrderNo")] + [System.Text.Json.Serialization.JsonPropertyName("MchOrderNo")] + [System.Xml.Serialization.XmlElement("MchOrderNo")] + public string MerchantOrderNumber { get; set; } = default!; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("TransactionId")] + [System.Text.Json.Serialization.JsonPropertyName("TransactionId")] + [System.Xml.Serialization.XmlElement("TransactionId")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置支付时间戳。 + /// + [Newtonsoft.Json.JsonProperty("PaidTime")] + [System.Text.Json.Serialization.JsonPropertyName("PaidTime")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("PaidTime")] + public long PayTimestamp { get; set; } + } + + public class GoodsInfo + { + /// + /// 获取或设置道具 ID。 + /// + [Newtonsoft.Json.JsonProperty("ProductId")] + [System.Text.Json.Serialization.JsonPropertyName("ProductId")] + [System.Xml.Serialization.XmlElement("ProductId")] + public string ProductId { get; set; } = default!; + + /// + /// 获取或设置数量。 + /// + [Newtonsoft.Json.JsonProperty("Quantity")] + [System.Text.Json.Serialization.JsonPropertyName("Quantity")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("Quantity")] + public int Quantity { get; set; } + + /// + /// 获取或设置原始价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("OrigPrice")] + [System.Text.Json.Serialization.JsonPropertyName("OrigPrice")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("OrigPrice")] + public int OriginalPrice { get; set; } + + /// + /// 获取或设置实付价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("ActualPrice")] + [System.Text.Json.Serialization.JsonPropertyName("ActualPrice")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("ActualPrice")] + public int ActualPrice { get; set; } + + /// + /// 获取或设置透传信息。 + /// + [Newtonsoft.Json.JsonProperty("Attach")] + [System.Text.Json.Serialization.JsonPropertyName("Attach")] + [System.Xml.Serialization.XmlElement("Attach", IsNullable = true)] + public string? Attachment { get; set; } + } + } + + /// + /// 获取或设置用户 OpenId。 + /// + [Newtonsoft.Json.JsonProperty("OpenId")] + [System.Text.Json.Serialization.JsonPropertyName("OpenId")] + [System.Xml.Serialization.XmlElement("OpenId")] + public string OpenId { get; set; } = default!; + + /// + /// 获取或设置业务订单号。 + /// + [Newtonsoft.Json.JsonProperty("OutTradeNo")] + [System.Text.Json.Serialization.JsonPropertyName("OutTradeNo")] + [System.Xml.Serialization.XmlElement("OutTradeNo")] + public string OutTradeNumber { get; set; } = default!; + + /// + /// 获取或设置虚拟支付环境。 + /// + [Newtonsoft.Json.JsonProperty("Env")] + [System.Text.Json.Serialization.JsonPropertyName("Env")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + [System.Xml.Serialization.XmlElement("Env")] + public int Environment { get; set; } + + /// + /// 获取或设置微信支付信息。 + /// + [Newtonsoft.Json.JsonProperty("WeChatPayInfo")] + [System.Text.Json.Serialization.JsonPropertyName("WeChatPayInfo")] + [System.Xml.Serialization.XmlElement("WeChatPayInfo", IsNullable = true)] + public Types.WechatpayInfo? WechatpayInfo { get; set; } + + /// + /// 获取或设置道具信息。 + /// + [Newtonsoft.Json.JsonProperty("GoodsInfo")] + [System.Text.Json.Serialization.JsonPropertyName("GoodsInfo")] + [System.Xml.Serialization.XmlElement("GoodsInfo", IsNullable = true)] + public Types.GoodsInfo? GoodsInfo { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaGameExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaGameExtensions.cs index e9c56752..17039397 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaGameExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaGameExtensions.cs @@ -1,13 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl; using Flurl.Http; -using Newtonsoft.Json.Converters; namespace SKIT.FlurlHttpClient.Wechat.Api { @@ -36,7 +32,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api request.SignMethod = Constants.MidasSignMethods.HMAC_SHA256; } - if (request.Signature == null) + if (request.Signature == null && request.SessionKey != null) { tmpRawData = tmpRawData ?? client.JsonSerializer.Serialize(request); @@ -45,7 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api case Constants.MidasSignMethods.HMAC_SHA256: { string msgText = tmpRawData; - request.Signature = Utilities.HMACUtility.HashWithSHA256(request.SessionKey ?? string.Empty, msgText).ToLower(); + request.Signature = Utilities.HMACUtility.HashWithSHA256(request.SessionKey, msgText).ToLower(); } break; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteXPayExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteXPayExtensions.cs new file mode 100644 index 00000000..85821e26 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteXPayExtensions.cs @@ -0,0 +1,364 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.Api +{ + public static class WechatApiClientExecuteXPayExtensions + { + private static T PreprocessRequest(WechatApiClient client, ref T request) + where T : Models.XPayRequestBase, new() + { + if (client == null) throw new ArgumentNullException(nameof(request)); + if (request == null) throw new ArgumentNullException(nameof(request)); + + string? tmpRawData = null; // 用于缓存待签名数据中的请求正文部分,避免序列化多次浪费性能 + + if (request.Signature == null && request.SessionKey != null) + { + tmpRawData = tmpRawData ?? client.JsonSerializer.Serialize(request); + + string msgText = tmpRawData; + request.Signature = Utilities.HMACUtility.HashWithSHA256(request.SessionKey, msgText).ToLower(); + } + + if (request.PaySign == null) + { + tmpRawData = tmpRawData ?? client.JsonSerializer.Serialize(request); + + string msgText = $"{request.GetRequestPath()}&{tmpRawData}"; + request.PaySign = Utilities.HMACUtility.HashWithSHA256(client.Credentials.VirtualPaymentAppKey ?? string.Empty, msgText).ToLower(); + } + + return request; + } + + /// + /// 异步调用 [POST] /xpay/query_user_balance 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayQueryUserBalanceAsync(this WechatApiClient client, Models.XPayQueryUserBalanceRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "query_user_balance") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("signature", request.Signature) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/currency_pay 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayCurrencyPayAsync(this WechatApiClient client, Models.XPayCurrencyPayRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "currency_pay") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("signature", request.Signature) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/cancel_currency_pay 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayCancelCurrencyPayAsync(this WechatApiClient client, Models.XPayCancelCurrencyPayRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "cancel_currency_pay") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("signature", request.Signature) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/notify_provide_goods 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayNotifyProvideGoodsAsync(this WechatApiClient client, Models.XPayNotifyProvideGoodsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "notify_provide_goods") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/present_currency 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayPresentCurrencyAsync(this WechatApiClient client, Models.XPayPresentCurrencyRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "present_currency") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/download_bill 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayDownloadBillAsync(this WechatApiClient client, Models.XPayDownloadBillRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "download_bill") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/query_order 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayQueryOrderAsync(this WechatApiClient client, Models.XPayQueryOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "query_order") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/refund_order 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayRefundOrderAsync(this WechatApiClient client, Models.XPayRefundOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "refund_order") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/create_withdraw_order 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayCreateWithdrawOrderAsync(this WechatApiClient client, Models.XPayCreateWithdrawOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "create_withdraw_order") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/query_withdraw_order 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayQueryWithdrawOrderAsync(this WechatApiClient client, Models.XPayQueryWithdrawOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "query_withdraw_order") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/start_upload_goods 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayStartUploadGoodsAsync(this WechatApiClient client, Models.XPayStartUploadGoodsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "start_upload_goods") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/query_upload_goods 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayQueryUploadGoodsAsync(this WechatApiClient client, Models.XPayQueryUploadGoodsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "query_upload_goods") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/start_publish_goods 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayStartPublishGoodsAsync(this WechatApiClient client, Models.XPayStartPublishGoodsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "start_publish_goods") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /xpay/query_publish_goods 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API + /// + /// + /// + /// + /// + public static async Task ExecuteXPayQueryPublishGoodsAsync(this WechatApiClient client, Models.XPayQueryPublishGoodsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + PreprocessRequest(client, ref request); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "xpay", "query_publish_goods") + .SetQueryParam("access_token", request.AccessToken) + .SetQueryParam("pay_sig", request.PaySign); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/Abstractions/WxaGameRequestBase.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/Abstractions/WxaGameRequestBase.cs index 07863192..4589d2b1 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/Abstractions/WxaGameRequestBase.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/Abstractions/WxaGameRequestBase.cs @@ -49,7 +49,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Models /// [Newtonsoft.Json.JsonIgnore] [System.Text.Json.Serialization.JsonIgnore] - public string SessionKey { get; set; } = string.Empty; + public string? SessionKey { get; set; } /// /// 获取或设置用于用户登录态签名的方式。 diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGameCancelPayRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGameCancelPayRequest.cs index 36c95d5b..3775fa37 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGameCancelPayRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGameCancelPayRequest.cs @@ -20,7 +20,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Models public string BillNumber { get; set; } = string.Empty; /// - /// 获取或设置本次退回的退游戏币的数量。 + /// 获取或设置本次退回的游戏币的数量。 /// [Newtonsoft.Json.JsonProperty("amount")] [System.Text.Json.Serialization.JsonPropertyName("amount")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGamePayResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGamePayResponse.cs index 5321d196..20bfff72 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGamePayResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/WxaGame/WxaGamePayResponse.cs @@ -20,7 +20,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Models public int Balance { get; set; } /// - /// 获取或设置本次扣的赠送币的数量。 + /// 获取或设置本次扣除的赠送币的数量。 /// [Newtonsoft.Json.JsonProperty("used_present_amount")] [System.Text.Json.Serialization.JsonPropertyName("used_present_amount")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/Abstractions/XPayRequestBase.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/Abstractions/XPayRequestBase.cs new file mode 100644 index 00000000..9f410ebc --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/Abstractions/XPayRequestBase.cs @@ -0,0 +1,56 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + public abstract class XPayRequestBase : WechatApiRequest + { + /// + /// 获取或设置用户唯一标识。 + /// + [Newtonsoft.Json.JsonProperty("openid")] + [System.Text.Json.Serialization.JsonPropertyName("openid")] + public string? OpenId { get; set; } + + /// + /// 获取或设置虚拟支付环境。 + /// + [Newtonsoft.Json.JsonProperty("env")] + [System.Text.Json.Serialization.JsonPropertyName("env")] + public int Environment { get; set; } + + /// + /// 获取或设置用户 IP。 + /// + [Newtonsoft.Json.JsonProperty("user_ip")] + [System.Text.Json.Serialization.JsonPropertyName("user_ip")] + public string? UserIp { get; set; } + + /// + /// 获取或设置平台类型。 + /// + [Newtonsoft.Json.JsonProperty("device_type")] + [System.Text.Json.Serialization.JsonPropertyName("device_type")] + public int? DeviceType { get; set; } + + /// + /// 获取或设置用于用户登录态签名的会话密钥。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? SessionKey { get; set; } + + /// + /// 获取或设置用户登录态签名。如果不指定将由系统自动生成。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? Signature { get; set; } + + /// + /// 获取或设置支付签名。如果不指定将由系统自动生成。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? PaySign { get; set; } + + protected internal abstract string GetRequestPath(); + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayRequest.cs new file mode 100644 index 00000000..aab821bc --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayRequest.cs @@ -0,0 +1,34 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/cancel_currency_pay 接口的请求。 + /// + public class XPayCancelCurrencyPayRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置扣除代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("pay_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("pay_order_id")] + public string PayOrderId { get; set; } = string.Empty; + + /// + /// 获取或设置退回代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = string.Empty; + + /// + /// 获取或设置本次退回的代币的数量。 + /// + [Newtonsoft.Json.JsonProperty("amount")] + [System.Text.Json.Serialization.JsonPropertyName("amount")] + public int Amount { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/cancel_currency_pay"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayResponse.cs new file mode 100644 index 00000000..4699188f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCancelCurrencyPayResponse.cs @@ -0,0 +1,15 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/cancel_currency_pay 接口的响应。 + /// + public class XPayCancelCurrencyPayResponse : WechatApiResponse + { + /// + /// 获取或设置退回代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderRequest.cs new file mode 100644 index 00000000..49f22435 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderRequest.cs @@ -0,0 +1,29 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/create_withdraw_order 接口的请求。 + /// + public class XPayCreateWithdrawOrderRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置提现单号。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_no")] + public string WithdrawNumber { get; set; } = string.Empty; + + /// + /// 获取或设置提现金额(单位:元)。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_amount")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.TextualDoubleConverter))] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_amount")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString | System.Text.Json.Serialization.JsonNumberHandling.WriteAsString)] + public double? Amount { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/create_withdraw_order"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderResponse.cs new file mode 100644 index 00000000..aa09e887 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCreateWithdrawOrderResponse.cs @@ -0,0 +1,22 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/create_withdraw_order 接口的响应。 + /// + public class XPayCreateWithdrawOrderResponse : WechatApiResponse + { + /// + /// 获取或设置提现单号。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_no")] + public string WithdrawNumber { get; set; } = default!; + + /// + /// 获取或设置微信内部提现单号。 + /// + [Newtonsoft.Json.JsonProperty("wx_withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("wx_withdraw_no")] + public string WxWithdrawNumber { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayRequest.cs new file mode 100644 index 00000000..d42d47d3 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayRequest.cs @@ -0,0 +1,41 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/currency_pay 接口的请求。 + /// + public class XPayCurrencyPayRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置扣除代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = string.Empty; + + /// + /// 获取或设置扣除代币数量。 + /// + [Newtonsoft.Json.JsonProperty("amount")] + [System.Text.Json.Serialization.JsonPropertyName("amount")] + public int Amount { get; set; } + + /// + /// 获取或设置物品信息。 + /// + [Newtonsoft.Json.JsonProperty("payitem")] + [System.Text.Json.Serialization.JsonPropertyName("payitem")] + public string? PayItem { get; set; } + + /// + /// 获取或设置备注。 + /// + [Newtonsoft.Json.JsonProperty("remark")] + [System.Text.Json.Serialization.JsonPropertyName("remark")] + public string? Remark { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/currency_pay"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayResponse.cs new file mode 100644 index 00000000..05cd3eec --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayCurrencyPayResponse.cs @@ -0,0 +1,29 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/currency_pay 接口的响应。 + /// + public class XPayCurrencyPayResponse : WechatApiResponse + { + /// + /// 获取或设置扣除代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = default!; + + /// + /// 获取或设置预扣后的余额。 + /// + [Newtonsoft.Json.JsonProperty("balance")] + [System.Text.Json.Serialization.JsonPropertyName("balance")] + public int Balance { get; set; } + + /// + /// 获取或设置本次扣除的赠送币的数量。 + /// + [Newtonsoft.Json.JsonProperty("used_present_amount")] + [System.Text.Json.Serialization.JsonPropertyName("used_present_amount")] + public int UsedPresentAmount { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillRequest.cs new file mode 100644 index 00000000..8521c541 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillRequest.cs @@ -0,0 +1,27 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/download_bill 接口的请求。 + /// + public class XPayDownloadBillRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置起始日期字符串(格式:yyyyMMdd)。 + /// + [Newtonsoft.Json.JsonProperty("begin_ds")] + [System.Text.Json.Serialization.JsonPropertyName("begin_ds")] + public string BeginDateString { get; set; } = string.Empty; + + /// + /// 获取或设置截止日期字符串(格式:yyyyMMdd)。 + /// + [Newtonsoft.Json.JsonProperty("end_ds")] + [System.Text.Json.Serialization.JsonPropertyName("end_ds")] + public string EndDateString { get; set; } = string.Empty; + + protected internal override string GetRequestPath() + { + return "/xpay/download_bill"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillResponse.cs new file mode 100644 index 00000000..1f1ecf4b --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayDownloadBillResponse.cs @@ -0,0 +1,15 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/download_bill 接口的响应。 + /// + public class XPayDownloadBillResponse : WechatApiResponse + { + /// + /// 获取或设置下载地址。 + /// + [Newtonsoft.Json.JsonProperty("url")] + [System.Text.Json.Serialization.JsonPropertyName("url")] + public string Url { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsRequest.cs new file mode 100644 index 00000000..1e93639d --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsRequest.cs @@ -0,0 +1,27 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/notify_provide_goods 接口的请求。 + /// + public class XPayNotifyProvideGoodsRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string? OrderId { get; set; } + + /// + /// 获取或设置微信内部订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("wx_order_id")] + public string? WxOrderId { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/notify_provide_goods"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsResponse.cs new file mode 100644 index 00000000..7099a792 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayNotifyProvideGoodsResponse.cs @@ -0,0 +1,9 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/notify_provide_goods 接口的响应。 + /// + public class XPayNotifyProvideGoodsResponse : WechatApiResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyRequest.cs new file mode 100644 index 00000000..220b9489 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyRequest.cs @@ -0,0 +1,27 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/present_currency 接口的请求。 + /// + public class XPayPresentCurrencyRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置赠送代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = string.Empty; + + /// + /// 获取或设置赠送代币的个数。 + /// + [Newtonsoft.Json.JsonProperty("amount")] + [System.Text.Json.Serialization.JsonPropertyName("amount")] + public int Amount { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/present_currency"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyResponse.cs new file mode 100644 index 00000000..eacfbd48 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayPresentCurrencyResponse.cs @@ -0,0 +1,29 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/present_currency 接口的响应。 + /// + public class XPayPresentCurrencyResponse : WechatApiResponse + { + /// + /// 获取或设置赠送代币的订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = default!; + + /// + /// 获取或设置赠送后的余额。 + /// + [Newtonsoft.Json.JsonProperty("balance")] + [System.Text.Json.Serialization.JsonPropertyName("balance")] + public int Balance { get; set; } + + /// + /// 获取或设置赠送后的代币余额。 + /// + [Newtonsoft.Json.JsonProperty("present_balance")] + [System.Text.Json.Serialization.JsonPropertyName("present_balance")] + public int PresentBalance { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderRequest.cs new file mode 100644 index 00000000..27694f27 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderRequest.cs @@ -0,0 +1,27 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_order 接口的请求。 + /// + public class XPayQueryOrderRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string? OrderId { get; set; } + + /// + /// 获取或设置微信内部订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("wx_order_id")] + public string? WxOrderId { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/query_order"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderResponse.cs new file mode 100644 index 00000000..795af64f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryOrderResponse.cs @@ -0,0 +1,154 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_order 接口的响应。 + /// + public class XPayQueryOrderResponse : WechatApiResponse + { + public static class Types + { + public class Order + { + /// + /// 获取或设置订单号。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string OrderId { get; set; } = default!; + + /// + /// 获取或设置虚拟支付环境。 + /// + [Newtonsoft.Json.JsonProperty("env_type")] + [System.Text.Json.Serialization.JsonPropertyName("env_type")] + public int Environment { get; set; } + + /// + /// 获取或设置订单类型。 + /// + [Newtonsoft.Json.JsonProperty("order_type")] + [System.Text.Json.Serialization.JsonPropertyName("order_type")] + public int OrderType { get; set; } + + /// + /// 获取或设置订单状态。 + /// + [Newtonsoft.Json.JsonProperty("status")] + [System.Text.Json.Serialization.JsonPropertyName("status")] + public int Status { get; set; } + + /// + /// 获取或设置业务类型。 + /// + [Newtonsoft.Json.JsonProperty("biz_type")] + [System.Text.Json.Serialization.JsonPropertyName("biz_type")] + public int BusinessType { get; set; } + + /// + /// 获取或设置订单金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("order_fee")] + [System.Text.Json.Serialization.JsonPropertyName("order_fee")] + public int OrderFee { get; set; } + + /// + /// 获取或设置订单优惠金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("coupon_fee")] + [System.Text.Json.Serialization.JsonPropertyName("coupon_fee")] + public int CouponFee { get; set; } + + /// + /// 获取或设置用户支付金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("paid_fee")] + [System.Text.Json.Serialization.JsonPropertyName("paid_fee")] + public int PaidFee { get; set; } + + /// + /// 获取或设置退款金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("refund_fee")] + [System.Text.Json.Serialization.JsonPropertyName("refund_fee")] + public int? RefundFee { get; set; } + + /// + /// 获取或设置剩余金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("left_fee")] + [System.Text.Json.Serialization.JsonPropertyName("left_fee")] + public int? LeftFee { get; set; } + + /// + /// 获取或设置付款时间戳。 + /// + [Newtonsoft.Json.JsonProperty("paid_time")] + [System.Text.Json.Serialization.JsonPropertyName("paid_time")] + public long? PayTimestamp { get; set; } + + /// + /// 获取或设置发货时间戳。 + /// + [Newtonsoft.Json.JsonProperty("provide_time")] + [System.Text.Json.Serialization.JsonPropertyName("provide_time")] + public long? ProvideTimestamp { get; set; } + + /// + /// 获取或设置创建时间戳。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + public long CreateTimestamp { get; set; } + + /// + /// 获取或设置更新时间戳。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + public long UpdateTimestamp { get; set; } + + /// + /// 获取或设置订单创建时传的信息。 + /// + [Newtonsoft.Json.JsonProperty("biz_meta")] + [System.Text.Json.Serialization.JsonPropertyName("biz_meta")] + public string? BusinessMeta { get; set; } + + /// + /// 获取或设置下单时米大师返回的 Token。 + /// + [Newtonsoft.Json.JsonProperty("token")] + [System.Text.Json.Serialization.JsonPropertyName("token")] + public string? MidasToken { get; set; } + + /// + /// 获取或设置微信内部单号。 + /// + [Newtonsoft.Json.JsonProperty("wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("wx_order_id")] + public string WxOrderId { get; set; } = default!; + + /// + /// 获取或设置渠道单号。 + /// + [Newtonsoft.Json.JsonProperty("channel_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("channel_order_id")] + public string? ChannelOrderId { get; set; } + + /// + /// 获取或设置微信支付交易单号。 + /// + [Newtonsoft.Json.JsonProperty("wxpay_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("wxpay_order_id")] + public string? TransactionId { get; set; } + } + } + + /// + /// 获取或设置订单信息。 + /// + [Newtonsoft.Json.JsonProperty("order")] + [System.Text.Json.Serialization.JsonPropertyName("order")] + public Types.Order Order { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsRequest.cs new file mode 100644 index 00000000..fab7e1e5 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsRequest.cs @@ -0,0 +1,13 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_publish_goods 接口的请求。 + /// + public class XPayQueryPublishGoodsRequest : XPayRequestBase, IInferable + { + protected internal override string GetRequestPath() + { + return "/xpay/query_publish_goods"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsResponse.cs new file mode 100644 index 00000000..9422d736 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryPublishGoodsResponse.cs @@ -0,0 +1,49 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_publish_goods 接口的响应。 + /// + public class XPayQueryPublishGoodsResponse : WechatApiResponse + { + public static class Types + { + public class PublishItem + { + /// + /// 获取或设置道具 ID。 + /// + [Newtonsoft.Json.JsonProperty("id")] + [System.Text.Json.Serialization.JsonPropertyName("id")] + public string Id { get; set; } = default!; + + /// + /// 获取或设置发布状态。 + /// + [Newtonsoft.Json.JsonProperty("publish_status")] + [System.Text.Json.Serialization.JsonPropertyName("publish_status")] + public int PublishStatus { get; set; } + + /// + /// 获取或设置发布失败原因。 + /// + [Newtonsoft.Json.JsonProperty("errmsg")] + [System.Text.Json.Serialization.JsonPropertyName("errmsg")] + public string? FailReason { get; set; } + } + } + + /// + /// 获取或设置道具列表。 + /// + [Newtonsoft.Json.JsonProperty("publish_item")] + [System.Text.Json.Serialization.JsonPropertyName("publish_item")] + public Types.PublishItem[] PublishItemList { get; set; } = default!; + + /// + /// 获取或设置发布状态。 + /// + [Newtonsoft.Json.JsonProperty("status")] + [System.Text.Json.Serialization.JsonPropertyName("status")] + public int Status { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsRequest.cs new file mode 100644 index 00000000..4691ecac --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsRequest.cs @@ -0,0 +1,13 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_upload_goods 接口的请求。 + /// + public class XPayQueryUploadGoodsRequest : XPayRequestBase, IInferable + { + protected internal override string GetRequestPath() + { + return "/xpay/query_upload_goods"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsResponse.cs new file mode 100644 index 00000000..a8efb7b2 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUploadGoodsResponse.cs @@ -0,0 +1,77 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_upload_goods 接口的响应。 + /// + public class XPayQueryUploadGoodsResponse : WechatApiResponse + { + public static class Types + { + public class UploadItem + { + /// + /// 获取或设置道具 ID。 + /// + [Newtonsoft.Json.JsonProperty("id")] + [System.Text.Json.Serialization.JsonPropertyName("id")] + public string Id { get; set; } = default!; + + /// + /// 获取或设置道具名称。 + /// + [Newtonsoft.Json.JsonProperty("name")] + [System.Text.Json.Serialization.JsonPropertyName("name")] + public string Name { get; set; } = default!; + + /// + /// 获取或设置道具单价(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("price")] + [System.Text.Json.Serialization.JsonPropertyName("price")] + public int Price { get; set; } + + /// + /// 获取或设置备注。 + /// + [Newtonsoft.Json.JsonProperty("remark")] + [System.Text.Json.Serialization.JsonPropertyName("remark")] + public string? Remark { get; set; } + + /// + /// 获取或设置图片 URL。 + /// + [Newtonsoft.Json.JsonProperty("item_url")] + [System.Text.Json.Serialization.JsonPropertyName("item_url")] + public string? PictureUrl { get; set; } + + /// + /// 获取或设置上传状态。 + /// + [Newtonsoft.Json.JsonProperty("upload_status")] + [System.Text.Json.Serialization.JsonPropertyName("upload_status")] + public int UploadStatus { get; set; } + + /// + /// 获取或设置上传失败原因。 + /// + [Newtonsoft.Json.JsonProperty("errmsg")] + [System.Text.Json.Serialization.JsonPropertyName("errmsg")] + public string? FailReason { get; set; } + } + } + + /// + /// 获取或设置道具列表。 + /// + [Newtonsoft.Json.JsonProperty("upload_item")] + [System.Text.Json.Serialization.JsonPropertyName("upload_item")] + public Types.UploadItem[] UploadItemList { get; set; } = default!; + + /// + /// 获取或设置上传状态。 + /// + [Newtonsoft.Json.JsonProperty("status")] + [System.Text.Json.Serialization.JsonPropertyName("status")] + public int Status { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceRequest.cs new file mode 100644 index 00000000..7e2d6373 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceRequest.cs @@ -0,0 +1,13 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_user_balance 接口的请求。 + /// + public class XPayQueryUserBalanceRequest : XPayRequestBase, IInferable + { + protected internal override string GetRequestPath() + { + return "/xpay/query_user_balance"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceResponse.cs new file mode 100644 index 00000000..109d561e --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryUserBalanceResponse.cs @@ -0,0 +1,59 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_user_balance 接口的响应。 + /// + public class XPayQueryUserBalanceResponse : WechatApiResponse + { + /// + /// 获取或设置代币总余额。 + /// + [Newtonsoft.Json.JsonProperty("balance")] + [System.Text.Json.Serialization.JsonPropertyName("balance")] + public int Balance { get; set; } + + /// + /// 获取或设置赠送账户的代币余额。 + /// + [Newtonsoft.Json.JsonProperty("present_balance")] + [System.Text.Json.Serialization.JsonPropertyName("present_balance")] + public int PresentBalance { get; set; } + + /// + /// 获取或设置是否满足首充活动。 + /// + [Newtonsoft.Json.JsonProperty("first_save_flag")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.NumericalBooleanConverter))] + [System.Text.Json.Serialization.JsonPropertyName("first_save_flag")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.NumericalBooleanConverter))] + public bool IsFirstSave { get; set; } + + /// + /// 获取或设置累计现金充值获得的代币数量。 + /// + [Newtonsoft.Json.JsonProperty("sum_save")] + [System.Text.Json.Serialization.JsonPropertyName("sum_save")] + public int SumSave { get; set; } + + /// + /// 获取或设置累计赠送的代币数量。 + /// + [Newtonsoft.Json.JsonProperty("sum_present")] + [System.Text.Json.Serialization.JsonPropertyName("sum_present")] + public int SumPresent { get; set; } + + /// + /// 获取或设置累计获得的代币数量。 + /// + [Newtonsoft.Json.JsonProperty("sum_balance")] + [System.Text.Json.Serialization.JsonPropertyName("sum_balance")] + public int SumBalance { get; set; } + + /// + /// 获取或设置累计总消耗代币数量。 + /// + [Newtonsoft.Json.JsonProperty("sum_cost")] + [System.Text.Json.Serialization.JsonPropertyName("sum_cost")] + public int SumCost { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderRequest.cs new file mode 100644 index 00000000..1189d5fe --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderRequest.cs @@ -0,0 +1,20 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_withdraw_order 接口的请求。 + /// + public class XPayQueryWithdrawOrderRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置提现单号。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_no")] + public string WithdrawNumber { get; set; } = string.Empty; + + protected internal override string GetRequestPath() + { + return "/xpay/query_withdraw_order"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderResponse.cs new file mode 100644 index 00000000..72968308 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayQueryWithdrawOrderResponse.cs @@ -0,0 +1,60 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/query_withdraw_order 接口的响应。 + /// + public class XPayQueryWithdrawOrderResponse : WechatApiResponse + { + /// + /// 获取或设置提现单号。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_no")] + public string WithdrawNumber { get; set; } = default!; + + /// + /// 获取或设置提现金额(单位:元)。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_amount")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_amount")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString | System.Text.Json.Serialization.JsonNumberHandling.WriteAsString)] + public double Amount { get; set; } + + /// + /// 获取或设置提现状态。 + /// + [Newtonsoft.Json.JsonProperty("status")] + [System.Text.Json.Serialization.JsonPropertyName("status")] + public int Status { get; set; } + + /// + /// 获取或设置成功时间戳。 + /// + [Newtonsoft.Json.JsonProperty("withdraw_success_timestamp")] + [System.Text.Json.Serialization.JsonPropertyName("withdraw_success_timestamp")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public long? SuccessTimestamp { get; set; } + + /// + /// 获取或设置失败原因。 + /// + [Newtonsoft.Json.JsonProperty("fail_reason")] + [System.Text.Json.Serialization.JsonPropertyName("fail_reason")] + public string? FailReason { get; set; } + + /// + /// 获取或设置创建时间戳。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public long CreateTimestamp { get; set; } + + /// + /// 获取或设置微信内部提现单号。 + /// + [Newtonsoft.Json.JsonProperty("wx_withdraw_no")] + [System.Text.Json.Serialization.JsonPropertyName("wx_withdraw_no")] + public string WxWithdrawNumber { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderRequest.cs new file mode 100644 index 00000000..b2faf4e7 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderRequest.cs @@ -0,0 +1,69 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/refund_order 接口的请求。 + /// + public class XPayRefundOrderRequest : XPayRequestBase, IInferable + { + /// + /// 获取或设置订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("order_id")] + [System.Text.Json.Serialization.JsonPropertyName("order_id")] + public string? PayOrderId { get; set; } + + /// + /// 获取或设置微信内部订单号。与字段 二选一。 + /// + [Newtonsoft.Json.JsonProperty("wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("wx_order_id")] + public string? PayWxOrderId { get; set; } + + /// + /// 获取或设置退款订单号。 + /// + [Newtonsoft.Json.JsonProperty("refund_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("refund_order_id")] + public string RefundOrderId { get; set; } = string.Empty; + + /// + /// 获取或设置退款金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("refund_fee")] + [System.Text.Json.Serialization.JsonPropertyName("refund_fee")] + public int RefundFee { get; set; } + + /// + /// 获取或设置剩余金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("left_fee")] + [System.Text.Json.Serialization.JsonPropertyName("left_fee")] + public int LeftFee { get; set; } + + /// + /// 获取或设置自定义信息。 + /// + [Newtonsoft.Json.JsonProperty("biz_meta")] + [System.Text.Json.Serialization.JsonPropertyName("biz_meta")] + public string? BusinessMeta { get; set; } + + /// + /// 获取或设置退款原因。 + /// + [Newtonsoft.Json.JsonProperty("refund_reason")] + [System.Text.Json.Serialization.JsonPropertyName("refund_reason")] + public string? RefundReason { get; set; } + + /// + /// 获取或设置退款来源。 + /// + [Newtonsoft.Json.JsonProperty("req_from")] + [System.Text.Json.Serialization.JsonPropertyName("req_from")] + public string? RefundFrom { get; set; } + + protected internal override string GetRequestPath() + { + return "/xpay/refund_order"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderResponse.cs new file mode 100644 index 00000000..22a310d1 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayRefundOrderResponse.cs @@ -0,0 +1,36 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/refund_order 接口的响应。 + /// + public class XPayRefundOrderResponse : WechatApiResponse + { + /// + /// 获取或设置订单号。 + /// + [Newtonsoft.Json.JsonProperty("pay_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("pay_order_id")] + public string PayOrderId { get; set; } = default!; + + /// + /// 获取或设置微信内部订单号。 + /// + [Newtonsoft.Json.JsonProperty("pay_wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("pay_wx_order_id")] + public string PayWxOrderId { get; set; } = default!; + + /// + /// 获取或设置退款订单号。 + /// + [Newtonsoft.Json.JsonProperty("refund_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("refund_order_id")] + public string RefundOrderId { get; set; } = default!; + + /// + /// 获取或设置微信内部退款订单号。 + /// + [Newtonsoft.Json.JsonProperty("refund_wx_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("refund_wx_order_id")] + public string RefundWxOrderId { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsRequest.cs new file mode 100644 index 00000000..dfae9eaa --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsRequest.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/start_publish_goods 接口的请求。 + /// + public class XPayStartPublishGoodsRequest : XPayRequestBase, IInferable + { + public static class Types + { + public class PublishItem + { + /// + /// 获取或设置道具 ID。 + /// + [Newtonsoft.Json.JsonProperty("id")] + [System.Text.Json.Serialization.JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + } + } + + /// + /// 获取或设置道具列表。 + /// + [Newtonsoft.Json.JsonProperty("publish_item")] + [System.Text.Json.Serialization.JsonPropertyName("publish_item")] + public IList PublishItemList { get; set; } = new List(); + + protected internal override string GetRequestPath() + { + return "/xpay/start_publish_goods"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsResponse.cs new file mode 100644 index 00000000..0dd37f20 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartPublishGoodsResponse.cs @@ -0,0 +1,9 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/start_publish_goods 接口的响应。 + /// + public class XPayStartPublishGoodsResponse : WechatApiResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsRequest.cs new file mode 100644 index 00000000..c46644c8 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsRequest.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/start_upload_goods 接口的请求。 + /// + public class XPayStartUploadGoodsRequest : XPayRequestBase, IInferable + { + public static class Types + { + public class UploadItem + { + /// + /// 获取或设置道具 ID。 + /// + [Newtonsoft.Json.JsonProperty("id")] + [System.Text.Json.Serialization.JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + + /// + /// 获取或设置道具名称。 + /// + [Newtonsoft.Json.JsonProperty("name")] + [System.Text.Json.Serialization.JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// + /// 获取或设置道具单价(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("price")] + [System.Text.Json.Serialization.JsonPropertyName("price")] + public int Price { get; set; } + + /// + /// 获取或设置备注。 + /// + [Newtonsoft.Json.JsonProperty("remark")] + [System.Text.Json.Serialization.JsonPropertyName("remark")] + public string? Remark { get; set; } + + /// + /// 获取或设置图片 URL。 + /// + [Newtonsoft.Json.JsonProperty("item_url")] + [System.Text.Json.Serialization.JsonPropertyName("item_url")] + public string? PictureUrl { get; set; } + } + } + + /// + /// 获取或设置道具列表。 + /// + [Newtonsoft.Json.JsonProperty("upload_item")] + [System.Text.Json.Serialization.JsonPropertyName("upload_item")] + public IList UploadItemList { get; set; } = new List(); + + protected internal override string GetRequestPath() + { + return "/xpay/start_upload_goods"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsResponse.cs new file mode 100644 index 00000000..f5ced799 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/XPay/XPayStartUploadGoodsResponse.cs @@ -0,0 +1,9 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /xpay/start_upload_goods 接口的响应。 + /// + public class XPayStartUploadGoodsResponse : WechatApiResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Settings/Credentials.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Settings/Credentials.cs index 2c0be034..17ab9923 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Settings/Credentials.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Settings/Credentials.cs @@ -34,6 +34,11 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Settings /// public string? ImmeDeliveryAppSecret { get; } + /// + /// 初始化客户端时 的副本。 + /// + public string? VirtualPaymentAppKey { get; } + /// /// 初始化客户端时 的副本。 /// @@ -64,6 +69,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Settings PushToken = options.PushToken; ImmeDeliveryAppKey = options.ImmeDeliveryAppKey; ImmeDeliveryAppSecret = options.ImmeDeliveryAppSecret; + VirtualPaymentAppKey = options.VirtualPaymentAppKey; MidasAppKey = options.MidasAppKey; MidasOfferId = options.MidasOfferId; MidasAppKeyV2 = options.MidasAppKeyV2; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/WechatApiClientOptions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/WechatApiClientOptions.cs index 8ea76b11..2e0d4904 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/WechatApiClientOptions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/WechatApiClientOptions.cs @@ -47,6 +47,11 @@ namespace SKIT.FlurlHttpClient.Wechat.Api /// public string? ImmeDeliveryAppSecret { get; set; } + /// + /// 获取或设置虚拟支付 AppKey(用于小程序虚拟支付相关接口)。 + /// + public string? VirtualPaymentAppKey { get; set; } + /// /// 获取或设置米大师平台 OfferId(用于小游戏虚拟支付 1.0 相关接口)。 /// diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayCoinPayNotifyEvent.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayCoinPayNotifyEvent.json new file mode 100644 index 00000000..9eccf852 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayCoinPayNotifyEvent.json @@ -0,0 +1,21 @@ +{ + "ToUserName": "", + "FromUserName": "", + "CreateTime": 0, + "MsgType": "event", + "Event": "xpay_coin_pay_notify", + "OpenId": "", + "OutTradeNo": "", + "Env": 0, + "WeChatPayInfo": { + "MchOrderNo": "", + "TransactionId": "", + "PaidTime": 0 + }, + "CoinInfo": { + "Quantity": 0, + "OrigPrice": 0, + "ActualPrice": 0, + "Attach": "" + } +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayGoodsDeliverNotifyEvent.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayGoodsDeliverNotifyEvent.json new file mode 100644 index 00000000..4f76883a --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/EventSamples/XPay/XPayGoodsDeliverNotifyEvent.json @@ -0,0 +1,22 @@ +{ + "ToUserName": "", + "FromUserName": "", + "CreateTime": 0, + "MsgType": "event", + "Event": "xpay_goods_deliver_notify", + "OpenId": "", + "OutTradeNo": "", + "Env": 0, + "WeChatPayInfo": { + "MchOrderNo": "", + "TransactionId": "", + "PaidTime": 0 + }, + "GoodsInfo": { + "ProductId": "", + "Quantity": 0, + "OrigPrice": 0, + "ActualPrice": 0, + "Attach": "" + } +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayRequest.json new file mode 100644 index 00000000..79ce8ec5 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayRequest.json @@ -0,0 +1,9 @@ +{ + "openid": "", + "env": 0, + "user_ip": "", + "pay_order_id": "", + "order_id": "", + "amount": 0, + "device_type": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayResponse.json new file mode 100644 index 00000000..0952bae3 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCancelCurrencyPayResponse.json @@ -0,0 +1,5 @@ +{ + "errcode": 0, + "errmsg": "ok", + "order_id": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderRequest.json new file mode 100644 index 00000000..1b9efa22 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderRequest.json @@ -0,0 +1,5 @@ +{ + "withdraw_no": "", + "withdraw_amount": "0", + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderResponse.json new file mode 100644 index 00000000..97c36cc8 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCreateWithdrawOrderResponse.json @@ -0,0 +1,6 @@ +{ + "errcode": 0, + "errmsg": "ok", + "withdraw_no": "", + "wx_withdraw_no": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayRequest.json new file mode 100644 index 00000000..ba110e43 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayRequest.json @@ -0,0 +1,10 @@ +{ + "openid": "", + "env": 0, + "user_ip": "", + "amount": 0, + "order_id": "", + "payitem": "", + "remark": "", + "device_type": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayResponse.json new file mode 100644 index 00000000..46874af0 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayCurrencyPayResponse.json @@ -0,0 +1,7 @@ +{ + "errcode": 0, + "errmsg": "ok", + "order_id": "", + "balance": 0, + "used_present_amount": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillRequest.json new file mode 100644 index 00000000..005ffe5c --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillRequest.json @@ -0,0 +1,4 @@ +{ + "begin_ds": "20230801", + "end_ds": "20230810" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillResponse.json new file mode 100644 index 00000000..327559ad --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayDownloadBillResponse.json @@ -0,0 +1,5 @@ +{ + "errcode": 0, + "errmsg": "ok", + "url": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayNotifyProvideGoodsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayNotifyProvideGoodsRequest.json new file mode 100644 index 00000000..aeca925e --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayNotifyProvideGoodsRequest.json @@ -0,0 +1,5 @@ +{ + "order_id": "", + "wx_order_id": "", + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyRequest.json new file mode 100644 index 00000000..9edfa2db --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyRequest.json @@ -0,0 +1,7 @@ +{ + "openid": "", + "env": 0, + "order_id": "", + "amount": 0, + "device_type": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyResponse.json new file mode 100644 index 00000000..af08a262 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayPresentCurrencyResponse.json @@ -0,0 +1,7 @@ +{ + "errcode": 0, + "errmsg": "ok", + "order_id": "", + "balance": 0, + "present_balance": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderRequest.json new file mode 100644 index 00000000..2fa3b205 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderRequest.json @@ -0,0 +1,6 @@ +{ + "openid": "", + "env": 0, + "order_id": "", + "wx_order_id": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderResponse.json new file mode 100644 index 00000000..fcb5cdfa --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryOrderResponse.json @@ -0,0 +1,25 @@ +{ + "errcode": 0, + "errmsg": "ok", + "order": { + "order_id": "", + "create_time": 0, + "update_time": 0, + "status": 0, + "biz_type": 0, + "order_fee": 0, + "coupon_fee": 0, + "paid_fee": 0, + "order_type": 0, + "refund_fee": 0, + "paid_time": 0, + "provide_time": 0, + "biz_meta": "", + "env_type": 0, + "token": "", + "left_fee": 0, + "wx_order_id": "", + "channel_order_id": "", + "wxpay_order_id": "" + } +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsRequest.json new file mode 100644 index 00000000..1f9f9e45 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsRequest.json @@ -0,0 +1,3 @@ +{ + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsResponse.json new file mode 100644 index 00000000..9eb82e90 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryPublishGoodsResponse.json @@ -0,0 +1,12 @@ +{ + "errcode": 0, + "errmsg": "ok", + "publish_item": [ + { + "id": "", + "publish_status": 0, + "errmsg": "" + } + ], + "status": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsRequest.json new file mode 100644 index 00000000..1f9f9e45 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsRequest.json @@ -0,0 +1,3 @@ +{ + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsResponse.json new file mode 100644 index 00000000..4ed17404 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUploadGoodsResponse.json @@ -0,0 +1,16 @@ +{ + "errcode": 0, + "errmsg": "ok", + "upload_item": [ + { + "id": "", + "name": "", + "price": 0, + "remark": "", + "item_url": "", + "upload_status": 0, + "errmsg": "" + } + ], + "status": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceRequest.json new file mode 100644 index 00000000..c98e4912 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceRequest.json @@ -0,0 +1,5 @@ +{ + "openid": "", + "env": 0, + "user_ip": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceResponse.json new file mode 100644 index 00000000..1c59f79f --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryUserBalanceResponse.json @@ -0,0 +1,11 @@ +{ + "errcode": 0, + "errmsg": "ok", + "balance": 0, + "present_balance": 0, + "sum_save": 0, + "sum_present": 0, + "sum_balance": 0, + "sum_cost": 0, + "first_save_flag": 1 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderRequest.json new file mode 100644 index 00000000..1c286dc0 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderRequest.json @@ -0,0 +1,4 @@ +{ + "withdraw_no": "", + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderResponse.json new file mode 100644 index 00000000..fe7c5ac7 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayQueryWithdrawOrderResponse.json @@ -0,0 +1,11 @@ +{ + "errcode": 0, + "errmsg": "ok", + "withdraw_no": "", + "status": 0, + "withdraw_amount": "0", + "wx_withdraw_no": "", + "withdraw_success_timestamp": 0, + "create_time": 0, + "fail_reason": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderRequest.json new file mode 100644 index 00000000..09b4fdea --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderRequest.json @@ -0,0 +1,12 @@ +{ + "openid": "", + "order_id": "", + "wx_order_id": "", + "refund_order_id": "", + "left_fee": 0, + "refund_fee": 0, + "biz_meta": "", + "refund_reason": "", + "req_from": "", + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderResponse.json new file mode 100644 index 00000000..f8bc4c79 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayRefundOrderResponse.json @@ -0,0 +1,8 @@ +{ + "errcode": 0, + "errmsg": "ok", + "refund_order_id": "", + "refund_wx_order_id": "", + "pay_order_id": "", + "pay_wx_order_id": "" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartPublishGoodsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartPublishGoodsRequest.json new file mode 100644 index 00000000..84766fb1 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartPublishGoodsRequest.json @@ -0,0 +1,8 @@ +{ + "publish_item": [ + { + "id": "" + } + ], + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartUploadGoodsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartUploadGoodsRequest.json new file mode 100644 index 00000000..7bc149b1 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/XPay/XPayStartUploadGoodsRequest.json @@ -0,0 +1,12 @@ +{ + "upload_item": [ + { + "id": "", + "name": "", + "price": 0, + "remark": "", + "item_url": "" + } + ], + "env": 0 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/TestCase_RequestSignatureTests.cs b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/TestCase_RequestSignatureTests.cs index 88691145..d2d6dedf 100644 --- a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/TestCase_RequestSignatureTests.cs +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/TestCase_RequestSignatureTests.cs @@ -25,7 +25,38 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.UnitTests Assert.Equal("a93d8d6bae9a9483c1b1d4e8670e7f6226ec94cb", request.DeliverySignature, ignoreCase: true); } - [Fact(DisplayName = "测试用例:米大师虚拟支付 1.0 请求签名")] + [Fact(DisplayName = "测试用例:虚拟支付请求签名")] + public async Task TestVirtualPaymentRequestSignature() + { + var mockClient = new WechatApiClient(new WechatApiClientOptions() + { + AppId = "wxtest", + AppSecret = "", + VirtualPaymentAppKey = "12345" + }); + mockClient.Configure(settings => + { + var jsonOptions = FlurlSystemTextJsonSerializer.GetDefaultSerializerOptions(); + jsonOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; + jsonOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.Strict; + jsonOptions.WriteIndented = false; + settings.JsonSerializer = new FlurlSystemTextJsonSerializer(jsonOptions); + }); + + var request = new Models.XPayQueryUserBalanceRequest() + { + OpenId = "xxx", + Environment = 0, + UserIp = "127.0.0.1", + SessionKey = "9hAb/NEYUlkaMBEsmFgzig==" + }; + var response = await mockClient.ExecuteXPayQueryUserBalanceAsync(request); // 这里不关心响应结果,只为获得预处理请求 + + Assert.Equal("e690cc22b6378ca9d70fe61727fabf65f0273d436813447816951989867a134c", request.Signature, ignoreCase: true); + Assert.Equal("fb4703e6b7da545a7f43428f02f2a9fa42e895704c6319d01a0aa859cf63253c", request.PaySign, ignoreCase: true); + } + + [Fact(DisplayName = "测试用例:米大师 1.0 请求签名")] public async Task TestMidasRequestSignature() { var mockClient = new WechatApiClient(new WechatApiClientOptions() @@ -48,8 +79,8 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.UnitTests Assert.Equal("1ad64e8dcb2ec1dc486b7fdf01f4a15159fc623dc3422470e51cf6870734726b", request.Signature, ignoreCase: true); } - [Fact(DisplayName = "测试用例:米大师虚拟支付 2.0 请求签名")] - public async Task TestMidasRequestSignatureV2() + [Fact(DisplayName = "测试用例:米大师 2.0 请求签名")] + public async Task TestMidasV2RequestSignature() { var mockClient = new WechatApiClient(new WechatApiClientOptions() {