mirror of
https://github.com/Varorbc/PaySharp.git
synced 2026-10-27 11:17:00 +08:00
添加APP支付
This commit is contained in:
@@ -12,5 +12,6 @@ namespace ICanPay.Unionpay
|
||||
public const string QUERYID = "queryId";
|
||||
public const string RESPCODE = "respCode";
|
||||
public const string RESPMSG = "respMsg";
|
||||
public const string ORDERDESC = "orderDesc";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ namespace ICanPay.Unionpay
|
||||
/// </summary>
|
||||
public string CertId { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密证书号
|
||||
/// </summary>
|
||||
public string EncryptCertId { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书私钥
|
||||
/// </summary>
|
||||
@@ -120,12 +125,12 @@ namespace ICanPay.Unionpay
|
||||
///94:IC卡脚本通知
|
||||
///95:查询更新加密公钥证书
|
||||
/// </summary>
|
||||
public string TxnType { get; internal set; }
|
||||
public string TxnType { get; internal set; } = "01";
|
||||
|
||||
/// <summary>
|
||||
/// 交易子类
|
||||
/// </summary>
|
||||
public string TxnSubType { get; internal set; }
|
||||
public string TxnSubType { get; internal set; } = "01";
|
||||
|
||||
/// <summary>
|
||||
/// 产品类型
|
||||
@@ -140,7 +145,7 @@ namespace ICanPay.Unionpay
|
||||
/// 001001:订购
|
||||
/// 000202:B2B
|
||||
/// </summary>
|
||||
public string BizType { get; internal set; }
|
||||
public string BizType { get; internal set; } = "000201";
|
||||
|
||||
/// <summary>
|
||||
/// 渠道类型
|
||||
|
||||
@@ -218,5 +218,32 @@ namespace ICanPay.Unionpay
|
||||
/// 银联受理订单号
|
||||
/// </summary>
|
||||
public string Tn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付卡标识
|
||||
/// </summary>
|
||||
public string PayCardNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付卡名称
|
||||
/// </summary>
|
||||
public string PayCardIssueName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 清算汇率
|
||||
/// </summary>
|
||||
public string ExchangeRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换日期
|
||||
/// </summary>
|
||||
public string ExchangeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 绑定关系标识号
|
||||
/// 适用于代收类绑定产品,字母不区分大小写,
|
||||
/// 用法:在绑定后支付时客户仅需要上送本字段,无需上送卡号,不支持换行符等不可见字符 用于唯一标识绑定关系
|
||||
/// </summary>
|
||||
public string BindId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ namespace ICanPay.Unionpay
|
||||
private double _amount;
|
||||
|
||||
/// <summary>
|
||||
/// 银联不支持此字段,填写无效
|
||||
/// 订单描述,仅APP支付有效
|
||||
/// </summary>
|
||||
[ReName(Name = Constant.ORDERDESC)]
|
||||
[StringLength(32, ErrorMessage = "订单描述最大长度为32位")]
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -57,7 +59,7 @@ namespace ICanPay.Unionpay
|
||||
/// <summary>
|
||||
/// 发卡机构代码,当账号类型为 02-存折时需填写 在前台类交易时填写默认银行代码,支持直接跳转到网 银
|
||||
/// </summary>
|
||||
[StringLength(20, ErrorMessage = "发卡机构代码最大长度为1024位")]
|
||||
[StringLength(20, ErrorMessage = "发卡机构代码最大长度为20位")]
|
||||
public string IssInsCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -65,5 +67,48 @@ namespace ICanPay.Unionpay
|
||||
/// </summary>
|
||||
[StringLength(1024, ErrorMessage = "商户自定义保留域最大长度为1024位")]
|
||||
public string ReqReserved { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易账号。请求时使用加密公钥对交易账号加密,并做 Base64 编码后上送;
|
||||
/// 应答时如需返回,则使用签名私钥 进行解密。
|
||||
/// 前台交易可由银联页面采集,也可由商户上送并返显。
|
||||
/// 如需锁定返显卡号,应通过保留域(reserved)上送卡 号锁定标识。
|
||||
/// </summary>
|
||||
[StringLength(1024, ErrorMessage = "交易账号最大长度为1024位")]
|
||||
public string AccNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 银行卡验证信息及身份信息
|
||||
/// 该域需整体做 Base64 编码。
|
||||
/// 所有子域需用“有子域包含,子域间以“含,符号链接。
|
||||
/// 格式如下:{子域名 1=值&子域名 2=值&子域名 3=值}
|
||||
/// 各子域取值见注
|
||||
/// 1。 借记卡可上送姓名、手机号、证件类型、证件号码;
|
||||
/// 贷记卡可上送姓名、手机号、证件类型、证件号码、有效 期、CVN2。
|
||||
/// 前台交易可以由银联页面采集,无需商户上送,后台交 易必须由商户上送。
|
||||
/// 前台交易支持商户上送并返显的要素包含手机号,姓 名,证件号。
|
||||
/// </summary>
|
||||
[StringLength(1024, ErrorMessage = "银行卡验证信息及身份信息最大长度为1024位")]
|
||||
public string CustomerInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分期付款信息域
|
||||
/// 相关子域见注 10。 格式如下:{子域名1=值&子域名2=值&子域名3=值}
|
||||
/// </summary>
|
||||
[StringLength(1024, ErrorMessage = "分期付款信息域最大长度为1024位")]
|
||||
public string InstalTransInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标记化支付信息域
|
||||
/// 格式如下:{子域名1=值&子域名2=值&子域名3=值}
|
||||
/// 示例: tokenPayData={token=6201002708161330&trId=12345678&tokenLevel=55&tokenBegin=20140816093022&tokenEnd=20150816093021&tokenType=01}
|
||||
/// </summary>
|
||||
[StringLength(1024, ErrorMessage = "标记化支付信息域最大长度为1024位")]
|
||||
public string TokenPayData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// /持卡人IP
|
||||
/// </summary>
|
||||
public string CustomerIp { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@ namespace ICanPay.Unionpay
|
||||
/// </summary>
|
||||
public class UnionpayGateway
|
||||
: GatewayBase,
|
||||
IFormPayment
|
||||
IFormPayment, IAppPayment
|
||||
{
|
||||
|
||||
#region 私有字段
|
||||
|
||||
private const string GATEWAYURL = "https://gateway.test.95516.com/gateway/api/frontTransReq.do";
|
||||
private const string FRONTGATEWAYURL = "https://gateway.test.95516.com/gateway/api/frontTransReq.do";
|
||||
private const string APPGATEWAYURL = "https://gateway.test.95516.com/gateway/api/appTransReq.do";
|
||||
private readonly Merchant _merchant;
|
||||
|
||||
#endregion
|
||||
@@ -39,7 +40,7 @@ namespace ICanPay.Unionpay
|
||||
|
||||
#region 属性
|
||||
|
||||
public override string GatewayUrl { get; set; } = GATEWAYURL;
|
||||
public override string GatewayUrl { get; set; } = FRONTGATEWAYURL;
|
||||
|
||||
public new Merchant Merchant => _merchant;
|
||||
|
||||
@@ -78,16 +79,59 @@ namespace ICanPay.Unionpay
|
||||
|
||||
public void InitFormPayment()
|
||||
{
|
||||
_merchant.TxnType = "01";
|
||||
_merchant.TxnSubType = "01";
|
||||
_merchant.BizType = "000201";
|
||||
InitOrderParameter();
|
||||
GatewayUrl = FRONTGATEWAYURL;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region App支付
|
||||
|
||||
public string BuildAppPayment()
|
||||
{
|
||||
InitAppPayment();
|
||||
|
||||
Commit();
|
||||
|
||||
return Notify.Tn;
|
||||
}
|
||||
|
||||
public void InitAppPayment()
|
||||
{
|
||||
Util.Sign(_merchant.CertKey, "accessType=0&backUrl=http://222.222.222.222:8080/demo/api_01_gateway/BackRcvResponse.aspx&bizType=000201&certId=68759663125&channelType=08¤cyCode=156&encoding=UTF-8&merId=777290058110048&orderId=20171116133157041&signMethod=01&txnAmt=1000&txnSubType=01&txnTime=20171116133157&txnType=01&version=5.1.0");
|
||||
InitOrderParameter();
|
||||
GatewayUrl = APPGATEWAYURL;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InitOrderParameter()
|
||||
{
|
||||
GatewayData.Add(Merchant, StringCase.Camel);
|
||||
GatewayData.Add(Order, StringCase.Camel);
|
||||
GatewayData.Add(Constant.SIGNATURE, BuildSign());
|
||||
}
|
||||
|
||||
#endregion
|
||||
private void Commit()
|
||||
{
|
||||
string result = HttpUtil
|
||||
.PostAsync(GatewayUrl, GatewayData.ToUrl())
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
ReadReturnResult(result);
|
||||
}
|
||||
|
||||
private void ReadReturnResult(string result)
|
||||
{
|
||||
GatewayData.FromUrl(result, false);
|
||||
base.Notify = GatewayData.ToObject<Notify>(StringCase.Camel);
|
||||
if (!IsSuccessPay)
|
||||
{
|
||||
throw new GatewayException(Notify.RespMsg);
|
||||
}
|
||||
ValidateNotifySign();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成签名
|
||||
@@ -95,7 +139,7 @@ namespace ICanPay.Unionpay
|
||||
/// <returns></returns>
|
||||
private string BuildSign()
|
||||
{
|
||||
return Util.Sign(_merchant.CertKey, GatewayData.ToUrl());
|
||||
return Util.Sign(_merchant.CertKey, GatewayData.ToUrl(false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -104,10 +148,7 @@ namespace ICanPay.Unionpay
|
||||
/// <returns></returns>
|
||||
private bool IsSuccessResult()
|
||||
{
|
||||
if (!ValidateNotifySign())
|
||||
{
|
||||
throw new GatewayException("签名不一致");
|
||||
}
|
||||
ValidateNotifySign();
|
||||
|
||||
if (IsSuccessPay)
|
||||
{
|
||||
@@ -122,7 +163,17 @@ namespace ICanPay.Unionpay
|
||||
/// </summary>
|
||||
private bool ValidateNotifySign()
|
||||
{
|
||||
return Util.VerifyData(GatewayData.ToUrl(Constant.SIGNATURE), Notify.Sign, Notify.SignPubKeyCert);
|
||||
GatewayData.Remove(Constant.SIGNATURE);
|
||||
|
||||
bool result = Util.VerifyData(GatewayData.ToUrl(false),
|
||||
Notify.Sign, Notify.SignPubKeyCert);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
throw new GatewayException("签名不一致");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,24 +179,11 @@ namespace ICanPay.Unionpay
|
||||
}
|
||||
|
||||
string unionpayCnName = "中国银联股份有限公司";
|
||||
|
||||
#if DEBUG
|
||||
|
||||
// 验证公钥是否属于银联
|
||||
if (!unionpayCnName.Equals(cn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (!unionpayCnName.Equals(cn) && !"00040000:SIGN".Equals(cn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user