最近在对接中行支付退款等功能,由于中行提供的文档里只有java demo和一份pfx私钥和一份cer公钥。看了java的源码是基于SHA1算法加密,于是乎想起php的openssl加签是有SHA1的算法的,但是php是不能读取pfx格式的证书的,然后网上搜索出openssl转变pfx为pem格式在进行读取,最后利用openssl_sign此函数进行验签,但是出现了问题,签名长度只有300多位,而正确的签名长度是1920位,后来还想利用open_pkcs7_sign进行加签,但是由于此函数文档确实太少,也没折腾起来,没办法所以就想到利用java来进行签名。
既然确定了用java那就是利用php跟java通信的方式,考虑了三种,但是最后选择了php-java-bridge此种方式,操作简单。
1.服务器安装java环境, 安装java网上教程已经很多了,请各位自行安装。
2.安装好了之后就可以下载javaBridge.jar 下载
3. 下载后之后放置到文件夹中,执行启动命令 java -jar JavaBridge.jar SERVLET_LOCAL:6666启动服务 6666是端口号,可以随意修改。
4. 接下来就是java代码的编写,利用demo里的代码进行简单修改后打包成jar文件,放到java的安装目录中的jre/lib/ext中
5.在做完以上一系列事情之后还需要下载 java.inc 我是放置于跟javaBridge同级目录
6. 接下来就是php代码的编写 上代码
//定义常量
define("JAVA_HOSTS","127.0.0.1:9123")
//引入java.inc
require_once(APPPATH."libraries/Boc/Java.inc");
//java treeMap实例
$treeMap = new Java("java.util.TreeMap");
//加签实例
$pkSign = new Java("com.fxqifu.boc.PkSign");
$params = [
'pid' => '1111',
'merId' => '2222',
];
foreach($params as $k => $val) {
$treeMap->put($k,$val);
}
//私钥证书路径
$pkSign->setPathPfx("usr/Boc/boc.pfx");
//加签
return java_values($pkSign->sign($treeMap));
7. 到了此处支付应该没什么问题了,回调验签上代码
!defined("JAVA_HOSTS") ? define("JAVA_HOSTS","127.0.0.1:9123") : '';
require_once(APPPATH."libraries/Boc/Java.inc");
$treeMapSignature = new Java("java.util.TreeMap");
$pkSign = new Java("com.fxqifu.boc.PkSign");
$signature = $params['signature'];
unset($params['signature']);
foreach($params as $k => $val) {
$treeMapSignature->put($k,$val);
}
//公钥路径
$pkSign->setPathCer("usr/Boc/verifyt4.cer");
//验签
return java_values($pkSign->verify($signature, $treeMapSignature));
8. 至此支付已经没什么大问题了,接下来讲讲退款
中行退款表示需要post提交表单形式,但是传统的表单提交肯定是不行的,因为需要回调接收。所以用到了php的curl,但是发现直接post形式请求,然后数据以数组的形式去请求,就会发现中行那边接收到了null,表示数据没有传出去,网上查找原因,具体可以查看此篇文章,在了解原理之后,把数组中的数据用=拼接key和value,每个值之间用&拼接,value需要urlencode,然后curl post提交即可得到正确的返回数据。
总结:一般情况下能用php解决的问题,最好用本语言解决,但是本语言解决不了才利用其它语言解决,语言没有好坏之分只有适合不适合,至此此篇文章是比较详细的php对接中行支付,大家有问题可以加我qq大家一起进步:690485272