添加APP支付

This commit is contained in:
varorbc
2017-11-16 15:49:58 +08:00
parent cc25cbfdb1
commit de4bee90aa
6 changed files with 147 additions and 31 deletions
+1
View File
@@ -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";
}
}
+8 -3
View File
@@ -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>
/// 渠道类型
+27
View File
@@ -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; }
}
}
+47 -2
View File
@@ -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; }
}
}
+64 -13
View File
@@ -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&currencyCode=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;
}
}
}
-13
View File
@@ -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;
}