PHP-Java-Bridge实现使php完美支持中国银联(chinapay)支付接口

来源:互联网 发布:我国2016车祸死亡数据 编辑:程序博客网 时间:2024/05/18 09:10

折腾了3天,终于把中国银联的接口在我们的服务器上搞定了。从申请接口到批复,中间经历了2个多月,还要多次电话催促,提供的接口支持又不全。中国银联的商户服务实在是无力吐槽,只有自己埋头琢磨了。

先说一下服务器配置:

        Ubuntu 12.04 AMD 64位版本+ PHP 5.4.9 + Apache 2.2.22,如图:



接口申请成功后,银联会发过来一封邮件,根据邮件提示登录商户控制台

http://console.chinapay.com/newgms/


使用Chrome或者Firfox需要先安装其非IE证书控件。

1.下载其Java版的NetPayClient 2.5[ NetPayClient2.5_java.rar]

2.下载php-java-bridge : 

http://php-java-bridge.sourceforge.net/pjb/

当前最新的php-java-bridge版本是6.2.1,下载两个文件JavaBridge.jar和java/Java.inc即可。

3.准备JDK环境(我的JDK环境是1.7.0.67,路径在 /usr/java/jdk1.7.0_67)。

4.解压NetPayClient2.5_java.rar,把netpayclient.jar 放在路径 /usr/java/jdk1.7.0_67/jre/lib/ext/ 下。JavaBridge从 /usr/java/jdk1.7.0_67/jre/lib/ext/ 读取类库,所以把jar文件放在里能确保JavaBridge正确读取。

5. vi /etc/environment,加入以下内容,


  PATH="/usr/java/jdk1.7.0_67/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
         JAVA_HOME="/usr/java/jdk1.7.0_67"
          CLASSPATH="/usr/java/jdk1.7.0_67/lib/dt.jar:/usr/java/jdk1.7.0_67/lib/tools.jar:/usr/java/jdk1.7.0_67/jre/lib/ext/netpayclient.jar"


6. source /etc/environment,更新环境变量(可敲入env 查看是否正确) 

7. 更改配置

sudo update-alternatives --install /usr/bin/java java /usr/java/jdk1.7.0_67/bin/java 300
sudo update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.7.0_67/bin/javac 300
sudo update-alternatives --install /usr/bin/jar jar   /usr/java/jdk1.7.0_67/bin/jar 300
sudo update-alternatives --install /usr/bin/javah javah /usr/java/jdk1.7.0_67/bin/javah 300
sudo update-alternatives --install /usr/bin/javap javap /usr/java/jdk1.7.0_67/bin/javap 300 

8. 上传JavaBridge到/etc/chinapay/phpJavaBridge/,银联的密钥文件放在/etc/chinapay/keys/

9.启动phpJavaBridge,监听8080端口

java -jar /etc/chinapay/phpJavaBridge/JavaBridge.jar SERVLET_LOCAL:8080  3 /var/log/JavaBridge.log

10.编写第一个脚本,测试php-java-bridge是否正常工作

   

<?require_once("/etc/chinapay/phpJavaBridge/Java.inc");$system = java("java.lang.System");$s = new Java("java.lang.String", "php-java-bridge config...<br><br>");  echo $s;      // demonstrate property access  print "Java version=".$system->getProperty("java.version")." <br> ";  print "Java vendor=" .$system->getProperty('java.vendor')." <br> ";  print "OS=".$system->getProperty(" os.name ")." ".  $system->getProperty("os.version")." on ".  $system->getProperty(" os.arch ")." <br> ";     // java.util.Date example  $formatter = new Java('java.text.SimpleDateFormat',  "EEEE, MMMM dd, yyyy 'at' h:mm:ss a zzzz");  echo $formatter. "<br>";  print $formatter->format(new Java("java.util.Date"));?>

输出:


php-java-bridge config...Java version=1.7.0_67 Java vendor=Oracle Corporation OS= 3.2.0-29-generic on 
java.text.SimpleDateFormat@1b76958aMonday, August 11, 2014 at 11:51:19 AM China Standard Time
说明php-java-bridge工作正常。

11.编写第二个脚本,测试netpayclient是否工作正常。

<?require_once("/etc/chinapay/phpJavaBridge/Java.inc");$key = new Java("chinapay.PrivateKey");$MerID = new Java("java.lang.String", "808********5949");  $Path = new Java("java.lang.String", "/etc/chinapay/keys/MerPrk1.key");    $OrderID = new Java("java.lang.String", "2222222221111111");$Bill = new Java("java.lang.String", "000000002000");$CurID  = new Java("java.lang.String", "156");$TransDate  = new Java("java.lang.String", "20140810");$TransType  = new Java("java.lang.String", "0001");try{$flag = $key->buildKey($MerID ,0,$Path);if(!$flag){echo "build key error!";} else{$sec = new Java("chinapay.SecureLink",$key); $checkedVal = $sec->signOrder($MerID,$OrderID ,$Bill,$CurID,$TransDate,$TransType); echo $checkedVal; }   } catch (JavaException $ex) {  echo "An exception occured: ".$ex."<br>\n";}?>
   

运行一下,好了,这下报一大堆错误:

Warning: Unchecked exception detected: [[o:Response$UndeclaredThrowableErrorMarker]:"FATAL: Undeclared java.lang.RuntimeException detected. java.lang.Exception: Invoke failed: [[o:SecureLink]]->signOrder((o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String]). Cause: java.lang.NullPointerException VM: 1.7.0_67@http://java.oracle.com/" at: #-15 chinapay.SecureLink.Sign(SecureLink.java:208) #-14 chinapay.SecureLink.genSign(SecureLink.ja[...]JavaBridge/Java.inc(1752): java_Client->invokeMethod(10, 'signOrder', Array) #5 /etc/chinapay/phpJavaBridge/Java.inc(1851): java_JavaProxy->__call('signOrder', Array) #6 /etc/chinapay/phpJavaBridge/Java.inc(1999): java_AbstractJava->__call('signOrder', Array) #7 /var/www/php-java/test2.php(19): Java->__call('signOrder', Array) #8 /var/www/php-java/test2.php(19): Java->signOrder(Object(Java), Object(Java), Object(Java), Object(Java), Object(Java), Object(Java)) #9 {main}] in /etc/chinapay/phpJavaBridge/Java.inc on line 202[[o:Response$UndeclaredThrowableErrorMarker]:"FATAL: Undeclared java.lang.RuntimeException detected. java.lang.Exception: Invoke failed: [[o:SecureLink]]->signOrder((o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String], (o:String)[o:String]). Cause: java.lang.NullPointerException VM: 1.7.0_67@http://java.oracle.com/" at: #-15 chinapay.SecureLink.Sign(SecureLink.java:208) #-14 chinapay.SecureLink.genSign(SecureLink.java:253) #-13 chinapay.SecureLink.signOrder(SecureLink.java:258) #-12 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) #-11 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) #-10 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) #-9 java.lang.reflect.Method.invoke(Method.java:606) #-8 php.java.bridge.JavaBridge.Invoke(JavaBridge.java:1044) #-7 php.java.bridge.Request.handleRequest(Request.java:417) #-6 php.java.bridge.Request.handleRequests(Request.java:500) #-5 php.java.bridge.JavaBridge.handleRequests(JavaBridge.java:150) #-4 php.java.bridge.JavaBridgeRunner.doPut(JavaBridgeRunner.java:207) #-3 php.java.bridge.http.HttpServer.service(HttpServer.java:289) #-2 php.java.bridge.http.HttpServer$Runner.run(HttpServer.java:205) #-1 php.java.bridge.ThreadPool$Delegate.run(ThreadPool.java:60) #0 /etc/chinapay/phpJavaBridge/Java.inc(232): java_ThrowExceptionProxyFactory->getProxy(11, 'chinapay.Secure...', 'F', true) #1 /etc/chinapay/phpJavaBridge/Java.inc(360): java_Arg->getResult(true) #2 /etc/chinapay/phpJavaBridge/Java.inc(366): java_Client->getWrappedResult(true) #3 /etc/chinapay/phpJavaBridge/Java.inc(560): java_Client->getResult() #4 /etc/chinapay/phpJavaBridge/Java.inc(1752): java_Client->invokeMethod(10, 'signOrder', Array) #5 /etc/chinapay/phpJavaBridge/Java.inc(1851): java_JavaProxy->__call('signOrder', Array) #6 /etc/chinapay/phpJavaBridge/Java.inc(1999): java_AbstractJava->__call('signOrder', Array) #7 /var/www/php-java/test2.php(19): Java->__call('signOrder', Array) #8 /var/www/php-java/test2.php(19): Java->signOrder(Object(Java), Object(Java), Object(Java), Object(Java), Object(Java), Object(Java)) #9 {main}]Fatal error: An unchecked exception occured during script execution. Please check the server log files for details. in /etc/chinapay/phpJavaBridge/Java.inc on line 776
  

 注释掉测试文件的Line 19 & Line 21 ,没有错误,怎么回事?

查看NetPayClient_Manual.pdf,第12页对返回值有个说明,是String checkValue[256],大概就是这个256出的问题。不如将chinapay.SecureLink.signOrder函数封装一下再输出正常的String看看?


12. 修改

 

    cd /usr/java/jdk1.7.0_67/jre/lib/ext/    mkdir netpayclient    cd netpayclient    jar -xvf ../netpayclient.jar

现在netpayclient目录下有chinapay和META-INF两个文件夹。

13.编写Wrapper.java,对chinapay组件进行封装

package chinapay;    import java.text.DecimalFormat;public class Wrapper{private static final String MerID = "<span style="text-indent: 2em; font-family: Arial, Helvetica, sans-serif;">808********5949</span>";private static final String KeyPath = "/etc/chinapay/keys/MerPrk1.key";private static final String CurrID = "156";private static final String TransType = "0001";public String signOrder(String order_id,int bill_total, long trans_date){PrivateKey key = new PrivateKey(); if(!key.buildKey(MerID,0,KeyPath)){ return "build failed.";}SecureLink sec_lnk = new SecureLink(key);DecimalFormat myFormatter1 = new DecimalFormat("000000000000");DecimalFormat myFormatter2 = new DecimalFormat("00000000");String s1 = myFormatter1.format(bill_total);String s2 = myFormatter2.format(trans_date);return sec_lnk.signOrder(MerID,order_id,s1,CurrID,s2,TransType);} }


14.把Wraper.java拷贝到/usr/java/jdk1.7.0_67/jre/lib/ext/netpayclient/chinapay,编译一下

javac Wrapper.java

rm Wrapper.java

jar -cvf netpayclient.jar .

rm -f /usr/java/jdk1.7.0_67/jre/lib/ext/netpayclient.jar

mv netpayclient.jar  /usr/java/jdk1.7.0_67/jre/lib/ext/

 

15.删除netpayclient 文件夹,运行

       nohup  java -jar /etc/chinapay/phpJavaBridge/JavaBridge.jar SERVLET_LOCAL:8080  3 /var/log/JavaBridge.log &

使php-java-bridge作为后台运行。


16.测试

<?php <span style="white-space:pre"></span>require_once("/etc/chinapay/phpJavaBridge/Java.inc"); <span style="white-space:pre"></span>try {   //  $w = new Java("chinapay.Wrapper");  $ret = $w->signOrder("2014081012345678",2000,20140810);  echo $ret ;  <span style="white-space:pre"></span>} catch (JavaException $ex) {     echo "An exception occured: ".$ex."<br>\n";} ?>

 OK了。


说明: key文件放在

"/etc/chinapay/keys/

时可能会因为读取失败而输出build failed,把文件放在/usr/java/chinapay/ 这个问题便可以解决。

很快便可在http://umango.cn里面看到集成。

0 1