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. 3.CSS三种基本选择器

    三种选择器的优先级: id选择器 > class选择器 > 标签选择器 1.标签选择器:会选择到页面上所有的该类标签的元素 格式: 标签{} 1 <!DOCTYPE html> ...

  2. 力扣273(java)-整数转换英文表示(困难)

    题目: 将非负整数 num 转换为其对应的英文表示. 示例 1: 输入:num = 123输出:"One Hundred Twenty Three"示例 2: 输入:num = 1 ...

  3. 牛客网-SQL专项训练9

    ①假设有选课表course_relation(student_id, course_id),其中student_id表示学号,course_id表示课程编号,如果小易现在想获取每个学生所选课程的个数信 ...

  4. 中仑网络全站 Dubbo 2 迁移 Dubbo 3 总结

    简介: 中仑网络在 2022 年完成了服务框架从 Dubbo 2 到 Dubbo 3 的全站升级,深度使用了应用级服务发现.Kubernetes 原生服务部署.服务治理等核心能力.来自中仑网络的技术负 ...

  5. PolarDB-X 源码解读:事务的一生

    简介: 本文将主要解读 PolarDB-X 中事务部分的相关代码,着重解读事务的一生在计算节点(CN)中的关键代码:从开始.执行.到最后提交这一整个生命周期. 概述 本文将主要解读 PolarDB-X ...

  6. 揭秘 cache 访问延迟背后的计算机原理

    ​简介:本文介绍如何测试多级 cache 的访存延迟,以及背后蕴含的计算机原理. CPU 的 cache 往往是分多级的金字塔模型,L1 最靠近 CPU,访问延迟最小,但 cache 的容量也最小.本 ...

  7. Dubbo-go v3.0 正式发布 ——打造国内一流开源 Go 服务框架

    ​简介:Dubbo-go 是常新的,每年都在不断进化.介绍 Dubbo-go 3.0 工作之前,先回顾其过往 6 年的发展历程,以明晰未来的方向. ​ 作者 | 李志信 来源 | 阿里技术公众号 作者 ...

  8. Go 语言网络库 getty 的那些事

    简介: Getty 维护团队不追求无意义的 benchmark 数据,不做无意义的炫技式优化,只根据生产环境需求来进行自身改进.只要维护团队在,Getty 稳定性和性能定会越来越优秀. 个人从事互联网 ...

  9. dotnet 警惕 C# 的 is var 写法

    本文将和大家介绍 C# 语言设计里面,我认为比较坑的一个语法.通过 is var 的写法,会让开发者误以为 null 是不被包含的,然而事实是在这里的 var 是被赋予含义的,将被允许 null 通过 ...

  10. Win32 使用 CreateProcess 方法让任务管理器里的命令行不显示应用文件路径

    本文记录一个 Win32 的有趣行为,调用 CreateProcess 方法传入特别的参数,可以让任务管理器里的命令行不显示应用文件路径 开始之前,先看看下面这张有趣的图片 可以看到我编写的 Svca ...