mirror of
https://github.com/Varorbc/PaySharp.git
synced 2026-10-16 20:31:04 +08:00
添加银联商务网关
This commit is contained in:
@@ -38,6 +38,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PaySharp.Allinpay", "src\PaySharp.Allinpay\PaySharp.Allinpay.csproj", "{5D183F2A-BBB4-4B3E-9951-4584A70ECB60}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PaySharp.Netpay", "src\PaySharp.Netpay\PaySharp.Netpay.csproj", "{1F2BA5BA-6915-4D5C-AD42-55AF4A42FCB2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -84,6 +86,10 @@ Global
|
||||
{5D183F2A-BBB4-4B3E-9951-4584A70ECB60}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5D183F2A-BBB4-4B3E-9951-4584A70ECB60}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5D183F2A-BBB4-4B3E-9951-4584A70ECB60}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1F2BA5BA-6915-4D5C-AD42-55AF4A42FCB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1F2BA5BA-6915-4D5C-AD42-55AF4A42FCB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1F2BA5BA-6915-4D5C-AD42-55AF4A42FCB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1F2BA5BA-6915-4D5C-AD42-55AF4A42FCB2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -360,9 +360,23 @@ namespace PaySharp.Core
|
||||
/// <returns></returns>
|
||||
public string ToUrl(bool isUrlEncode = true)
|
||||
{
|
||||
return string.Join("&",
|
||||
_values
|
||||
.Select(a => $"{a.Key}={(isUrlEncode ? WebUtility.UrlEncode(a.Value.ToString()) : a.Value.ToString())}"));
|
||||
var values = _values.Select(a =>
|
||||
{
|
||||
var value = a.Value.ToString();
|
||||
if (a.Value is bool)
|
||||
{
|
||||
value = value.ToLower();
|
||||
}
|
||||
|
||||
if (isUrlEncode)
|
||||
{
|
||||
value = WebUtility.UrlEncode(value);
|
||||
}
|
||||
|
||||
return $"{a.Key}={value}";
|
||||
});
|
||||
|
||||
return string.Join("&", values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Utils;
|
||||
|
||||
namespace PaySharp.Netpay.Domain
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础模型
|
||||
/// </summary>
|
||||
public class BaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息编号
|
||||
/// </summary>
|
||||
[StringLength(64, ErrorMessage = "消息编号最大长度为64位")]
|
||||
public string MsgId { get; set; } = Util.GenerateNonceStr();
|
||||
|
||||
/// <summary>
|
||||
/// 消息类型
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 微信:wx.appPreOrder(存量商户需改为新的msgType)
|
||||
/// 支付宝:trade.precreate
|
||||
/// 全民付:qmf.order
|
||||
/// 银联云闪付(走银联全渠道):uac.appOrder
|
||||
/// ApplePay支付:applepay.order
|
||||
/// 查询订单:query
|
||||
/// </remarks>
|
||||
[Required(ErrorMessage = "请设置消息类型")]
|
||||
[StringLength(64, MinimumLength = 1, ErrorMessage = "消息类型,最小长度为1位,最大长度为64位")]
|
||||
public string MsgType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文请求时间
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请设置报文请求时间")]
|
||||
public string RequestTimestamp { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/// <summary>
|
||||
/// 商户的交易订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "merOrderId")]
|
||||
[StringLength(32, MinimumLength = 6, ErrorMessage = "商户的交易订单号,最小长度为6位,最大长度为32位")]
|
||||
[Required(ErrorMessage = "请设置商户的交易订单号")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求系统预留字段
|
||||
/// </summary>
|
||||
public string SrcReserve { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace PaySharp.Netpay.Domain
|
||||
{
|
||||
/// <summary>
|
||||
/// 商品模型
|
||||
/// </summary>
|
||||
public class Goods
|
||||
{
|
||||
/// <summary>
|
||||
/// 折扣
|
||||
/// </summary>
|
||||
public long Discount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public string Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品编号
|
||||
/// </summary>
|
||||
[ReName(Name = "goodsId")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品名称
|
||||
/// </summary>
|
||||
[ReName(Name = "goodsName")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品数量
|
||||
/// </summary>
|
||||
public long Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品单价(分)
|
||||
/// </summary>
|
||||
public long Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品分类
|
||||
/// </summary>
|
||||
[ReName(Name = "goodsCategory")]
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品说明
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "subMerchantId")]
|
||||
public string SubMchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户子订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "merOrderId")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子商户商品总额
|
||||
/// </summary>
|
||||
[ReName(Name = "subOrderAmount")]
|
||||
public int TotalAmount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace PaySharp.Netpay.Domain
|
||||
{
|
||||
public class QueryModel : BaseModel, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 交易单号
|
||||
/// </summary>
|
||||
[ReName(Name = "targetOrderId")]
|
||||
public string TradeNo { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (string.IsNullOrEmpty(OutTradeNo) && string.IsNullOrEmpty(TradeNo))
|
||||
{
|
||||
yield return new ValidationResult("商户订单号和交易单号不能同时为空");
|
||||
}
|
||||
|
||||
yield return ValidationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace PaySharp.Netpay.Domain
|
||||
{
|
||||
public class SubOrders
|
||||
{
|
||||
/// <summary>
|
||||
/// 子商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "mid")]
|
||||
public string MchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户子订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "merOrderId")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子商户分账金额
|
||||
/// </summary>
|
||||
public int TotalAmount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace PaySharp.Netpay.Domain
|
||||
{
|
||||
public class UnifiedPayModel : BaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 商品信息
|
||||
/// </summary>
|
||||
public Goods Goods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户附加数据
|
||||
/// </summary>
|
||||
[StringLength(255, ErrorMessage = "商户附加数据最大长度为64位")]
|
||||
public string AttachedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单过期时间
|
||||
/// </summary>
|
||||
public string ExpireTime { get; set; } = DateTime.Now.AddMinutes(30).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/// <summary>
|
||||
/// 商品标记,用于优惠活动
|
||||
/// </summary>
|
||||
[StringLength(32, ErrorMessage = "商品标记最大长度为32位")]
|
||||
public string GoodsTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品交易单号
|
||||
/// 跟goods字段二选一,商品信息通过goods.add接口提前上送
|
||||
/// </summary>
|
||||
public string GoodsTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品描述
|
||||
/// </summary>
|
||||
[ReName(Name = "orderDesc")]
|
||||
[StringLength(255, ErrorMessage = "商品描述最大长度为255位")]
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单原始金额,单位分,用于记录前端系统打折前的金额
|
||||
/// </summary>
|
||||
public int OriginalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品编号
|
||||
/// </summary>
|
||||
public string ProductId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付总金额,单位为分
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 若<see cref="DivisionFlag"/>为true,则:totalAmount = subOrders字段中的所有totalAmount值之和
|
||||
/// 加上platformAmount值 = goods中的所有subOrderAmount值之和。
|
||||
/// </remarks>
|
||||
public int TotalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分账标记
|
||||
/// 暂时只支持微信(WXPay.jsPay)、支付宝(trade.jsPay)支付 和 银联云闪付(uac.appOrder)
|
||||
/// 若为true,则goods字段和subOrders字段不能同时为空;且secureTransaction字段上送false或不上送。
|
||||
/// </summary>
|
||||
public bool DivisionFlag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台商户分账金额
|
||||
/// </summary>
|
||||
/// <remarks>若分账标记传,则分账金额必传</remarks>
|
||||
public int? PlatformAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在传分账标记的情况下,若传子商户号,子商户分账金额必传,即ubOrders每个元素的mid和totalAmount非空 且 mid不超过20个。
|
||||
/// 分账方案subOrders里子商户分账总额+platformAmount要与支付总额totalAmount相等
|
||||
/// </summary>
|
||||
public SubOrders SubOrders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易类型
|
||||
/// 微信必传:APP
|
||||
/// </summary>
|
||||
public string TradeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户用户号
|
||||
/// </summary>
|
||||
[ReName(Name = "merchantUserId")]
|
||||
[StringLength(32, ErrorMessage = "商户用户号最大长度为32位")]
|
||||
public string MchUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[StringLength(11, ErrorMessage = "手机号最大长度为11位")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标识是否是担保交易
|
||||
/// 若上送为true,则交易的金额将会被暂缓结算。
|
||||
/// 调用担保完成接口后,完成部分金额会在t+1日结算给商户,剩余部分金额退还用户。
|
||||
/// 调用担保撤销接口,则全部资金退还给用户。
|
||||
/// 30天后 没有主动调用担保完成 且 没有主动调用担保撤销的交易 将会自动按撤销处理。
|
||||
/// </summary>
|
||||
public bool SecureTransaction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要限制信用卡支付
|
||||
/// </summary>
|
||||
public bool LimitCreditCard { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace PaySharp.Netpay
|
||||
{
|
||||
public class Merchant : IMerchant
|
||||
{
|
||||
#region 属性
|
||||
|
||||
/// <summary>
|
||||
/// 终端号
|
||||
/// </summary>
|
||||
[ReName(Name = "tid")]
|
||||
[Required(ErrorMessage = "请输入终端号")]
|
||||
[StringLength(32, MinimumLength = 2, ErrorMessage = "终端号最大长度为32位")]
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信子AppId
|
||||
/// </summary>
|
||||
/// <remarks>只对微信支付有效</remarks>
|
||||
[StringLength(32, ErrorMessage = "微信子AppId最大长度为32位")]
|
||||
public string SubAppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "mid")]
|
||||
[Required(ErrorMessage = "请设置商户号")]
|
||||
[StringLength(32, MinimumLength = 8, ErrorMessage = "商户号最大长度为32位")]
|
||||
public string MchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "instMid")]
|
||||
[StringLength(32, MinimumLength = 8, ErrorMessage = "机构商户号最大长度为32位")]
|
||||
public string InstMchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MD5交易密钥
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请设置MD5交易密钥")]
|
||||
[Ignore]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源
|
||||
/// </summary>
|
||||
[ReName(Name = "msgSrc")]
|
||||
[Required(ErrorMessage = "请设置来源")]
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名类型
|
||||
/// </summary>
|
||||
public string SignType => "MD5";
|
||||
|
||||
/// <summary>
|
||||
/// 返回地址
|
||||
/// </summary>
|
||||
[ReName(Name = "showUrl")]
|
||||
public string ReturnUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网关回发通知URL
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请输入网关回发通知URL")]
|
||||
public string NotifyUrl { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
#if NETCOREAPP3_1
|
||||
using Microsoft.Extensions.Options;
|
||||
#endif
|
||||
using System.Threading.Tasks;
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Exceptions;
|
||||
using PaySharp.Core.Request;
|
||||
using PaySharp.Core.Utils;
|
||||
using PaySharp.Netpay.Response;
|
||||
|
||||
namespace PaySharp.Netpay
|
||||
{
|
||||
/// <summary>
|
||||
/// 银联商务网关
|
||||
/// </summary>
|
||||
public sealed class NetpayGateway : BaseGateway
|
||||
{
|
||||
#region 私有字段
|
||||
|
||||
private readonly Merchant _merchant;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
|
||||
/// <summary>
|
||||
/// 初始化银联商务网关
|
||||
/// </summary>
|
||||
/// <param name="merchant">商户数据</param>
|
||||
public NetpayGateway(Merchant merchant)
|
||||
: base(merchant)
|
||||
{
|
||||
_merchant = merchant;
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
|
||||
/// <summary>
|
||||
/// 初始化银联商务网关
|
||||
/// </summary>
|
||||
/// <param name="merchant">商户数据</param>
|
||||
public NetpayGateway(IOptions<Merchant> merchant)
|
||||
: this(merchant.Value)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
|
||||
public override string GatewayUrl { get; set; } = "https://qr.chinaums.com";
|
||||
|
||||
public new NotifyResponse NotifyResponse => (NotifyResponse)base.NotifyResponse;
|
||||
|
||||
protected override bool IsPaySuccess => NotifyResponse.TradeStatus == "TRADE_SUCCESS";
|
||||
|
||||
protected override bool IsRefundSuccess => NotifyResponse.TradeStatus == "TRADE_REFUND";
|
||||
|
||||
protected override bool IsCancelSuccess { get; }
|
||||
|
||||
protected override string[] NotifyVerifyParameter => new string[]
|
||||
{
|
||||
"tid", "mid", "merOrderId"
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
|
||||
protected override async Task<bool> ValidateNotifyAsync()
|
||||
{
|
||||
base.NotifyResponse = await GatewayData.ToObjectAsync<NotifyResponse>(StringCase.Camel);
|
||||
base.NotifyResponse.Raw = GatewayData.Raw;
|
||||
|
||||
if (!SubmitProcess.CheckSign(GatewayData, _merchant.Key, NotifyResponse.Sign))
|
||||
{
|
||||
throw new GatewayException("签名不一致");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void WriteSuccessFlag()
|
||||
{
|
||||
HttpUtil.Write("SUCCESS");
|
||||
}
|
||||
|
||||
protected override void WriteFailureFlag()
|
||||
{
|
||||
HttpUtil.Write("FAILED");
|
||||
}
|
||||
|
||||
public override TResponse Execute<TModel, TResponse>(Request<TModel, TResponse> request)
|
||||
{
|
||||
return SubmitProcess.Execute(_merchant, request, GatewayUrl);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="../../package.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netcoreapp3.1</TargetFrameworks>
|
||||
<Title>PaySharp.Netpay</Title>
|
||||
<Description>通联收银宝</Description>
|
||||
<PackageTags>dotnetcore;pay;Netpay;</PackageTags>
|
||||
<PackageReleaseNotes>
|
||||
</PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../../output.props" />
|
||||
|
||||
<Import Project="../../dependencies.props" />
|
||||
|
||||
</Project>
|
||||
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
#if NET45
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using PaySharp.Netpay;
|
||||
|
||||
namespace PaySharp.Core.Mvc
|
||||
{
|
||||
public static class PaySharpConfigExtensions
|
||||
{
|
||||
public static IGateways RegisterNetpay(this IGateways gateways, Action<Merchant> action)
|
||||
{
|
||||
if (action != null)
|
||||
{
|
||||
var merchant = new Merchant();
|
||||
action(merchant);
|
||||
gateways.Add(new NetpayGateway(merchant));
|
||||
}
|
||||
|
||||
return gateways;
|
||||
}
|
||||
|
||||
public static IGateways RegisterNetpay(this IGateways gateways)
|
||||
{
|
||||
var merchants = (List<Hashtable>)ConfigurationManager.GetSection("paySharp/Netpays");
|
||||
if (merchants == null)
|
||||
{
|
||||
return gateways;
|
||||
}
|
||||
|
||||
foreach (var item in merchants)
|
||||
{
|
||||
var netpayGateway = new NetpayGateway(new Merchant
|
||||
{
|
||||
AppId = item["appId"].ToString(),
|
||||
SubAppId = item["subAppId"].ToString(),
|
||||
MchId = item["mchId"].ToString(),
|
||||
InstMchId = item["instMchId"].ToString(),
|
||||
Key = item["key"].ToString(),
|
||||
Source = item["source"].ToString(),
|
||||
NotifyUrl = item["notifyUrl"].ToString(),
|
||||
ReturnUrl = item["returnUrl"].ToString()
|
||||
});
|
||||
|
||||
var gatewayUrl = item["gatewayUrl"].ToString();
|
||||
if (!string.IsNullOrEmpty(gatewayUrl))
|
||||
{
|
||||
netpayGateway.GatewayUrl = gatewayUrl;
|
||||
}
|
||||
|
||||
gateways.Add(netpayGateway);
|
||||
}
|
||||
|
||||
return gateways;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
using PaySharp.Core.Request;
|
||||
using PaySharp.Core.Response;
|
||||
using PaySharp.Core.Utils;
|
||||
|
||||
namespace PaySharp.Netpay.Request
|
||||
{
|
||||
public class BaseRequest<TModel, TResponse> : Request<TModel, TResponse> where TResponse : IResponse
|
||||
{
|
||||
public BaseRequest()
|
||||
{
|
||||
RequestUrl = "/netpay-route-server/api/";
|
||||
}
|
||||
|
||||
public override void AddGatewayData(TModel model)
|
||||
{
|
||||
base.AddGatewayData(model);
|
||||
|
||||
GatewayData.Add(model, StringCase.Camel);
|
||||
}
|
||||
|
||||
internal virtual void Execute(Merchant merchant)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(NotifyUrl))
|
||||
{
|
||||
GatewayData.Add("notifyUrl", NotifyUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using PaySharp.Netpay.Domain;
|
||||
using PaySharp.Netpay.Response;
|
||||
|
||||
namespace PaySharp.Netpay.Request
|
||||
{
|
||||
public class QueryRequest : BaseRequest<QueryModel, QueryResponse>
|
||||
{
|
||||
internal override void Execute(Merchant merchant)
|
||||
{
|
||||
GatewayData.Remove("notifyUrl");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using PaySharp.Netpay.Domain;
|
||||
using PaySharp.Netpay.Response;
|
||||
|
||||
namespace PaySharp.Netpay.Request
|
||||
{
|
||||
public class UnifiedPayRequest : BaseRequest<UnifiedPayModel, UnifiedPayResponse>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Request;
|
||||
using PaySharp.Core.Response;
|
||||
|
||||
namespace PaySharp.Netpay.Response
|
||||
{
|
||||
public abstract class BaseResponse : IResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 平台错误码
|
||||
/// </summary>
|
||||
public string ErrCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台错误信息
|
||||
/// </summary>
|
||||
public string ErrMsg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息编号
|
||||
/// </summary>
|
||||
public string MsgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源
|
||||
/// </summary>
|
||||
[ReName(Name = "msgSrc")]
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息类型
|
||||
/// </summary>
|
||||
public string MsgType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求系统预留字段
|
||||
/// </summary>
|
||||
public string SrcReserve { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报文响应时间
|
||||
/// </summary>
|
||||
public string ResponseTimestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户名称
|
||||
/// </summary>
|
||||
[ReName(Name = "merName")]
|
||||
public string MchName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "mid")]
|
||||
public string MchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "merOrderId")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终端号
|
||||
/// </summary>
|
||||
[ReName(Name = "tid")]
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台流水号
|
||||
/// </summary>
|
||||
[ReName(Name = "seqId")]
|
||||
public string TradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 清分ID,如果来源方传了bankRefId就等于bankRefId,否则等于seqId
|
||||
/// </summary>
|
||||
public string SettleRefId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易状态
|
||||
/// NEW_ORDER 新订单
|
||||
/// UNKNOWN 不明确的交易状态
|
||||
/// TRADE_CLOSED 在指定时间段内未支付时关闭的交易;在交易完成撤销成功时关闭的交易;支付失败的交易。
|
||||
/// WAIT_BUYER_PAY 交易创建,等待买家付款。
|
||||
/// TRADE_SUCCESS 支付成功
|
||||
/// TRADE_REFUND 订单转入退货流程
|
||||
/// </summary>
|
||||
[ReName(Name = "status")]
|
||||
public string TradeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付总金额
|
||||
/// </summary>
|
||||
public int TotalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接系统
|
||||
/// </summary>
|
||||
public string ConnectSys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "targetOrderId")]
|
||||
public string ChannelTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道代码
|
||||
/// Alipay 1.0 支付宝1.0协议
|
||||
/// Alipay 2.0 支付宝2.0协议
|
||||
/// WXPay 微信
|
||||
/// YQB 壹钱包
|
||||
/// QMF 全民付远程快捷
|
||||
/// UnionPay 银联钱包
|
||||
/// BaiDu 百度钱包
|
||||
/// JD 京东钱包
|
||||
/// SF 顺丰顺手付
|
||||
/// COMM 交通银行
|
||||
/// BestPay 翼支付
|
||||
/// ACP 银联全渠道立码付
|
||||
/// NetPayBills 银商网付平台账单模块
|
||||
/// NetPayGtwy 银商网付平台网关模块
|
||||
/// QmfWebPay POS通插件WEB版
|
||||
/// UAC 银联全渠道
|
||||
/// </summary>
|
||||
[ReName(Name = "targetSys")]
|
||||
public string ChannelCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道状态
|
||||
/// </summary>
|
||||
[ReName(Name = "targetStatus")]
|
||||
public string ChannelStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "targetMid")]
|
||||
public string ChannelMchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 营销联盟优惠金额
|
||||
/// </summary>
|
||||
[ReName(Name = "yxlmAmount")]
|
||||
public int MarketingAffiliateAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// </summary>
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原始值
|
||||
/// </summary>
|
||||
public string Raw { get; set; }
|
||||
|
||||
internal GatewayData GatewayData { get; set; }
|
||||
|
||||
internal abstract void Execute<TModel, TResponse>(Merchant merchant, Request<TModel, TResponse> request) where TResponse : IResponse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Response;
|
||||
|
||||
namespace PaySharp.Netpay.Response
|
||||
{
|
||||
public class NotifyResponse : IResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "mid")]
|
||||
public string MchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终端号
|
||||
/// </summary>
|
||||
[ReName(Name = "tid")]
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "instMid")]
|
||||
public string InstMchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户附加数据
|
||||
/// </summary>
|
||||
public string AttachedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 银行卡号
|
||||
/// </summary>
|
||||
public string BankCardNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道列表
|
||||
/// </summary>
|
||||
public string BillFunds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道描述
|
||||
/// </summary>
|
||||
public string BillFundsDesc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家编号
|
||||
/// </summary>
|
||||
public string BuyerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子买家编号
|
||||
/// </summary>
|
||||
public string SubBuyerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家用户名
|
||||
/// </summary>
|
||||
public string BuyerUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家付款的金额
|
||||
/// </summary>
|
||||
public int BuyerPayAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付总金额
|
||||
/// </summary>
|
||||
public int TotalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发票金额
|
||||
/// </summary>
|
||||
public int InvoiceAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实收金额
|
||||
/// </summary>
|
||||
public int ReceiptAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款金额
|
||||
/// </summary>
|
||||
public int RefundAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款说明
|
||||
/// </summary>
|
||||
public string RefundDesc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道退款号
|
||||
/// </summary>
|
||||
[ReName(Name = "refundTargetOrderId")]
|
||||
public string ChannelRefundNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款时间
|
||||
/// </summary>
|
||||
[ReName(Name = "refundPayTime")]
|
||||
public DateTime? RefundTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款结算日期
|
||||
/// </summary>
|
||||
[ReName(Name = "refundPayTime")]
|
||||
public DateTime? RefundSettleDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "merOrderId")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付时间
|
||||
/// </summary>
|
||||
public DateTime PayTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检索参考号,用在银联体系交易中
|
||||
/// </summary>
|
||||
public string RefId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平台流水号
|
||||
/// </summary>
|
||||
[ReName(Name = "seqId")]
|
||||
public string TradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结算日期
|
||||
/// </summary>
|
||||
public DateTime SettleDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易状态
|
||||
/// NEW_ORDER 新订单
|
||||
/// UNKNOWN 不明确的交易状态
|
||||
/// TRADE_CLOSED 在指定时间段内未支付时关闭的交易;在交易完成撤销成功时关闭的交易;支付失败的交易。
|
||||
/// WAIT_BUYER_PAY 交易创建,等待买家付款。
|
||||
/// TRADE_SUCCESS 支付成功
|
||||
/// TRADE_REFUND 订单转入退货流程
|
||||
/// </summary>
|
||||
[ReName(Name = "status")]
|
||||
public string TradeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接系统
|
||||
/// </summary>
|
||||
public string ConnectSys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道订单号
|
||||
/// </summary>
|
||||
[ReName(Name = "targetOrderId")]
|
||||
public string ChannelTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道代码
|
||||
/// Alipay 1.0 支付宝1.0协议
|
||||
/// Alipay 2.0 支付宝2.0协议
|
||||
/// WXPay 微信
|
||||
/// YQB 壹钱包
|
||||
/// QMF 全民付远程快捷
|
||||
/// UnionPay 银联钱包
|
||||
/// BaiDu 百度钱包
|
||||
/// JD 京东钱包
|
||||
/// SF 顺丰顺手付
|
||||
/// COMM 交通银行
|
||||
/// BestPay 翼支付
|
||||
/// ACP 银联全渠道立码付
|
||||
/// NetPayBills 银商网付平台账单模块
|
||||
/// NetPayGtwy 银商网付平台网关模块
|
||||
/// QmfWebPay POS通插件WEB版
|
||||
/// UAC 银联全渠道
|
||||
/// </summary>
|
||||
[ReName(Name = "targetSys")]
|
||||
public string ChannelCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 营销联盟优惠金额
|
||||
/// </summary>
|
||||
[ReName(Name = "yxlmAmount")]
|
||||
public int MarketingAffiliateAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// </summary>
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户出资优惠金额
|
||||
/// </summary>
|
||||
public int CouponMerchantContribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 其他出资优惠金额
|
||||
/// </summary>
|
||||
public int CouponOtherContribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信活动编号
|
||||
/// </summary>
|
||||
public string ActivityIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单详情
|
||||
/// </summary>
|
||||
[ReName(Name = "orderDesc")]
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public string CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户UUID
|
||||
/// </summary>
|
||||
[ReName(Name = "mchntUuid")]
|
||||
public string MchUuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户所属分支机构代码
|
||||
/// </summary>
|
||||
public string SubInst { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退货外部订单号
|
||||
/// </summary>
|
||||
public string RefundExtOrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商品交易单号
|
||||
/// </summary>
|
||||
public string GoodsTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外部订单号
|
||||
/// </summary>
|
||||
public string ExtOrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 担保交易状态
|
||||
/// </summary>
|
||||
public string SecureStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 担保完成金额
|
||||
/// </summary>
|
||||
public string CompleteAmount { get; set; }
|
||||
|
||||
public string Raw { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Request;
|
||||
|
||||
namespace PaySharp.Netpay.Response
|
||||
{
|
||||
public class QueryResponse : BaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 机构商户号
|
||||
/// </summary>
|
||||
[ReName(Name = "instMid")]
|
||||
public string InstMchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检索参考号,用在银联体系交易中
|
||||
/// </summary>
|
||||
public string RefId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家编号
|
||||
/// </summary>
|
||||
public string BuyerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子买家编号
|
||||
/// </summary>
|
||||
public string SubBuyerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家用户名
|
||||
/// </summary>
|
||||
public string BuyerUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 买家付款的金额
|
||||
/// </summary>
|
||||
public int BuyerPayAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 银行卡号
|
||||
/// </summary>
|
||||
public string BankCardNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 银行信息
|
||||
/// </summary>
|
||||
public string BankInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道列表
|
||||
/// </summary>
|
||||
public string BillFunds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道描述
|
||||
/// </summary>
|
||||
public string BillFundsDesc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠金额
|
||||
/// </summary>
|
||||
public int CouponAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发票金额
|
||||
/// </summary>
|
||||
public int InvoiceAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实收金额
|
||||
/// </summary>
|
||||
public int ReceiptAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款金额
|
||||
/// </summary>
|
||||
public int RefundAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付时间
|
||||
/// </summary>
|
||||
public DateTime PayTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结算日期
|
||||
/// </summary>
|
||||
public DateTime SettleDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信活动编号
|
||||
/// </summary>
|
||||
public string ActivityIds { get; set; }
|
||||
|
||||
internal override void Execute<TModel, TResponse>(Merchant merchant, Request<TModel, TResponse> request)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using PaySharp.Core.Request;
|
||||
|
||||
namespace PaySharp.Netpay.Response
|
||||
{
|
||||
public class UnifiedPayResponse : BaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// JSAPI支付用的请求报文,带有签名信息
|
||||
/// </summary>
|
||||
public string JsPayRequest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// APP支付用的请求报文,带有签名信息
|
||||
/// </summary>
|
||||
public string AppPayRequest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付ID,用于APP支付和公众号支付
|
||||
/// </summary>
|
||||
public string PrepayId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付二维码,内容为URL,由终端转换成二维码显示
|
||||
/// </summary>
|
||||
public string QrCode { get; set; }
|
||||
|
||||
internal override void Execute<TModel, TResponse>(Merchant merchant, Request<TModel, TResponse> request)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#if NETCOREAPP3_1
|
||||
using System;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using PaySharp.Netpay;
|
||||
using PaySharp.Core;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IGateways UseNetpay(this IGateways gateways, Action<Merchant> action)
|
||||
{
|
||||
if (action != null)
|
||||
{
|
||||
var merchant = new Merchant();
|
||||
action(merchant);
|
||||
gateways.Add(new NetpayGateway(merchant));
|
||||
}
|
||||
|
||||
return gateways;
|
||||
}
|
||||
|
||||
public static IGateways UseNetpay(this IGateways gateways, IConfiguration configuration)
|
||||
{
|
||||
var merchants = configuration.GetSection("PaySharp:Netpays").Get<Merchant[]>();
|
||||
if (merchants != null)
|
||||
{
|
||||
for (var i = 0; i < merchants.Length; i++)
|
||||
{
|
||||
var netpayGateway = new NetpayGateway(merchants[i]);
|
||||
var gatewayUrl = configuration.GetSection($"PaySharp:Netpays:{i}:GatewayUrl").Value;
|
||||
if (!string.IsNullOrEmpty(gatewayUrl))
|
||||
{
|
||||
netpayGateway.GatewayUrl = gatewayUrl;
|
||||
}
|
||||
|
||||
gateways.Add(netpayGateway);
|
||||
}
|
||||
}
|
||||
|
||||
return gateways;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
using PaySharp.Core;
|
||||
using PaySharp.Core.Exceptions;
|
||||
using PaySharp.Core.Request;
|
||||
using PaySharp.Core.Response;
|
||||
using PaySharp.Core.Utils;
|
||||
using PaySharp.Netpay.Request;
|
||||
using PaySharp.Netpay.Response;
|
||||
|
||||
namespace PaySharp.Netpay
|
||||
{
|
||||
internal static class SubmitProcess
|
||||
{
|
||||
private static string _gatewayUrl;
|
||||
|
||||
internal static TResponse Execute<TModel, TResponse>(Merchant merchant, Request<TModel, TResponse> request, string gatewayUrl = null) where TResponse : IResponse
|
||||
{
|
||||
AddMerchant(merchant, request, gatewayUrl);
|
||||
|
||||
var sign = BuildSign(request.GatewayData, merchant.Key);
|
||||
request.GatewayData.Add("sign", sign);
|
||||
|
||||
var result = HttpUtil.Post(request.RequestUrl, request.GatewayData.ToJson());
|
||||
|
||||
var gatewayData = new GatewayData();
|
||||
gatewayData.FromJson(result);
|
||||
|
||||
var baseResponse = (BaseResponse)(object)gatewayData.ToObject<TResponse>(StringCase.Camel);
|
||||
baseResponse.Raw = result;
|
||||
baseResponse.GatewayData = gatewayData;
|
||||
if (baseResponse.ErrCode == "SUCCESS")
|
||||
{
|
||||
sign = gatewayData.GetStringValue("sign");
|
||||
|
||||
if (!string.IsNullOrEmpty(sign) && !CheckSign(gatewayData, merchant.Key, sign))
|
||||
{
|
||||
throw new GatewayException("签名验证失败");
|
||||
}
|
||||
|
||||
baseResponse.Execute(merchant, request);
|
||||
}
|
||||
|
||||
return (TResponse)(object)baseResponse;
|
||||
}
|
||||
|
||||
private static void AddMerchant<TModel, TResponse>(Merchant merchant, Request<TModel, TResponse> request, string gatewayUrl) where TResponse : IResponse
|
||||
{
|
||||
if (!string.IsNullOrEmpty(gatewayUrl))
|
||||
{
|
||||
_gatewayUrl = gatewayUrl;
|
||||
}
|
||||
|
||||
if (!request.RequestUrl.StartsWith("http"))
|
||||
{
|
||||
request.RequestUrl = _gatewayUrl + request.RequestUrl;
|
||||
}
|
||||
request.GatewayData.Add(merchant, StringCase.Camel);
|
||||
((BaseRequest<TModel, TResponse>)request).Execute(merchant);
|
||||
}
|
||||
|
||||
internal static string BuildSign(GatewayData gatewayData, string key)
|
||||
{
|
||||
gatewayData.Remove("sign");
|
||||
|
||||
var data = gatewayData.ToUrl(false) + key;
|
||||
var sign = EncryptUtil.MD5(data);
|
||||
|
||||
return sign;
|
||||
}
|
||||
|
||||
internal static bool CheckSign(GatewayData gatewayData, string key, string sign)
|
||||
{
|
||||
return BuildSign(gatewayData, key) == sign;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using PaySharp.Netpay;
|
||||
using PaySharp.Netpay.Domain;
|
||||
using PaySharp.Netpay.Request;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace PaySharp.UnitTest
|
||||
{
|
||||
public class NetpayGatewayTest
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
private readonly NetpayGateway _netpayGateway;
|
||||
private readonly Merchant _merchant;
|
||||
private string OutTradeNo => DateTime.Now.ToString("3194yyyyMMddhhmmss");
|
||||
|
||||
public NetpayGatewayTest(ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
|
||||
_merchant = new Merchant
|
||||
{
|
||||
AppId = "00000001",
|
||||
MchId = "898310148160568",
|
||||
Key = "fcAmtnx7MwismjWNhNKdHC44mNXtnEQeJkRrhKJwyrW2ysRR",
|
||||
Source = "WWW.TEST.COM",
|
||||
NotifyUrl = "http://localhost:61337/Notify"
|
||||
};
|
||||
|
||||
_netpayGateway = new NetpayGateway(_merchant)
|
||||
{
|
||||
GatewayUrl = "https://qr-test2.chinaums.com"
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestUnifiedPay()
|
||||
{
|
||||
var request = new UnifiedPayRequest();
|
||||
request.AddGatewayData(new UnifiedPayModel
|
||||
{
|
||||
MsgType = "trade.precreate",
|
||||
Body = "银联商务统一支付测试",
|
||||
TotalAmount = 1,
|
||||
OriginalAmount = 1,
|
||||
OutTradeNo = OutTradeNo
|
||||
});
|
||||
|
||||
var response = _netpayGateway.Execute(request);
|
||||
|
||||
_output.WriteLine(response.QrCode);
|
||||
Assert.NotNull(response.QrCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestQuery()
|
||||
{
|
||||
var request = new QueryRequest();
|
||||
request.AddGatewayData(new QueryModel()
|
||||
{
|
||||
MsgType = "query",
|
||||
OutTradeNo = "319420200104045313"
|
||||
});
|
||||
|
||||
var response = _netpayGateway.Execute(request);
|
||||
Assert.Equal(1, response.TotalAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\PaySharp.Alipay\PaySharp.Alipay.csproj" />
|
||||
<ProjectReference Include="..\..\src\PaySharp.Allinpay\PaySharp.Allinpay.csproj" />
|
||||
<ProjectReference Include="..\..\src\PaySharp.Netpay\PaySharp.Netpay.csproj" />
|
||||
<ProjectReference Include="..\..\src\PaySharp.Unionpay\PaySharp.Unionpay.csproj" />
|
||||
<ProjectReference Include="..\..\src\PaySharp.Wechatpay\PaySharp.Wechatpay.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user