C# .NET 拉卡拉支付接口解析 付款码支付  条码支付 被扫 反扫 刷卡支付 B扫C。

简要:

1.测试环境给的私钥是PKCS8。签名用。

2.CRT证书用X509Certificate2 读取出序列号,签名时用。

3.验证签名的公钥证书是“lkl-apigw-v1-test-.cer”

4.如果termExtInfo对象为null,得处理下JSON字符串,尾部追加“termExtInfo:{}”,否则会报HTTP 400 BAD REQUEST 错误。或者你termExtInfo对象里传个客户端IP即可。

5.退款查询使用交易查询接口,把退款申请号传入ornOrderId即可。

测试环境主URL:https://test.wsmsd.cn/sit/labs/txn.

部分代码:

1.读取PKCS8私钥,转为C# .NET RSACryptoServiceProvider 对象,用到了BouncyCastle.Crypto库,用nuget下载最新版本即可:

/// <summary>
/// PKCS8 文本转RSACryptoServiceProvider 对象
/// </summary>
/// <param name="privateKeyPemPkcs8"></param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPrivateKeyPKCS8(string privateKeyPemPkcs8)
{ try
{
//PKCS8是“BEGIN PRIVATE KEY”
privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); //pkcs8 文本先转为 .NET XML 私钥字符串
string privateKeyXml = RSAPrivateKeyJava2DotNet(privateKeyPemPkcs8); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(privateKeyXml);
return publicRsa;
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// PKCS8 私钥文本 转 .NET XML 私钥文本
/// </summary>
/// <param name="privateKeyPemPkcs8"></param>
/// <returns></returns>
public static string RSAPrivateKeyJava2DotNet(string privateKeyPemPkcs8)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyPemPkcs8));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}

2.读取接入者公钥的序列号,“cert-.crt”文件:

X509Certificate2 cert = new X509Certificate2(ofdCrt.FileName);
txtCertSN.Text = cert.SerialNumber;

3.私钥签名:

public string GetSign(string appid, string serial_no, string bodyJson)
{
/*
将分配的appId、证书序列号、时间戳、随机字符串、请求报文拼接。拼接报文一共有5行,每一行为一个参数。行尾以\n(换行符,ASCII编码值为0x0A)结束,包括最后一行。 具体格式如下:
${appid}\n+${serialNo}\n+${timeStamp}\n+${nonceStr}\n+${body}\n
*/ string timestamp = TimeStampUtil.GetTimeStampTen().ToString();//10位和13位的都可以
string nonce_str = Guid.NewGuid().ToString("N").Substring(12); StringBuilder sc = new StringBuilder();
sc.AppendFormat("{0}\n", appid);
sc.AppendFormat("{0}\n", serial_no);
sc.AppendFormat("{0}\n", timestamp);
sc.AppendFormat("{0}\n", nonce_str);
sc.AppendFormat("{0}\n", bodyJson);
string fnstr = sc.ToString(); var rsaP = RsaUtil.LoadPrivateKey(txtPrivateKey.Text, "PKCS8");
byte[] data = Encoding.UTF8.GetBytes(fnstr);//待签名字符串转成byte数组,UTF8
byte[] byteSign = rsaP.SignData(data, "SHA256");//对应JAVA的RSAwithSHA256
string sign = Convert.ToBase64String(byteSign);//签名byte数组转为BASE64字符串 string schema = "LKLAPI-SHA256withRSA";
String token = "appid=\"" + appid + "\",serial_no=\"" + serial_no + "\",timestamp=\"" + timestamp
+ "\",nonce_str=\"" + nonce_str + "\",signature=\"" + sign + "\"";
String authorization = schema + " " + token;
return authorization;
}

4.空termExtInfo处理:

 MicroPayReq req = new MicroPayReq();
req.mercId = txtMchNo.Text.Trim();
req.termNo = txtTermNo.Text.Trim();
req.authCode = txtAuthCode.Text.Trim();
req.amount = total_fee.ToString();
req.orderId = txtOutTradeNo.Text;
req.subject = "条码支付-总部"; LKL_PubReq<MicroPayReq> pub = new LKL_PubReq<MicroPayReq>();
pub.reqData = req; string bodyJson = JsonConvert.SerializeObject(pub, jsetting);
bodyJson = bodyJson.Substring(0, bodyJson.Length - 1);
//空termExtInfo处理
bodyJson = bodyJson + ",\"termExtInfo\":{}}";

5.HTTP 发送报文:

public static string HttpPostJson(string url, string body, IDictionary<string, string> header, int timeOut, IDictionary<string, string> rspHeader)
{
string rst = "";
Encoding enc1 = Encoding.UTF8;
byte[] content = enc1.GetBytes(body); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json;charset=utf-8";
request.Timeout = timeOut * 1000;
request.ReadWriteTimeout = timeOut * 1000;
request.KeepAlive = false;
request.ServicePoint.Expect100Continue = false;
request.ContentLength = content.Length;
//设置请求header
foreach (var item in header)
{
request.Headers.Add(item.Key, item.Value);
} using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(content, 0, content.Length);
} HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, enc1);
rst = reader.ReadToEnd();
} //收集响应header
if (rspHeader == null)
{
rspHeader = new Dictionary<string, string>();
}
foreach (var item in response.Headers.AllKeys)
{
rspHeader.Add(item, response.Headers[item]);
} if (response != null)
{
response.Close();
response = null;
}
if (request != null)
{
request.Abort();//2018-7-31,增加
request = null;
} return rst;
}

6.读取公钥证书,转为C# RSACryptoServiceProvider对象 ,用于验证签名。

/// <summary>
/// 加载公钥证书
/// </summary>
/// <param name="publicKeyCert">公钥证书文本内容</param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPublicCert(string publicKeyCert)
{ publicKeyCert = publicKeyCert.Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", "").Replace("\r", "").Replace("\n", "").Trim(); byte[] bytesCerContent = Convert.FromBase64String(publicKeyCert);
X509Certificate2 x509 = new X509Certificate2(bytesCerContent);
RSACryptoServiceProvider rsaPub = (RSACryptoServiceProvider)x509.PublicKey.Key;
return rsaPub; }

7.验证签名:

/// <summary>
/// 验证签名
/// </summary>
/// <param name="rspHeader">HTTP响应头</param>
/// <param name="rspBody">响应报文</param>
/// <param name="pubCert">公钥证书</param>
/// <returns></returns>
bool ValidSign(IDictionary<string, string> rspHeader, string rspBody, string pubCert)
{
string appid = "";
string serial_no = "";
string timestamp = "";
string nonce_str = "";
string rspSign = ""; foreach (var item in rspHeader)
{
if (item.Key == "Lklapi-Appid")
appid = item.Value; if (item.Key == "Lklapi-Serial")
serial_no = item.Value; if (item.Key == "Lklapi-Timestamp")
timestamp = item.Value; if (item.Key == "Lklapi-Nonce")
nonce_str = item.Value; if (item.Key == "Lklapi-Signature")
rspSign = item.Value;
} StringBuilder sc = new StringBuilder();
sc.AppendFormat("{0}\n", appid);
sc.AppendFormat("{0}\n", serial_no);
sc.AppendFormat("{0}\n", timestamp);
sc.AppendFormat("{0}\n", nonce_str);
sc.AppendFormat("{0}\n", rspBody);
string fnstr = sc.ToString(); byte[] byteCon = Encoding.UTF8.GetBytes(fnstr); byte[] byteRspSign = Convert.FromBase64String(rspSign);
var rsaPub = RsaUtil.LoadPublicCert(pubCert); bool bRst = rsaPub.VerifyData(byteCon, "SHA256", byteRspSign); return bRst; }

C# .NET 的RSA CryptoServiceProvider对象+SHA256 哈希算法,等效于JAVA的 SHA256withRSA.

完整调用代码:https://gitee.com/runliuv/mypub/tree/master/donetproj/

C# .NET 拉卡拉支付接口解析 付款码支付 条码支付的更多相关文章

  1. phpt5支付宝登陆支付接口解析

    先看效果图 下面的源码来源网络,自己对照修改. 放入一个插件库中,方便管理 创建支付类 1.发起支付 public function init() { $order_id = $_REQUEST['o ...

  2. C#支付宝支付接口H5版(手机网页支付)

    接口官方文档 https://docs.open.alipay.com/203/107090/ 首先在Nuget 安装 Alipay /// <summary>         /// 支 ...

  3. JAVA微信支付接口开发——支付

    微信支付接口开发--支付 这几天在做支付服务,系统接入了支付宝.微信.银联三方支付接口.个人感觉支付宝的接口开发较为简单,并且易于测试. 关于数据传输,微信是用xml,所以需要对xml进行解析. 1. ...

  4. thinkphp.2 thinkphp5微信支付 微信公众号支付 thinkphp 微信扫码支付 thinkphp 微信企业付款5

    前面已经跑通了微信支付的流程,接下来吧微信支付和微信企业付款接入到thinkphp中,版本是3.2 把微信支付类.企业付款类整合到一起放到第三方类库,这里我把微信支付帮助类和企业付款类放到同一个文件了 ...

  5. Python支付接口汇总大全(包含微信、支付宝等)

    微信接口 wzhifuSDK- 由微信支付SDK 官方PHP Demo移植而来,v3.37下载地址 weixin_pay- 是一个简单的微信支付的接口 weixin_pay- 微信支付接口(V3.3. ...

  6. 2019 拉卡拉java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.拉卡拉等公司offer,岗位是Java后端开发,因为发展原因最终选择去了拉卡拉,入职一年时间了,也成为了面试官 ...

  7. ASP.NET Core2.0 环境下MVC模式的支付宝PC网站支付接口-沙箱环境开发测试

    1.新建.NET Core web项目 2.Controllers-Models-Views 分三个大部分 3.下载安装最新sdk 官方的SDK以及Demo都还是.NET Framework的,根据官 ...

  8. 工行ICBC_WAPB_B2C支付接口

    一. 前期准备 手机银行(WAP)B2C在线支付接口说明V1.0.0.6.doc 手机银行移动生活商户及门户网站js接口API.doc 支付组件ICBCEBankUtil.dll和infosecapi ...

  9. C#开发微信门户及应用(35)--微信支付之企业付款封装操作

    在前面几篇随笔,都是介绍微信支付及红包相关的内容,其实支付部分的内容还有很多,例如企业付款.公众号支付或刷卡支付.摇一摇红包.代金券等方面的内容,这些都是微信接口支持的内容,本篇继续微信支付这一主题, ...

  10. 对接第三方支付接口-获取http中的返回参数

    这几天对接第三方支付接口,在回调通知里获取返回参数,有一家返回的json格式,请求参数可以从标准输入流中获取. //1.解析参数 , 读取请求内容 BufferedReader br; String ...

随机推荐

  1. 力扣523(java&python)-连续的子数组和(中等)

    题目: 给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组: 子数组大小 至少为 2 ,且子数组元素总和为 k 的倍数.如果存在,返回 true ...

  2. 力扣21(java&python)-合并两个有序链表(简单)

    题目: 将两个升序链表合并为一个新的 升序 链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例 1: 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3 ...

  3. 用了那么久的Lombok,你知道它的原理么?

    简介: 在写Java代码的时候,最烦写setter/getter方法,自从有了Lombok插件不用再写那些方法之后,感觉再也回不去了,那你们是否好奇过Lombok是怎么把setter/getter方法 ...

  4. DataX在数据迁移中的应用

    简介: DataX在数据迁移中的应用 1. DataX定义 首先简单介绍下datax是什么.DataX是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlSe ...

  5. 阿里云AHAS Chaos:应用及业务高可用提升工具平台之故障演练

    简介: 阿里云AHAS Chaos:应用及业务高可用提升工具平台之故障演练 应用高可用服务AHAS及故障演练AHAS Chaos 应用高可用服务(Application High Availabili ...

  6. 创新推出 | Serverless 场景排查问题利器:函数实例命令行操作

    ​简介: 实例命令行功能的推出希望能消除用户使用 Serverless 的"最后一公里",直接将真实的函数运行环境展现给用户,此后 Serverless 将不再是一个"黑 ...

  7. Serverless 工程实践 | 快速搭建 Kubeless 平台

    ​简介: Kubeless 是基于 Kubernetes 的原生无服务器框架.其允许用户部署少量的代码(函数),而无须担心底层架构. 快速搭建 Kubeless 平台 Kubeless 简介 Kube ...

  8. ChaosBlade:从混沌工程实验工具到混沌工程平台

    ​简介: ChaosBlade 是阿里巴巴 2019 年开源的混沌工程项目,已加入到 CNCF Sandbox 中.起初包含面向多环境.多语言的混沌工程实验工具 chaosblade,到现在发展到面向 ...

  9. WPF 已知问题 InputEventArgs 的 Timestamp 属性是静态的导致事件之间相互影响

    本文记录一个 WPF 已知的设计问题,当前此问题已经被大佬修复,这个设计问题刚好属于比较边缘的模块,我写了这么多年的代码还没有踩到这个坑一次,也没有听到有谁提到这个坑 远古时候,不知道大佬是故意还是失 ...

  10. 习题8 #第8章 Verilog有限状态机设计-1 #Verilog #Quartus #modelsim

    1. 设计一个"111"串行数据检测器.要求是:当检测到连续3个或3个以上的"1"时输出为1,其他输入情况下输出为0. (1)思路分析:参照本章前文的范例,如第 ...