忽略dll文件git

This commit is contained in:
“wanyongkang”
2023-07-29 10:19:42 +08:00
parent 7f97317bcc
commit b562aba2b1
3868 changed files with 63608 additions and 385427 deletions

View File

@@ -1,66 +1,66 @@
using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.Pay.AliPay
{
public class AliPayClient
{
public static readonly string url = "https://api.mch.weixin.qq.com";
IHttpClientFactory m_HttpClientFactory;
public AliPayClient(IHttpClientFactory _HttpClientFactory)
{
m_HttpClientFactory = _HttpClientFactory;
}
public async Task<string> PcPayCreateOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var APP_ID = "";
var APP_PRIVATE_KEY = "";
var CHARSET = "";
var ALIPAY_PUBLIC_KEY = "";
// 组装业务参数model
AlipayTradePagePayModel model = new AlipayTradePagePayModel
{
Body = request.Body,
Subject = request.Body,
TotalAmount = request.TotalFee.ToString(),
OutTradeNo = "",
ProductCode = "FAST_INSTANT_TRADE_PAY"//QUICK_WAP_PAY
};
AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();
// 设置同步回调地址
// aliRequest.SetReturnUrl($"http://{Request.Host}/Pay/Callback");
// 设置异步通知接收地址
aliRequest.SetNotifyUrl("");
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY);
var response = _aopClient.PageExecute(aliRequest);
return "";
}
public async Task<string> H5PayCreateOrderAsync(WxH5PayCreateOrderRequest request, MchInfo mchInfo)
{
//AlipayTradeWapPayModel
return "";
}
}
}
using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.Pay.AliPay
{
public class AliPayClient
{
public static readonly string url = "https://api.mch.weixin.qq.com";
IHttpClientFactory m_HttpClientFactory;
public AliPayClient(IHttpClientFactory _HttpClientFactory)
{
m_HttpClientFactory = _HttpClientFactory;
}
public async Task<string> PcPayCreateOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var APP_ID = "";
var APP_PRIVATE_KEY = "";
var CHARSET = "";
var ALIPAY_PUBLIC_KEY = "";
// 组装业务参数model
AlipayTradePagePayModel model = new AlipayTradePagePayModel
{
Body = request.Body,
Subject = request.Body,
TotalAmount = request.TotalFee.ToString(),
OutTradeNo = "",
ProductCode = "FAST_INSTANT_TRADE_PAY"//QUICK_WAP_PAY
};
AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();
// 设置同步回调地址
// aliRequest.SetReturnUrl($"http://{Request.Host}/Pay/Callback");
// 设置异步通知接收地址
aliRequest.SetNotifyUrl("");
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY);
var response = _aopClient.PageExecute(aliRequest);
return "";
}
public async Task<string> H5PayCreateOrderAsync(WxH5PayCreateOrderRequest request, MchInfo mchInfo)
{
//AlipayTradeWapPayModel
return "";
}
}
}

View File

@@ -1,54 +1,54 @@
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay
{
/// <summary>
/// 支付宝支付窗支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class AliJsPayRequest : WeiFuTongRequestBase
{
/// <summary>
/// 买家支付宝账号和buger_id不能同时为空
/// </summary>
[XmlElement("buyer_logon_id")]
public string BuyerLogonId { get; set; }
/// <summary>
/// 买家支付宝用户ID和buyer_logon_id不能同时
/// </summary>
[XmlElement("buyer_id")]
public string BuyerId { get; set; }
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")] public string NotifyUrl { get; set; }
public AliJsPayRequest() : base("pay.alipay.jspay")
{
}
}
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay
{
/// <summary>
/// 支付宝支付窗支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class AliJsPayRequest : WeiFuTongRequestBase
{
/// <summary>
/// 买家支付宝账号和buger_id不能同时为空
/// </summary>
[XmlElement("buyer_logon_id")]
public string BuyerLogonId { get; set; }
/// <summary>
/// 买家支付宝用户ID和buyer_logon_id不能同时
/// </summary>
[XmlElement("buyer_id")]
public string BuyerId { get; set; }
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")] public string NotifyUrl { get; set; }
public AliJsPayRequest() : base("pay.alipay.jspay")
{
}
}
}

View File

@@ -1,14 +1,14 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay
{
[XmlRoot("xml", Namespace = "")]
public class AliJsPayResponse: WeiFuTongResponseBase
{
/// <summary>
/// JSON字符串自行唤起支付宝钱包支付
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay
{
[XmlRoot("xml", Namespace = "")]
public class AliJsPayResponse: WeiFuTongResponseBase
{
/// <summary>
/// JSON字符串自行唤起支付宝钱包支付
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
}
}

View File

@@ -1,45 +1,45 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class AliJsPay
{
/// <summary>
/// 支付宝支付窗支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<AliJsPayResponse> AliJsPayCreateOrderAsync(this WeiFuTongClient weiFuTongClient
, AliJsPayRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace($"威富通-支付宝支付窗支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<AliJsPayResponse>(resText);
res.HandleError();
return res;
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.AliJsPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class AliJsPay
{
/// <summary>
/// 支付宝支付窗支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<AliJsPayResponse> AliJsPayCreateOrderAsync(this WeiFuTongClient weiFuTongClient
, AliJsPayRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace($"威富通-支付宝支付窗支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<AliJsPayResponse>(resText);
res.HandleError();
return res;
}
}
}

View File

@@ -1,56 +1,56 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.QrPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class QrPay
{
/// <summary>
/// 扫码支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<QrPayCreateOrderResponse> QrPayCreateOrderAsync(this WeiFuTongClient weiFuTongClient
, QrPayCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
string target = "";
if (request.Service == "pay.weixin.native")
{
target = "微信";
}
else if (request.Service == "pay.alipay.native")
{
target = "支付宝";
}
LogHelper.Trace($"威富通-{target}扫码支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<QrPayCreateOrderResponse>(resText);
res.HandleError();
return res;
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.QrPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class QrPay
{
/// <summary>
/// 扫码支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<QrPayCreateOrderResponse> QrPayCreateOrderAsync(this WeiFuTongClient weiFuTongClient
, QrPayCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
string target = "";
if (request.Service == "pay.weixin.native")
{
target = "微信";
}
else if (request.Service == "pay.alipay.native")
{
target = "支付宝";
}
LogHelper.Trace($"威富通-{target}扫码支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<QrPayCreateOrderResponse>(resText);
res.HandleError();
return res;
}
}
}

View File

@@ -1,49 +1,49 @@
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.QueryOrder;
using Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class QueryOrderExt
{
/// <summary>
/// 支付订单查询
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongQueryOrderResponse> QueryOrderAsync(this WeiFuTongClient weiFuTongClient
, WeiFuTongQueryOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
//LogHelper.Trace("威富通支付订单查询", log.ToString());
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException(response.StatusCode) {Content = resText};
}
Util.CheckSignFromXml(resText, request.MchInfo);
return XML.XmlDeserialize<WeiFuTongQueryOrderResponse>(resText);
}
}
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.QueryOrder;
using Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class QueryOrderExt
{
/// <summary>
/// 支付订单查询
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongQueryOrderResponse> QueryOrderAsync(this WeiFuTongClient weiFuTongClient
, WeiFuTongQueryOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
//LogHelper.Trace("威富通支付订单查询", log.ToString());
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException(response.StatusCode) {Content = resText};
}
Util.CheckSignFromXml(resText, request.MchInfo);
return XML.XmlDeserialize<WeiFuTongQueryOrderResponse>(resText);
}
}
}

View File

@@ -1,81 +1,81 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.Refund;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class RefundExt
{
/// <summary>
/// 退款请求
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongRefundResponse> RefundAsync(this WeiFuTongClient weiFuTongClient,
WeiFuTongRefundRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace($"威富通发起退款", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WeiFuTongRefundResponse>(resText);
res.HandleError();
return res;
}
/// <summary>
/// 退款查询
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongRefundQueryResponse> QueryRefundAsync(this WeiFuTongClient weiFuTongClient,
WeiFuTongRefundQueryRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
//LogHelper.Trace($"威富通-退款查询", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WeiFuTongRefundQueryResponse>(resText).ParseItemsFromXml(resText);
if (!(res.IsCancel() || res.IsNotExists()) && res.HasError())
{
res.HandleError();
}
return res;
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.Refund;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class RefundExt
{
/// <summary>
/// 退款请求
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongRefundResponse> RefundAsync(this WeiFuTongClient weiFuTongClient,
WeiFuTongRefundRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace($"威富通发起退款", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WeiFuTongRefundResponse>(resText);
res.HandleError();
return res;
}
/// <summary>
/// 退款查询
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WeiFuTongRefundQueryResponse> QueryRefundAsync(this WeiFuTongClient weiFuTongClient,
WeiFuTongRefundQueryRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
//LogHelper.Trace($"威富通-退款查询", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WeiFuTongRefundQueryResponse>(resText).ParseItemsFromXml(resText);
if (!(res.IsCancel() || res.IsNotExists()) && res.HasError())
{
res.HandleError();
}
return res;
}
}
}

View File

@@ -1,56 +1,56 @@
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class SwipeCard
{
/// <summary>
/// 刷卡支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns>need_query为Y时需要轮询查询支付状态不为Y则支付成功</returns>
public static async Task<SwipeCardCreateOrderResponse> SwipeCardCreateOrderAsync(
this WeiFuTongClient weiFuTongClient
, SwipeCardCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace("威富通-刷卡支付下单", log.ToString());
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException(response.StatusCode) {Content = resText};
}
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<SwipeCardCreateOrderResponse>(resText);
if (res.HasError() && res.NeedQuery != "Y" && res.NeedQuery != "")
{
res.HandleError();
}
return res;
}
}
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class SwipeCard
{
/// <summary>
/// 刷卡支付下单
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns>need_query为Y时需要轮询查询支付状态不为Y则支付成功</returns>
public static async Task<SwipeCardCreateOrderResponse> SwipeCardCreateOrderAsync(
this WeiFuTongClient weiFuTongClient
, SwipeCardCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
LogHelper.Trace("威富通-刷卡支付下单", log.ToString());
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException(response.StatusCode) {Content = resText};
}
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<SwipeCardCreateOrderResponse>(resText);
if (res.HasError() && res.NeedQuery != "Y" && res.NeedQuery != "")
{
res.HandleError();
}
return res;
}
}
}

View File

@@ -1,57 +1,57 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class WechatJsPay
{
/// <summary>
/// 微信小程序或公众号支付
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WechatJsPayCreateOrderResponse> WechatJsPayCreateOrderAsync(
this WeiFuTongClient weiFuTongClient
, WechatJsPayCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
string appEnv = "";
if (request.IsMinipg == "1")
{
appEnv = "小程序";
}
else
{
appEnv = "公众号";
}
LogHelper.Trace($"威富通-微信{appEnv}支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WechatJsPayCreateOrderResponse>(resText);
res.HandleError();
return res;
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.ClientExtension
{
public static class WechatJsPay
{
/// <summary>
/// 微信小程序或公众号支付
/// </summary>
/// <param name="weiFuTongClient"></param>
/// <param name="request"></param>
/// <returns></returns>
public static async Task<WechatJsPayCreateOrderResponse> WechatJsPayCreateOrderAsync(
this WeiFuTongClient weiFuTongClient
, WechatJsPayCreateOrderRequest request)
{
StringBuilder log = new StringBuilder();
var body = request.ToXml();
log.Append("请求:\r\n" + body);
var response = await weiFuTongClient.CreateHttpClient()
.PostAsync(request.PaymentChannel.GetUrl(), new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
log.Append("\r\n响应" + resText);
string appEnv = "";
if (request.IsMinipg == "1")
{
appEnv = "小程序";
}
else
{
appEnv = "公众号";
}
LogHelper.Trace($"威富通-微信{appEnv}支付下单", log.ToString());
Util.CheckSignFromXml(resText, request.MchInfo);
var res = XML.XmlDeserialize<WechatJsPayCreateOrderResponse>(resText);
res.HandleError();
return res;
}
}
}

View File

@@ -1,141 +1,141 @@
using System;
using System.Globalization;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Notify
{
[XmlRoot("xml", Namespace = "")]
public class NotifyResponse : WeiFuTongResponseBase
{
/// <summary>
/// 用户在服务商 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 交易类型
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 用户是否关注服务商公众账号Y-关注N-未关注
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 支付结果0—成功其它—失败
/// </summary>
[XmlElement("pay_result")]
public int PayResult { get; set; }
/// <summary>
/// 支付结果信息,支付成功时为空
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
using System;
using System.Globalization;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Notify
{
[XmlRoot("xml", Namespace = "")]
public class NotifyResponse : WeiFuTongResponseBase
{
/// <summary>
/// 用户在服务商 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 交易类型
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 用户是否关注服务商公众账号Y-关注N-未关注
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 支付结果0—成功其它—失败
/// </summary>
[XmlElement("pay_result")]
public int PayResult { get; set; }
/// <summary>
/// 支付结果信息,支付成功时为空
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
}

View File

@@ -1,40 +1,40 @@
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QrPay
{
[XmlRoot("xml", Namespace = "")]
public class QrPayCreateOrderRequest: WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
public QrPayCreateOrderRequest(string service) : base(service)
{
}
}
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QrPay
{
[XmlRoot("xml", Namespace = "")]
public class QrPayCreateOrderRequest: WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
public QrPayCreateOrderRequest(string service) : base(service)
{
}
}
}

View File

@@ -1,20 +1,20 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QrPay
{
[XmlRoot("xml", Namespace = "")]
public class QrPayCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 商户可用此参数自定义去生成二维码后展示出来进行扫码支付
/// </summary>
[XmlElement("code_url")]
public string CodeUrl { get; set; }
/// <summary>
/// 此参数的值即是根据code_url生成的可以扫码支付的二维码图片地址
/// </summary>
[XmlElement("code_img_url")]
public string CodeImgUrl { get; set; }
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QrPay
{
[XmlRoot("xml", Namespace = "")]
public class QrPayCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 商户可用此参数自定义去生成二维码后展示出来进行扫码支付
/// </summary>
[XmlElement("code_url")]
public string CodeUrl { get; set; }
/// <summary>
/// 此参数的值即是根据code_url生成的可以扫码支付的二维码图片地址
/// </summary>
[XmlElement("code_img_url")]
public string CodeImgUrl { get; set; }
}
}

View File

@@ -1,27 +1,27 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QueryOrder
{
/// <summary>
/// 威富通查询订单请求
/// </summary>
public class WeiFuTongQueryOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 平台交易号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先。
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
public WeiFuTongQueryOrderRequest()
: base("unified.trade.query")
{
}
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.QueryOrder
{
/// <summary>
/// 威富通查询订单请求
/// </summary>
public class WeiFuTongQueryOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 平台交易号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先。
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
public WeiFuTongQueryOrderRequest()
: base("unified.trade.query")
{
}
}
}

View File

@@ -1,221 +1,221 @@
using System;
using System.Globalization;
using System.Xml.Serialization;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付查询订单响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongQueryOrderResponse : WeiFuTongResponseBase
{
// 以下字段在 status 为 0的时候有返回
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 终端设备号
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
// 以下字段在 status 和 result_code 都为 0的时候有返回
/// <summary>
/// SUCCESS—支付成功
/// REFUND—转入退款
/// NOTPAY—未支付
/// CLOSED—已关闭
/// REVOKED/REVERSE—已撤销
/// USERPAYING—用户支付中
/// PAYERROR—支付失败(其他原因,如银行返回失败)
/// </summary>
[XmlElement("trade_state")]
public string TradeState { get; set; }
// 以下字段在 trade_state为 SUCCESS的时候有返回
/// <summary>
/// pay.wechat.micropay——微信刷卡支付
/// pay.alipay.micropay——支付宝刷卡支付
/// pay.jdpay.micropay——京东刷卡支付
/// pay.qq.micropay——QQ钱包刷卡支付
/// pay.shiming.micropay——会员卡支付
/// pay.unionpay.micropay——银联支付
/// pay.bestpay.micropay——翼支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 受理商户appid
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 用户在受理商户 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// 用户是否关注公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 开票金额 【支付宝】
/// </summary>
[XmlElement("invoice_amount")]
public string InvoiceAmount { get; set; }
/// <summary>
/// 实收金额【支付宝】实收金额,单位为元,两位小数。该金额为本笔交易,商户账户能够实际收到的金额
/// </summary>
[XmlElement("receipt_amount")]
public string ReceiptAmount { get; set; }
/// <summary>
/// 买家实付金额【支付宝】买家实付金额,单位为元,两位小数。该金额代表该笔交易买家实际支付的金额,不包含商户折扣等金额
/// </summary>
[XmlElement("buyer_pay_amount")]
public string BuyerPayAmount { get; set; }
/// <summary>
/// 集分宝付款金额【支付宝】
/// </summary>
[XmlElement("point_amount")]
public string PointAmount { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 是否支付成功
/// </summary>
/// <returns></returns>
public bool IsPaySuccess()
{
return !HasError() && (TradeState == "SUCCESS" || TradeState == "REFUND");
}
/// <summary>
/// 是否为支付失败,未支付和支付中不认定为失败
/// </summary>
/// <returns></returns>
public bool IsPayFailed()
{
return !HasError()
&& TradeState != "SUCCESS"
&& TradeState != "NOTPAY"
&& TradeState != "USERPAYING"
&& TradeState != "REFUND";
}
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
using System;
using System.Globalization;
using System.Xml.Serialization;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付查询订单响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongQueryOrderResponse : WeiFuTongResponseBase
{
// 以下字段在 status 为 0的时候有返回
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 终端设备号
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
// 以下字段在 status 和 result_code 都为 0的时候有返回
/// <summary>
/// SUCCESS—支付成功
/// REFUND—转入退款
/// NOTPAY—未支付
/// CLOSED—已关闭
/// REVOKED/REVERSE—已撤销
/// USERPAYING—用户支付中
/// PAYERROR—支付失败(其他原因,如银行返回失败)
/// </summary>
[XmlElement("trade_state")]
public string TradeState { get; set; }
// 以下字段在 trade_state为 SUCCESS的时候有返回
/// <summary>
/// pay.wechat.micropay——微信刷卡支付
/// pay.alipay.micropay——支付宝刷卡支付
/// pay.jdpay.micropay——京东刷卡支付
/// pay.qq.micropay——QQ钱包刷卡支付
/// pay.shiming.micropay——会员卡支付
/// pay.unionpay.micropay——银联支付
/// pay.bestpay.micropay——翼支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 受理商户appid
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 用户在受理商户 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// 用户是否关注公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 开票金额 【支付宝】
/// </summary>
[XmlElement("invoice_amount")]
public string InvoiceAmount { get; set; }
/// <summary>
/// 实收金额【支付宝】实收金额,单位为元,两位小数。该金额为本笔交易,商户账户能够实际收到的金额
/// </summary>
[XmlElement("receipt_amount")]
public string ReceiptAmount { get; set; }
/// <summary>
/// 买家实付金额【支付宝】买家实付金额,单位为元,两位小数。该金额代表该笔交易买家实际支付的金额,不包含商户折扣等金额
/// </summary>
[XmlElement("buyer_pay_amount")]
public string BuyerPayAmount { get; set; }
/// <summary>
/// 集分宝付款金额【支付宝】
/// </summary>
[XmlElement("point_amount")]
public string PointAmount { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 是否支付成功
/// </summary>
/// <returns></returns>
public bool IsPaySuccess()
{
return !HasError() && (TradeState == "SUCCESS" || TradeState == "REFUND");
}
/// <summary>
/// 是否为支付失败,未支付和支付中不认定为失败
/// </summary>
/// <returns></returns>
public bool IsPayFailed()
{
return !HasError()
&& TradeState != "SUCCESS"
&& TradeState != "NOTPAY"
&& TradeState != "USERPAYING"
&& TradeState != "REFUND";
}
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
}

View File

@@ -1,39 +1,39 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款查询请求
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundQueryRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 可传入平台订单号或第三方商户单号third_order_no, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户退款单号32个字符内、可包含字母,确保在商户系统唯一。
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号refund_id、out_refund_no、out_trade_no 、transaction_id 四个参数必填一个, 如果同时存在优先级为refund_id>out_refund_no>transaction_id>out_trade_no
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
public WeiFuTongRefundQueryRequest() : base("unified.trade.refundquery")
{
}
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款查询请求
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundQueryRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 可传入平台订单号或第三方商户单号third_order_no, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户退款单号32个字符内、可包含字母,确保在商户系统唯一。
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号refund_id、out_refund_no、out_trade_no 、transaction_id 四个参数必填一个, 如果同时存在优先级为refund_id>out_refund_no>transaction_id>out_trade_no
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
public WeiFuTongRefundQueryRequest() : base("unified.trade.refundquery")
{
}
}
}

View File

@@ -1,168 +1,168 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using Hncore.Infrastructure.Extension;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款查询响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundQueryResponse : WeiFuTongResponseBase
{
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户系统内部的订单号
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 退款记录数
/// </summary>
[XmlElement("refund_count")]
public int RefundCount { get; set; }
/// <summary>
/// 多笔退款详情
/// </summary>
public List<RefundQueryItem> RefundQueryItems { get; set; } = new List<RefundQueryItem>();
public WeiFuTongRefundQueryResponse ParseItemsFromXml(string xmlText)
{
if (RefundCount <= 0)
{
return this;
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(xmlText);
XmlNode root = xmlDoc.SelectSingleNode("xml");
for (int i = 0; i < RefundCount; i++)
{
RefundQueryItems.Add(new RefundQueryItem()
{
OutRefundNo = root.SelectSingleNode("out_refund_no_" + i).InnerText,
RefundId = root.SelectSingleNode("refund_id_" + i).InnerText,
RefundChannel = root.SelectSingleNode("refund_channel_" + i).InnerText,
RefundFee = root.SelectSingleNode("refund_fee_" + i).InnerText.ToInt(),
RefundTime = root.SelectSingleNode("refund_time_" + i).InnerText,
RefundStatus = root.SelectSingleNode("refund_status_" + i).InnerText
});
}
return this;
}
/// <summary>
/// 是否是退款成功
/// </summary>
/// <returns></returns>
public bool IsRefundSuccess()
{
return !HasError()
&& RefundQueryItems.Any()
&& RefundQueryItems.First().RefundStatus == "SUCCESS";
}
/// <summary>
/// 是否是退款失败
/// </summary>
/// <returns></returns>
public bool IsRefundFail()
{
return !HasError()
&& RefundQueryItems.Any()
&& RefundQueryItems.First().RefundStatus == "FAIL";
}
/// <summary>
/// 是否是已撤销
/// </summary>
/// <returns></returns>
public bool IsCancel()
{
return RefundCount == 0
&& ErrCode == "REFUND_FAIL"
&& ErrMsg.Contains("已撤销");
}
/// <summary>
/// 退款不存在
/// </summary>
/// <returns></returns>
public bool IsNotExists()
{
return HasError() &&
(
ErrCode.ToLower().Contains("refund not exists")
|| ErrCode.ToLower().Contains("order not exists")
|| ErrMsg.Contains("退款不存在")
|| ErrMsg.Contains("订单不存在")
);
}
public DateTime GetRefundSuccessTime()
{
DateTime.TryParseExact(RefundQueryItems.First().RefundTime, "yyyyMMddHHmmss", null, DateTimeStyles.None,
out var paySuccessTime);
return paySuccessTime;
}
}
public class RefundQueryItem
{
/// <summary>
/// 商户退款单号
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
/// <summary>
/// 退款渠道 ORIGINAL—原路退款默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
/// <summary>
/// 退款时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("refund_time")]
public string RefundTime { get; set; }
/// <summary>
/// SUCCESS—退款成功
/// FAIL—退款失败
/// PROCESSING—退款处理中
/// NOTSURE—未确定 需要商户原退款单号重新发起
/// CHANGE—转入代发退款到银行发现用户的卡作废或者冻结了导致原路退款银行卡失败资金回流到商户的现金帐号需要商户人工干预通过线下或者平台转账的方式进行退款。
/// </summary>
[XmlElement("refund_status")]
public string RefundStatus { get; set; }
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using Hncore.Infrastructure.Extension;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款查询响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundQueryResponse : WeiFuTongResponseBase
{
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户系统内部的订单号
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 退款记录数
/// </summary>
[XmlElement("refund_count")]
public int RefundCount { get; set; }
/// <summary>
/// 多笔退款详情
/// </summary>
public List<RefundQueryItem> RefundQueryItems { get; set; } = new List<RefundQueryItem>();
public WeiFuTongRefundQueryResponse ParseItemsFromXml(string xmlText)
{
if (RefundCount <= 0)
{
return this;
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(xmlText);
XmlNode root = xmlDoc.SelectSingleNode("xml");
for (int i = 0; i < RefundCount; i++)
{
RefundQueryItems.Add(new RefundQueryItem()
{
OutRefundNo = root.SelectSingleNode("out_refund_no_" + i).InnerText,
RefundId = root.SelectSingleNode("refund_id_" + i).InnerText,
RefundChannel = root.SelectSingleNode("refund_channel_" + i).InnerText,
RefundFee = root.SelectSingleNode("refund_fee_" + i).InnerText.ToInt(),
RefundTime = root.SelectSingleNode("refund_time_" + i).InnerText,
RefundStatus = root.SelectSingleNode("refund_status_" + i).InnerText
});
}
return this;
}
/// <summary>
/// 是否是退款成功
/// </summary>
/// <returns></returns>
public bool IsRefundSuccess()
{
return !HasError()
&& RefundQueryItems.Any()
&& RefundQueryItems.First().RefundStatus == "SUCCESS";
}
/// <summary>
/// 是否是退款失败
/// </summary>
/// <returns></returns>
public bool IsRefundFail()
{
return !HasError()
&& RefundQueryItems.Any()
&& RefundQueryItems.First().RefundStatus == "FAIL";
}
/// <summary>
/// 是否是已撤销
/// </summary>
/// <returns></returns>
public bool IsCancel()
{
return RefundCount == 0
&& ErrCode == "REFUND_FAIL"
&& ErrMsg.Contains("已撤销");
}
/// <summary>
/// 退款不存在
/// </summary>
/// <returns></returns>
public bool IsNotExists()
{
return HasError() &&
(
ErrCode.ToLower().Contains("refund not exists")
|| ErrCode.ToLower().Contains("order not exists")
|| ErrMsg.Contains("退款不存在")
|| ErrMsg.Contains("订单不存在")
);
}
public DateTime GetRefundSuccessTime()
{
DateTime.TryParseExact(RefundQueryItems.First().RefundTime, "yyyyMMddHHmmss", null, DateTimeStyles.None,
out var paySuccessTime);
return paySuccessTime;
}
}
public class RefundQueryItem
{
/// <summary>
/// 商户退款单号
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
/// <summary>
/// 退款渠道 ORIGINAL—原路退款默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
/// <summary>
/// 退款时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("refund_time")]
public string RefundTime { get; set; }
/// <summary>
/// SUCCESS—退款成功
/// FAIL—退款失败
/// PROCESSING—退款处理中
/// NOTSURE—未确定 需要商户原退款单号重新发起
/// CHANGE—转入代发退款到银行发现用户的卡作废或者冻结了导致原路退款银行卡失败资金回流到商户的现金帐号需要商户人工干预通过线下或者平台转账的方式进行退款。
/// </summary>
[XmlElement("refund_status")]
public string RefundStatus { get; set; }
}
}

View File

@@ -1,56 +1,56 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款请求
/// </summary>
public class WeiFuTongRefundRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 可传入平台订单号或第三方商户单号third_order_no, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户退款单号32个字符内、可包含字母,确保在商户系统唯一。同个退款单号多次请求,平台当一个单处理,只会退一次款。如果出现退款不成功,请采用原退款单号重新发起,避免出现重复退款。
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 订单总金额,单位为分
/// </summary>
[XmlElement("total_fee")]
public int OrderTotalFee { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
/// <summary>
/// 操作员帐号,默认为商户号
/// </summary>
[XmlElement("op_user_id")]
public string OpUserId => MchId;
/// <summary>
/// 退款渠道ORIGINAL-原路退款,默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel => "ORIGINAL";
public WeiFuTongRefundRequest() : base("unified.trade.refund")
{
}
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款请求
/// </summary>
public class WeiFuTongRefundRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 可传入平台订单号或第三方商户单号third_order_no, out_trade_no和transaction_id至少一个必填同时存在时transaction_id优先
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户退款单号32个字符内、可包含字母,确保在商户系统唯一。同个退款单号多次请求,平台当一个单处理,只会退一次款。如果出现退款不成功,请采用原退款单号重新发起,避免出现重复退款。
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 订单总金额,单位为分
/// </summary>
[XmlElement("total_fee")]
public int OrderTotalFee { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
/// <summary>
/// 操作员帐号,默认为商户号
/// </summary>
[XmlElement("op_user_id")]
public string OpUserId => MchId;
/// <summary>
/// 退款渠道ORIGINAL-原路退款,默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel => "ORIGINAL";
public WeiFuTongRefundRequest() : base("unified.trade.refund")
{
}
}
}

View File

@@ -1,47 +1,47 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundResponse : WeiFuTongResponseBase
{
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户系统内部的订单号
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商户退款单号
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
/// <summary>
/// 退款渠道 ORIGINAL—原路退款默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.Refund
{
/// <summary>
/// 威富通退款响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRefundResponse : WeiFuTongResponseBase
{
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 商户系统内部的订单号
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商户退款单号
/// </summary>
[XmlElement("out_refund_no")]
public string OutRefundNo { get; set; }
/// <summary>
/// 平台退款单号
/// </summary>
[XmlElement("refund_id")]
public string RefundId { get; set; }
/// <summary>
/// 退款渠道 ORIGINAL—原路退款默认
/// </summary>
[XmlElement("refund_channel")]
public string RefundChannel { get; set; }
/// <summary>
/// 退款总金额,单位为分,可以做部分退款
/// </summary>
[XmlElement("refund_fee")]
public int RefundFee { get; set; }
}
}

View File

@@ -1,55 +1,55 @@
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付下单请求
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class SwipeCardCreateOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 终端设备号商户自定义。特别说明对于QQ钱包支付此参数必传否则会报错。
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 扫码支付授权码, 设备读取用户展示的条码或者二维码信息
/// </summary>
[XmlElement("auth_code")]
public string AuthCode { get; set; }
public SwipeCardCreateOrderRequest()
: base("unified.trade.micropay")
{
}
}
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付下单请求
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class SwipeCardCreateOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 终端设备号商户自定义。特别说明对于QQ钱包支付此参数必传否则会报错。
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 扫码支付授权码, 设备读取用户展示的条码或者二维码信息
/// </summary>
[XmlElement("auth_code")]
public string AuthCode { get; set; }
public SwipeCardCreateOrderRequest()
: base("unified.trade.micropay")
{
}
}
}

View File

@@ -1,206 +1,206 @@
using System;
using System.Globalization;
using System.Xml.Serialization;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付下单响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class SwipeCardCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 用来判断是否需要调用查询接口值为Y时需要值为N时不需要
/// </summary>
[XmlElement("need_query")]
public string NeedQuery { get; set; }
//以下字段在 status 为 0的时候有返回
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 终端设备号
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
//以下字段在 status 和 result_code 都为 0的时候有返回
/// <summary>
/// 用户在受理商户 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// pay.wechat.micropay——微信刷卡支付
/// pay.alipay.micropay——支付宝刷卡支付
/// pay.jdpay.micropay——京东刷卡支付
/// pay.qq.micropay——QQ钱包刷卡支付
/// pay.shiming.micropay——会员卡支付
/// pay.unionpay.micropay——银联支付
/// pay.bestpay.micropay——翼支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 用户是否关注公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 支付结果0—成功其它—失败
/// </summary>
[XmlElement("pay_result")]
public int PayResult { get; set; }
/// <summary>
/// 支付结果信息,支付成功时为空
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 开票金额 【支付宝】
/// </summary>
[XmlElement("invoice_amount")]
public string InvoiceAmount { get; set; }
/// <summary>
/// 集分宝付款金额【支付宝】
/// </summary>
[XmlElement("point_amount")]
public string PointAmount { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 交易支付使用的资金渠道 【支付宝】
/// </summary>
[XmlElement("fund_bill_list")]
public string FundChannel { get; set; }
/// <summary>
/// 实收金额【支付宝】实收金额,单位为元,两位小数。该金额为本笔交易,商户账户能够实际收到的金额
/// </summary>
[XmlElement("receipt_amount")]
public string ReceiptAmount { get; set; }
/// <summary>
/// 买家实付金额【支付宝】买家实付金额,单位为元,两位小数。该金额代表该笔交易买家实际支付的金额,不包含商户折扣等金额
/// </summary>
[XmlElement("buyer_pay_amount")]
public string BuyerPayAmount { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
using System;
using System.Globalization;
using System.Xml.Serialization;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.SwipeCard
{
/// <summary>
/// 刷卡支付下单响应
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class SwipeCardCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 用来判断是否需要调用查询接口值为Y时需要值为N时不需要
/// </summary>
[XmlElement("need_query")]
public string NeedQuery { get; set; }
//以下字段在 status 为 0的时候有返回
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 终端设备号
/// </summary>
[XmlElement("device_info")]
public string DeviceInfo { get; set; }
//以下字段在 status 和 result_code 都为 0的时候有返回
/// <summary>
/// 用户在受理商户 appid 下的唯一标识
/// </summary>
[XmlElement("openid")]
public string OpenId { get; set; }
/// <summary>
/// 用户在子商户appid下的唯一标识
/// </summary>
[XmlElement("sub_openid")]
public string SubOpenId { get; set; }
/// <summary>
/// pay.wechat.micropay——微信刷卡支付
/// pay.alipay.micropay——支付宝刷卡支付
/// pay.jdpay.micropay——京东刷卡支付
/// pay.qq.micropay——QQ钱包刷卡支付
/// pay.shiming.micropay——会员卡支付
/// pay.unionpay.micropay——银联支付
/// pay.bestpay.micropay——翼支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; }
/// <summary>
/// 用户是否关注公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("is_subscribe")]
public string IsSubscribe { get; set; }
/// <summary>
/// 支付结果0—成功其它—失败
/// </summary>
[XmlElement("pay_result")]
public int PayResult { get; set; }
/// <summary>
/// 支付结果信息,支付成功时为空
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
/// <summary>
/// 平台交易号
/// </summary>
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 第三方订单号
/// </summary>
[XmlElement("out_transaction_id")]
public string OutTransactionId { get; set; }
/// <summary>
/// 第三方商户单号,可在支持的商户扫码退款
/// </summary>
[XmlElement("third_order_no")]
public string ThirdOrderNo { get; set; }
/// <summary>
/// 用户是否关注子公众账号Y-关注N-未关注,仅在公众账号类型支付有效
/// </summary>
[XmlElement("sub_is_subscribe")]
public string SubIsSubscribe { get; set; }
/// <summary>
/// 子商户appid
/// </summary>
[XmlElement("sub_appid")]
public string SubAppId { get; set; }
/// <summary>
/// 商户系统内部的定单号32个字符内、可包含字母
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 现金支付金额【微信】
/// </summary>
[XmlElement("cash_fee")]
public int CashFee { get; set; }
/// <summary>
/// 开票金额 【支付宝】
/// </summary>
[XmlElement("invoice_amount")]
public string InvoiceAmount { get; set; }
/// <summary>
/// 集分宝付款金额【支付宝】
/// </summary>
[XmlElement("point_amount")]
public string PointAmount { get; set; }
/// <summary>
/// 现金券金额【微信】
/// </summary>
[XmlElement("coupon_fee")]
public string CouponFee { get; set; }
/// <summary>
/// 交易支付使用的资金渠道 【支付宝】
/// </summary>
[XmlElement("fund_bill_list")]
public string FundChannel { get; set; }
/// <summary>
/// 实收金额【支付宝】实收金额,单位为元,两位小数。该金额为本笔交易,商户账户能够实际收到的金额
/// </summary>
[XmlElement("receipt_amount")]
public string ReceiptAmount { get; set; }
/// <summary>
/// 买家实付金额【支付宝】买家实付金额,单位为元,两位小数。该金额代表该笔交易买家实际支付的金额,不包含商户折扣等金额
/// </summary>
[XmlElement("buyer_pay_amount")]
public string BuyerPayAmount { get; set; }
/// <summary>
/// 货币类型,符合 ISO 4217 标准的三位字母代码默认人民币CNY
/// </summary>
[XmlElement("fee_type")]
public string FeeType { get; set; }
/// <summary>
/// 商家数据包,原样返回
/// </summary>
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 付款银行
/// </summary>
[XmlElement("bank_type")]
public string BankType { get; set; }
/// <summary>
/// 银行订单号,若为微信支付则为空
/// </summary>
[XmlElement("bank_billno")]
public string BankBillno { get; set; }
/// <summary>
/// 支付完成时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
/// </summary>
[XmlElement("time_end")]
public string TimeEnd { get; set; }
/// <summary>
/// 获取支付成功时间
/// </summary>
/// <returns></returns>
public DateTime GetPaySuccessTime()
{
DateTime.TryParseExact(TimeEnd, "yyyyMMddHHmmss", null, DateTimeStyles.None, out var paySuccessTime);
return paySuccessTime;
}
}
}

View File

@@ -1,100 +1,100 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.PaymentCenter.Model;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class Util
{
public static void CheckSignFromXml(string xmlText, MchInfo mchInfo)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(xmlText);
XmlNode root = xmlDoc.SelectSingleNode("xml");
XmlNodeList xnl = root.ChildNodes;
if (root.SelectSingleNode("status") == null || root.SelectSingleNode("status").InnerText != "0")
{
return;
}
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string responseSign = "";
string signType = "MD5";
foreach (XmlNode xnf in xnl)
{
var parameter = xnf.Name;
var parameterValue = xnf.InnerText;
if (parameter == "sign")
{
responseSign = parameterValue;
}
if (parameter == "sign_type")
{
signType = parameterValue;
}
if (parameter.Has() && parameterValue.Has() && parameter != "sign")
{
if (dic.Keys.Contains(parameter))
{
dic.Remove(parameter);
}
dic.Add(parameter, parameterValue);
}
}
string sign = "";
foreach (var item in dic)
{
sign += item.Key + "=" + item.Value + "&";
}
if (signType == "MD5" || string.IsNullOrEmpty(signType))
{
sign += "key=" + mchInfo.Key;
sign = SecurityHelper.GetMd5Hash(sign).ToUpper();
if (responseSign.ToUpper() != sign)
{
BusinessException.Throw("验签失败");
}
}
else if (signType == "RSA_1_1")
{
sign = sign.Substring(0, sign.Length - 1);
var verify = new RsaPkcs8Util(Encoding.UTF8
, mchInfo.RSAPublicKey
, mchInfo.RSAPrivateKey)
.VerifyData(sign, responseSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
if (!verify)
{
BusinessException.Throw("验签失败");
}
}
else
{
BusinessException.Throw("未知签名方式");
}
}
}
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.PaymentCenter.Model;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class Util
{
public static void CheckSignFromXml(string xmlText, MchInfo mchInfo)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(xmlText);
XmlNode root = xmlDoc.SelectSingleNode("xml");
XmlNodeList xnl = root.ChildNodes;
if (root.SelectSingleNode("status") == null || root.SelectSingleNode("status").InnerText != "0")
{
return;
}
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string responseSign = "";
string signType = "MD5";
foreach (XmlNode xnf in xnl)
{
var parameter = xnf.Name;
var parameterValue = xnf.InnerText;
if (parameter == "sign")
{
responseSign = parameterValue;
}
if (parameter == "sign_type")
{
signType = parameterValue;
}
if (parameter.Has() && parameterValue.Has() && parameter != "sign")
{
if (dic.Keys.Contains(parameter))
{
dic.Remove(parameter);
}
dic.Add(parameter, parameterValue);
}
}
string sign = "";
foreach (var item in dic)
{
sign += item.Key + "=" + item.Value + "&";
}
if (signType == "MD5" || string.IsNullOrEmpty(signType))
{
sign += "key=" + mchInfo.Key;
sign = SecurityHelper.GetMd5Hash(sign).ToUpper();
if (responseSign.ToUpper() != sign)
{
BusinessException.Throw("验签失败");
}
}
else if (signType == "RSA_1_1")
{
sign = sign.Substring(0, sign.Length - 1);
var verify = new RsaPkcs8Util(Encoding.UTF8
, mchInfo.RSAPublicKey
, mchInfo.RSAPrivateKey)
.VerifyData(sign, responseSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
if (!verify)
{
BusinessException.Throw("验签失败");
}
}
else
{
BusinessException.Throw("未知签名方式");
}
}
}
}

View File

@@ -1,67 +1,67 @@
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WechatJsPayCreateOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("is_raw")]
public string IsRaw { get; set; } = "1";
/// <summary>
/// 值为1表示小程序支付不传或值不为1表示公众账号内支付
/// </summary>
[XmlElement("is_minipg")]
public string IsMinipg { get; set; }
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 微信用户关注商家公众号的openid
/// </summary>
[XmlElement("sub_openid")]
public string UserOpenId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("sub_appid")]
public string AppId { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
public WechatJsPayCreateOrderRequest() : base("pay.weixin.jspay")
{
}
}
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WechatJsPayCreateOrderRequest : WeiFuTongRequestBase
{
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("is_raw")]
public string IsRaw { get; set; } = "1";
/// <summary>
/// 值为1表示小程序支付不传或值不为1表示公众账号内支付
/// </summary>
[XmlElement("is_minipg")]
public string IsMinipg { get; set; }
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 微信用户关注商家公众号的openid
/// </summary>
[XmlElement("sub_openid")]
public string UserOpenId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("sub_appid")]
public string AppId { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("mch_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
public WechatJsPayCreateOrderRequest() : base("pay.weixin.jspay")
{
}
}
}

View File

@@ -1,14 +1,14 @@
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay
{
[XmlRoot("xml", Namespace = "")]
public class WechatJsPayCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 原生态js支付信息或小程序支付信息
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
}
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WeiFuTong.WechatJsPay
{
[XmlRoot("xml", Namespace = "")]
public class WechatJsPayCreateOrderResponse : WeiFuTongResponseBase
{
/// <summary>
/// 原生态js支付信息或小程序支付信息
/// </summary>
[XmlElement("pay_info")]
public string PayInfo { get; set; }
}
}

View File

@@ -1,26 +1,26 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class WeiFuTongClient
{
private IHttpClientFactory _httpClientFactory;
public WeiFuTongClient(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public HttpClient CreateHttpClient()
{
var httpClient = _httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromMinutes(5);
return httpClient;
}
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class WeiFuTongClient
{
private IHttpClientFactory _httpClientFactory;
public WeiFuTongClient(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public HttpClient CreateHttpClient()
{
var httpClient = _httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromMinutes(5);
return httpClient;
}
}
}

View File

@@ -1,32 +1,32 @@
using Hncore.Infrastructure.Data;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class WeiFuTongConfig
{
public const string WeiFuTongUrl = "https://pay.hstypay.com/v2/pay/gateway";
public const string QuanFuTongUrl = "https://pay.swiftpass.cn/pay/gateway";
}
public static class Extension
{
public static string GetUrl(this PaymentChannel paymentChannel)
{
if (paymentChannel == PaymentChannel.WeiFuTong)
{
return WeiFuTongConfig.WeiFuTongUrl;
}
if (paymentChannel == PaymentChannel.QuanFuTong)
{
return WeiFuTongConfig.QuanFuTongUrl;
}
BusinessException.Throw("未知支付渠道");
return "";
}
}
using Hncore.Infrastructure.Data;
using Hncore.Pass.PaymentCenter.Domain;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
public class WeiFuTongConfig
{
public const string WeiFuTongUrl = "https://pay.hstypay.com/v2/pay/gateway";
public const string QuanFuTongUrl = "https://pay.swiftpass.cn/pay/gateway";
}
public static class Extension
{
public static string GetUrl(this PaymentChannel paymentChannel)
{
if (paymentChannel == PaymentChannel.WeiFuTong)
{
return WeiFuTongConfig.WeiFuTongUrl;
}
if (paymentChannel == PaymentChannel.QuanFuTong)
{
return WeiFuTongConfig.QuanFuTongUrl;
}
BusinessException.Throw("未知支付渠道");
return "";
}
}
}

View File

@@ -1,42 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongDTOBase
{
/// <summary>
/// 随机字符串,不长于 32 位
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; } = Guid.NewGuid().ToString().Replace("-", "");
/// <summary>
/// 签名类型取值MD5默认MD5
/// </summary>
[XmlElement("sign_type")]
public string SignType { get; set; } = "MD5";
/// <summary>
/// MD5签名结果
/// </summary>
[XmlElement("sign")]
public string Sign { get; set; }
/// <summary>
/// 版本号version默认值是2.0
/// </summary>
[XmlElement("version")]
public string Version { get; set; } = "2.0";
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongDTOBase
{
/// <summary>
/// 随机字符串,不长于 32 位
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; } = Guid.NewGuid().ToString().Replace("-", "");
/// <summary>
/// 签名类型取值MD5默认MD5
/// </summary>
[XmlElement("sign_type")]
public string SignType { get; set; } = "MD5";
/// <summary>
/// MD5签名结果
/// </summary>
[XmlElement("sign")]
public string Sign { get; set; }
/// <summary>
/// 版本号version默认值是2.0
/// </summary>
[XmlElement("version")]
public string Version { get; set; } = "2.0";
}
}

View File

@@ -1,156 +1,156 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using Hncore.Pass.PaymentCenter.Domain;
using Hncore.Pass.PaymentCenter.Model;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRequestBase : WeiFuTongDTOBase
{
/// <summary>
/// 接口类型
/// </summary>
[XmlElement("service")]
public string Service { get; set; }
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; private set; }
/// <summary>
/// 连锁商户号
/// </summary>
[XmlElement("groupno")]
public string GroupNo { get; private set; }
/// <summary>
/// 可选值 UTF-8 ,默认为 UTF-8
/// </summary>
[XmlElement("charset")]
public string Charset { get; set; } = "UTF-8";
private MchInfo _mchInfo;
public MchInfo MchInfo
{
get => _mchInfo;
set
{
_mchInfo = value;
MchId = value.MchId;
GroupNo = value.GroupNo;
}
}
private PaymentChannel _paymentChannel;
public PaymentChannel PaymentChannel
{
get => _paymentChannel;
set
{
_paymentChannel = value;
if (value == PaymentChannel.QuanFuTong)
{
SignType = "RSA_1_1";
}
}
}
public WeiFuTongRequestBase(string service)
{
Service = service;
}
protected virtual SortedDictionary<string, string> ToSortDic()
{
var type = GetType();
var properties = type.GetProperties();
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
foreach (var property in properties)
{
var xmlAttr = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
if (!xmlAttr.Any())
{
continue;
}
string name = ((XmlElementAttribute) xmlAttr[0]).ElementName;
object valueObj = property.GetValue(this, null);
if (valueObj == null)
{
continue;
}
string value = valueObj.ToString();
if (!string.IsNullOrEmpty(value))
{
dic[name] = value;
}
}
return dic;
}
protected virtual void CreateSign(MchInfo mchInfo)
{
Sign = "";
string sign = "";
foreach (var item in ToSortDic())
{
sign += item.Key + "=" + item.Value + "&";
}
if (SignType == "MD5")
{
sign += "key=" + mchInfo.Key;
sign = SecurityHelper.GetMd5Hash(sign).ToUpper();
}
else if (SignType == "RSA_1_1")
{
sign = sign.Substring(0, sign.Length - 1);
sign = new RsaPkcs8Util(Encoding.UTF8
, mchInfo.RSAPublicKey
, mchInfo.RSAPrivateKey)
.SignData(sign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
Sign = sign;
}
public string ToXml()
{
CreateSign(MchInfo);
StringBuilder sb = new StringBuilder("<xml>\n");
foreach (var item in ToSortDic())
{
string key = item.Key;
sb.Append("\t<").Append(key).Append("><![CDATA[").Append(item.Value).Append("]]></").Append(key)
.Append(">\n");
}
return sb.Append("</xml>").ToString();
}
}
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using Hncore.Infrastructure.Common;
using Hncore.Pass.PaymentCenter.Domain;
using Hncore.Pass.PaymentCenter.Model;
using XC.RSAUtil;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongRequestBase : WeiFuTongDTOBase
{
/// <summary>
/// 接口类型
/// </summary>
[XmlElement("service")]
public string Service { get; set; }
/// <summary>
/// 门店编号,由平台分配
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; private set; }
/// <summary>
/// 连锁商户号
/// </summary>
[XmlElement("groupno")]
public string GroupNo { get; private set; }
/// <summary>
/// 可选值 UTF-8 ,默认为 UTF-8
/// </summary>
[XmlElement("charset")]
public string Charset { get; set; } = "UTF-8";
private MchInfo _mchInfo;
public MchInfo MchInfo
{
get => _mchInfo;
set
{
_mchInfo = value;
MchId = value.MchId;
GroupNo = value.GroupNo;
}
}
private PaymentChannel _paymentChannel;
public PaymentChannel PaymentChannel
{
get => _paymentChannel;
set
{
_paymentChannel = value;
if (value == PaymentChannel.QuanFuTong)
{
SignType = "RSA_1_1";
}
}
}
public WeiFuTongRequestBase(string service)
{
Service = service;
}
protected virtual SortedDictionary<string, string> ToSortDic()
{
var type = GetType();
var properties = type.GetProperties();
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
foreach (var property in properties)
{
var xmlAttr = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
if (!xmlAttr.Any())
{
continue;
}
string name = ((XmlElementAttribute) xmlAttr[0]).ElementName;
object valueObj = property.GetValue(this, null);
if (valueObj == null)
{
continue;
}
string value = valueObj.ToString();
if (!string.IsNullOrEmpty(value))
{
dic[name] = value;
}
}
return dic;
}
protected virtual void CreateSign(MchInfo mchInfo)
{
Sign = "";
string sign = "";
foreach (var item in ToSortDic())
{
sign += item.Key + "=" + item.Value + "&";
}
if (SignType == "MD5")
{
sign += "key=" + mchInfo.Key;
sign = SecurityHelper.GetMd5Hash(sign).ToUpper();
}
else if (SignType == "RSA_1_1")
{
sign = sign.Substring(0, sign.Length - 1);
sign = new RsaPkcs8Util(Encoding.UTF8
, mchInfo.RSAPublicKey
, mchInfo.RSAPrivateKey)
.SignData(sign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
Sign = sign;
}
public string ToXml()
{
CreateSign(MchInfo);
StringBuilder sb = new StringBuilder("<xml>\n");
foreach (var item in ToSortDic())
{
string key = item.Key;
sb.Append("\t<").Append(key).Append("><![CDATA[").Append(item.Value).Append("]]></").Append(key)
.Append(">\n");
}
return sb.Append("</xml>").ToString();
}
}
}

View File

@@ -1,66 +1,66 @@
using System.Xml.Serialization;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Extension;
using Newtonsoft.Json;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongResponseBase : WeiFuTongDTOBase
{
/// <summary>
/// 0表示成功非0表示失败此字段是通信标识非交易标识交易是否成功需要查看 result_code 来判断
/// </summary>
[XmlElement("status")]
public string Status { get; set; }
/// <summary>
/// 返回信息,如非空,为错误原因签名失败参数格式校验错误
/// </summary>
[XmlElement("message")]
public string Message { get; set; }
/// <summary>
/// 业务结果 0表示成功非0表示失败
/// </summary>
[XmlElement("result_code")]
public string ResultCode { get; set; }
/// <summary>
/// 错误代码
/// </summary>
[XmlElement("err_code")]
public string ErrCode { get; set; }
/// <summary>
/// 错误代码描述
/// </summary>
[XmlElement("err_msg")]
public string ErrMsg { get; set; }
/// <summary>
/// 可选值 UTF-8 ,默认为 UTF-8
/// </summary>
[JsonIgnore]
[XmlElement("charset")]
public string Charset { get; set; }
public virtual bool HasError()
{
return Status != "0" || ResultCode != "0";
}
public virtual void HandleError()
{
if (Status != "0")
{
BusinessException.Throw($"支付平台通讯失败,status:{Status},message:{Message}");
}
if (ResultCode != "0")
{
BusinessException.Throw($"支付平台业务处理失败,result_code:{ResultCode},err_msg:{ErrMsg }");
}
}
}
using System.Xml.Serialization;
using Hncore.Infrastructure.Data;
using Hncore.Infrastructure.Extension;
using Newtonsoft.Json;
namespace Hncore.Pass.PaymentCenter.WeiFuTong
{
[XmlRoot("xml", Namespace = "")]
public class WeiFuTongResponseBase : WeiFuTongDTOBase
{
/// <summary>
/// 0表示成功非0表示失败此字段是通信标识非交易标识交易是否成功需要查看 result_code 来判断
/// </summary>
[XmlElement("status")]
public string Status { get; set; }
/// <summary>
/// 返回信息,如非空,为错误原因签名失败参数格式校验错误
/// </summary>
[XmlElement("message")]
public string Message { get; set; }
/// <summary>
/// 业务结果 0表示成功非0表示失败
/// </summary>
[XmlElement("result_code")]
public string ResultCode { get; set; }
/// <summary>
/// 错误代码
/// </summary>
[XmlElement("err_code")]
public string ErrCode { get; set; }
/// <summary>
/// 错误代码描述
/// </summary>
[XmlElement("err_msg")]
public string ErrMsg { get; set; }
/// <summary>
/// 可选值 UTF-8 ,默认为 UTF-8
/// </summary>
[JsonIgnore]
[XmlElement("charset")]
public string Charset { get; set; }
public virtual bool HasError()
{
return Status != "0" || ResultCode != "0";
}
public virtual void HandleError()
{
if (Status != "0")
{
BusinessException.Throw($"支付平台通讯失败,status:{Status},message:{Message}");
}
if (ResultCode != "0")
{
BusinessException.Throw($"支付平台业务处理失败,result_code:{ResultCode},err_msg:{ErrMsg }");
}
}
}
}

View File

@@ -1,91 +1,91 @@
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信扫码付款
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxH5PayCreateOrderRequest : WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// H5支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "MWEB";
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 商品Id
/// </summary>
[XmlElement("product_id")]
public string ProductId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxH5PayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信扫码付款
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxH5PayCreateOrderRequest : WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// H5支付
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "MWEB";
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 商品Id
/// </summary>
[XmlElement("product_id")]
public string ProductId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxH5PayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
}

View File

@@ -1,88 +1,88 @@
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayCreateOrderRequest: WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "JSAPI";//NATIVE
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 微信用户关注商家公众号的openid
/// </summary>
[XmlElement("openid")]
public string UserOpenId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxJsPayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayCreateOrderRequest: WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "JSAPI";//NATIVE
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 微信用户关注商家公众号的openid
/// </summary>
[XmlElement("openid")]
public string UserOpenId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxJsPayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
}

View File

@@ -1,20 +1,20 @@
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Newtonsoft.Json;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxJsPayCreateOrderResponse: WxJsPayDataBase
{
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
public string nonceStr { get; set; }
public string prepay_id { get; set; }
public string signType { get; set; }
public string paySign { get; set; }
[JsonIgnore]
public string package => $"prepay_id={this.prepay_id}";
}
}
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Newtonsoft.Json;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxJsPayCreateOrderResponse: WxJsPayDataBase
{
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
public string nonceStr { get; set; }
public string prepay_id { get; set; }
public string signType { get; set; }
public string paySign { get; set; }
[JsonIgnore]
public string package => $"prepay_id={this.prepay_id}";
}
}

View File

@@ -1,166 +1,166 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付H5支付 数据签名校验
/// </summary>
public class WxPayChecker: SortedDictionary<string, string>
{
public string SignType { get; set; } = "MD5";// "HMAC-SHA256";
public string MchKey { get; set; }
/**
* 生成时间戳标准北京时间时区为东八区自1970年1月1日 0点0分0秒以来的秒数
* @return 时间戳
*/
public string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/**
* 生成随机串,随机串包含字母或数字
* @return 随机串
*/
public string GenerateNonceStr()
{
return Guid.NewGuid().ToString("N");
}
public virtual string CreateSign()
{
string sign = "";
foreach (var item in this)
{
if (item.Key == "sign"|| item.Key == "paySign") continue;
sign += item.Key + "=" + item.Value + "&";
}
if(this.MchKey.Has())
sign += "key=" + this.MchKey;
LogHelper.Trace("CreateSign Str", sign);
if (SignType == "MD5")
{
sign = SecurityHelper.GetMd5Hash(sign);
}
else if (SignType == "HMAC-SHA256")
{
sign = CalcHMACSHA256Hash(sign, this.MchKey);
}
this["sign"] = sign;
return sign;
}
public bool IsSet(string key)
{
if (!this.ContainsKey(key)) return false;
return this[key].Has();
}
public virtual bool CheckSign()
{
//如果没有设置签名,则跳过检测
if (!this.IsSet("sign"))
{
LogHelper.Error("CheckSign", "签名不存在!");
return false;
}
//获取接收到的签名
string return_sign = this["sign"];
//在本地计算新的签名
string cal_sign = CreateSign();
if (cal_sign == return_sign)
{
return true;
}
return true;
}
private string CalcHMACSHA256Hash(string plaintext, string salt)
{
string result = "";
var enc = Encoding.Default;
byte[]
baText2BeHashed = enc.GetBytes(plaintext),
baSalt = enc.GetBytes(salt);
System.Security.Cryptography.HMACSHA256 hasher = new HMACSHA256(baSalt);
byte[] baHashedText = hasher.ComputeHash(baText2BeHashed);
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x2")).ToArray());
return result;
}
public string ToXml()
{
CreateSign();
StringBuilder sb = new StringBuilder("<xml>\n");
foreach (var item in this)
{
string key = item.Key;
sb.Append("\t<").Append(key).Append("><![CDATA[").Append(item.Value).Append("]]></").Append(key)
.Append(">\n");
}
return sb.Append("</xml>").ToString();
}
public WxPayChecker FromXml(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
if (!CheckSign())
{
return null;
}
return this;
}
public WxPayChecker FromXmlNoCheckSign(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
return this;
}
}
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付H5支付 数据签名校验
/// </summary>
public class WxPayChecker: SortedDictionary<string, string>
{
public string SignType { get; set; } = "MD5";// "HMAC-SHA256";
public string MchKey { get; set; }
/**
* 生成时间戳标准北京时间时区为东八区自1970年1月1日 0点0分0秒以来的秒数
* @return 时间戳
*/
public string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/**
* 生成随机串,随机串包含字母或数字
* @return 随机串
*/
public string GenerateNonceStr()
{
return Guid.NewGuid().ToString("N");
}
public virtual string CreateSign()
{
string sign = "";
foreach (var item in this)
{
if (item.Key == "sign"|| item.Key == "paySign") continue;
sign += item.Key + "=" + item.Value + "&";
}
if(this.MchKey.Has())
sign += "key=" + this.MchKey;
LogHelper.Trace("CreateSign Str", sign);
if (SignType == "MD5")
{
sign = SecurityHelper.GetMd5Hash(sign);
}
else if (SignType == "HMAC-SHA256")
{
sign = CalcHMACSHA256Hash(sign, this.MchKey);
}
this["sign"] = sign;
return sign;
}
public bool IsSet(string key)
{
if (!this.ContainsKey(key)) return false;
return this[key].Has();
}
public virtual bool CheckSign()
{
//如果没有设置签名,则跳过检测
if (!this.IsSet("sign"))
{
LogHelper.Error("CheckSign", "签名不存在!");
return false;
}
//获取接收到的签名
string return_sign = this["sign"];
//在本地计算新的签名
string cal_sign = CreateSign();
if (cal_sign == return_sign)
{
return true;
}
return true;
}
private string CalcHMACSHA256Hash(string plaintext, string salt)
{
string result = "";
var enc = Encoding.Default;
byte[]
baText2BeHashed = enc.GetBytes(plaintext),
baSalt = enc.GetBytes(salt);
System.Security.Cryptography.HMACSHA256 hasher = new HMACSHA256(baSalt);
byte[] baHashedText = hasher.ComputeHash(baText2BeHashed);
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x2")).ToArray());
return result;
}
public string ToXml()
{
CreateSign();
StringBuilder sb = new StringBuilder("<xml>\n");
foreach (var item in this)
{
string key = item.Key;
sb.Append("\t<").Append(key).Append("><![CDATA[").Append(item.Value).Append("]]></").Append(key)
.Append(">\n");
}
return sb.Append("</xml>").ToString();
}
public WxPayChecker FromXml(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
if (!CheckSign())
{
return null;
}
return this;
}
public WxPayChecker FromXmlNoCheckSign(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
return this;
}
}
}

View File

@@ -1,51 +1,51 @@
using System;
using System.Linq;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付 数据签名校验
/// </summary>
public class WxJsPayDataBase
{
public string GenerateNonceStr()
{
return Guid.NewGuid().ToString("N");
}
public WxPayChecker ToPayData()
{
var type = GetType();
var properties = type.GetProperties();
var data = new WxPayChecker();
foreach (var property in properties)
{
var xmlAttr = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
if (!xmlAttr.Any())
{
continue;
}
string name = ((XmlElementAttribute)xmlAttr[0]).ElementName;
object valueObj = property.GetValue(this, null);
if (valueObj == null)
{
continue;
}
string value = valueObj.ToString();
if (!string.IsNullOrEmpty(value))
{
data[name] = value;
}
}
return data;
}
}
using System;
using System.Linq;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付 数据签名校验
/// </summary>
public class WxJsPayDataBase
{
public string GenerateNonceStr()
{
return Guid.NewGuid().ToString("N");
}
public WxPayChecker ToPayData()
{
var type = GetType();
var properties = type.GetProperties();
var data = new WxPayChecker();
foreach (var property in properties)
{
var xmlAttr = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
if (!xmlAttr.Any())
{
continue;
}
string name = ((XmlElementAttribute)xmlAttr[0]).ElementName;
object valueObj = property.GetValue(this, null);
if (valueObj == null)
{
continue;
}
string value = valueObj.ToString();
if (!string.IsNullOrEmpty(value))
{
data[name] = value;
}
}
return data;
}
}
}

View File

@@ -1,50 +1,50 @@
using Hncore.Infrastructure.Extension;
using System;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付 数据签名校验
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayInfo: WxJsPayDataBase
{
public WxJsPayInfo(string appId,string signType,string package,string key)
{
this.appId = appId;
this.signType = signType;
this.package = package;
this.nonceStr = this.GenerateNonceStr();
this.timeStamp = DateTime.Now.GetUnixTimeStamp().ToString();
this.key = key;
}
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
[XmlElement("nonceStr")]
public string nonceStr { get; set; }
[XmlElement("signType")]
public string signType { get; set; }
[XmlElement("package")]
public string package { get; set; }
private string key;
public string paySign => getSign();
private string getSign()
{
var data = this.ToPayData();
data.SignType = this.signType;
data.MchKey = this.key;
return data.CreateSign();
}
}
using Hncore.Infrastructure.Extension;
using System;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付 数据签名校验
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayInfo: WxJsPayDataBase
{
public WxJsPayInfo(string appId,string signType,string package,string key)
{
this.appId = appId;
this.signType = signType;
this.package = package;
this.nonceStr = this.GenerateNonceStr();
this.timeStamp = DateTime.Now.GetUnixTimeStamp().ToString();
this.key = key;
}
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
[XmlElement("nonceStr")]
public string nonceStr { get; set; }
[XmlElement("signType")]
public string signType { get; set; }
[XmlElement("package")]
public string package { get; set; }
private string key;
public string paySign => getSign();
private string getSign()
{
var data = this.ToPayData();
data.SignType = this.signType;
data.MchKey = this.key;
return data.CreateSign();
}
}
}

View File

@@ -1,39 +1,39 @@
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayOrderQueryRequest : WxJsPayDataBase
{
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
public WxJsPayOrderQueryRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxJsPayOrderQueryRequest : WxJsPayDataBase
{
[XmlElement("transaction_id")]
public string TransactionId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
public WxJsPayOrderQueryRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
}

View File

@@ -1,161 +1,161 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxPayClient
{
public static readonly string url = "https://api.mch.weixin.qq.com";
IHttpClientFactory m_HttpClientFactory;
public WxPayClient(IHttpClientFactory _HttpClientFactory)
{
m_HttpClientFactory = _HttpClientFactory;
}
public async Task<string> CreatePayOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("prepay_id"))
{
return "";
}
var appId = payData["appid"];
var package = $"prepay_id={payData["prepay_id"]}";
var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);
return resp.ToJson();
}
public async Task<string> JsPayCreateOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("prepay_id"))
{
return "";
}
var appId = payData["appid"];
var package = $"prepay_id={payData["prepay_id"]}";
var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);
return resp.ToJson();
}
public async Task<string> ScanPayCreateOrderAsync(WxScanPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
LogHelper.Info("ScanPayCreateOrderAsync body", body);
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("code_url"))
{
return "";
}
var code_url = payData["code_url"];
return code_url;
}
public async Task<string> H5PayCreateOrderAsync(WxH5PayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("H5PayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("mweb_url"))
{
return "";
}
var code_url = payData["mweb_url"];
return code_url;
}
public async Task<bool> OrderQuery(WxJsPayOrderQueryRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
request.MchId = mchInfo.MchId;
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/orderquery", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData["return_code"].ToString() == "SUCCESS" &&
payData["result_code"].ToString() == "SUCCESS")
{
return true;
}
else
{
return false;
}
}
}
}
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxPayClient
{
public static readonly string url = "https://api.mch.weixin.qq.com";
IHttpClientFactory m_HttpClientFactory;
public WxPayClient(IHttpClientFactory _HttpClientFactory)
{
m_HttpClientFactory = _HttpClientFactory;
}
public async Task<string> CreatePayOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("prepay_id"))
{
return "";
}
var appId = payData["appid"];
var package = $"prepay_id={payData["prepay_id"]}";
var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);
return resp.ToJson();
}
public async Task<string> JsPayCreateOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("prepay_id"))
{
return "";
}
var appId = payData["appid"];
var package = $"prepay_id={payData["prepay_id"]}";
var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);
return resp.ToJson();
}
public async Task<string> ScanPayCreateOrderAsync(WxScanPayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
LogHelper.Info("ScanPayCreateOrderAsync body", body);
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("code_url"))
{
return "";
}
var code_url = payData["code_url"];
return code_url;
}
public async Task<string> H5PayCreateOrderAsync(WxH5PayCreateOrderRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/unifiedorder", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData.IsSet("err_code_des"))
{
LogHelper.Error("H5PayCreateOrderAsync Error", payData["err_code_des"]);
return "";
}
if (!payData.IsSet("mweb_url"))
{
return "";
}
var code_url = payData["mweb_url"];
return code_url;
}
public async Task<bool> OrderQuery(WxJsPayOrderQueryRequest request, MchInfo mchInfo)
{
var httpClient = m_HttpClientFactory.CreateClient();
request.MchId = mchInfo.MchId;
var payData = request.ToPayData();
payData.MchKey = mchInfo.Key;
var body = payData.ToXml();
httpClient.Timeout = TimeSpan.FromMinutes(5);
var response = await httpClient
.PostAsync($"{url}/pay/orderquery", new StringContent(body));
var resText = await response.Content.ReadAsStringAsync();
payData.FromXml(resText);
if (payData["return_code"].ToString() == "SUCCESS" &&
payData["result_code"].ToString() == "SUCCESS")
{
return true;
}
else
{
return false;
}
}
}
}

View File

@@ -1,91 +1,91 @@
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信扫码付款
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxScanPayCreateOrderRequest : WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "NATIVE";
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 商品Id
/// </summary>
[XmlElement("product_id")]
public string ProductId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxScanPayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
using Hncore.Infrastructure.Common;
using System.Xml;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信扫码付款
/// </summary>
[XmlRoot("xml", Namespace = "")]
public class WxScanPayCreateOrderRequest : WxJsPayDataBase
{
/// <summary>
/// 商户系统内部的订单号 ,5到32个字符、 只能包含字母数字或者下划线,区分大小写,每次下单请求确保在商户系统唯一
/// </summary>
[XmlElement("out_trade_no")]
public string OutTradeNo { get; set; }
[XmlElement("attach")]
public string Attach { get; set; }
/// <summary>
/// 商品描述
/// </summary>
[XmlElement("body")]
public string Body { get; set; }
/// <summary>
/// 总金额,以分为单位,不允许包含任何字、符号
/// </summary>
[XmlElement("total_fee")]
public int TotalFee { get; set; }
/// <summary>
/// 原生JS
/// </summary>
[XmlElement("trade_type")]
public string TradeType { get; set; } = "NATIVE";
[XmlElement("notify_url")]
public string NotifyUrl { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("appid")]
public string AppId { get; set; }
/// <summary>
/// 公众账号或小程序ID
/// </summary>
[XmlElement("mch_id")]
public string MchId { get; set; }
/// <summary>
/// 订单生成的机器 IP
/// </summary>
[XmlElement("spbill_create_ip")]
public string MchCreateIp { get; set; } = NetworkHelper.GetPublicIp();
/// <summary>
/// 商品Id
/// </summary>
[XmlElement("product_id")]
public string ProductId { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
[XmlElement("nonce_str")]
public string NonceStr { get; set; }
/// <summary>
/// 绝对过期时间 yyyyMMddHHmmss
/// </summary>
[XmlElement("time_expire")]
public string TimeExpire { get; set; }
public int TenantId { get; set; }
public int StoreId { get; set; }
public WxScanPayCreateOrderRequest()
{
this.NonceStr =this.GenerateNonceStr();
}
}
}

View File

@@ -1,20 +1,20 @@
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Newtonsoft.Json;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxScanPayCreateOrderResponse : WxJsPayDataBase
{
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
public string nonceStr { get; set; }
public string prepay_id { get; set; }
public string signType { get; set; }
public string paySign { get; set; }
[JsonIgnore]
public string package => $"prepay_id={this.prepay_id}";
}
}
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Newtonsoft.Json;
using System.Xml.Serialization;
namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
public class WxScanPayCreateOrderResponse : WxJsPayDataBase
{
[XmlElement("appId")]
public string appId { get; set; }
[XmlElement("timeStamp")]
public string timeStamp { get; set; }
public string nonceStr { get; set; }
public string prepay_id { get; set; }
public string signType { get; set; }
public string paySign { get; set; }
[JsonIgnore]
public string package => $"prepay_id={this.prepay_id}";
}
}