天天看点

ecshop网站添加“银联商务”支付功能

  年初时公司要在官网上添加一个支付功能“银联商务”支付。这个支付系统支持许多的银行在线支付。写在这里希望能帮助一些需要的朋友。

   虽然ecshop的支付方式已经有好多了,但有时也有使用其它没有有支付系统。当然如果能看懂这个添加过程,那么其它的支付功能添加也不会太难。

   与“银联商务”签合同就不说了。签合同后“银联商务”会给我们一个测试帐号与测试地址。

ecshop网站添加“银联商务”支付功能

  这是测试与调试必须要的。

  还得到商户的控制台(用上面的地址帐号登录)下面的 "ChinaPay安装插件下载" 里找到下载 "NetPayClient php (通用版)安装程序" 。下载后里面有只一个PHP文件是处理整个加密密钥程序,必须要的,虽然代码进行了加密,但高手一看就可以解密出来。

ecshop网站添加“银联商务”支付功能

一般我们可以不用解密出来,直接可以使用。如果没有解密那文件可以放在/includes/modules/  下。不要放在/includes/modules/payment/ 下。

  这个程序要用到PHP的“bcmath”高精度数学函数库,这个库在window里是自带的,但在linux里必须一般要安装才能使用。当然如果PHP已经安装了这个扩展就没有必要再装了。

  linux系统下,给PHP安装扩展方法有很多,这时说下我使用的方法:

       在终端输入命令  yum install php-bcmath  回车后 就可以等待安装完成。

  下面来说下流程:

ecshop网站添加“银联商务”支付功能

   在/includes/modules/payment/   下新建一个支付文件,命名可以自己定义的。如 chinaPay.php  这里就以chinaPay.php为名。

添加以下代码:

<?php

//银联商务  支付接囗

if (!defined('IN_ECS'))

{

   die('Hacking attempt');

}

$payment_lang = ROOT_PATH . 'languages/' .$GLOBALS['_CFG']['lang']. '/payment/'.basename(__FILE__);

if (file_exists($payment_lang))

   global $_LANG;

   include_once($payment_lang);

/* 安装模块的基本信息后台管理中用到的 */

if (isset($set_modules) && $set_modules == TRUE)

   $i = isset($modules) ? count($modules) : 0;

   /* 代码 */

   $modules[$i]['code']    = basename(__FILE__, '.php');

   /* 描述对应的语言项 */

   $modules[$i]['desc']    = 'chinaPay_desc';//对应语言文件中的说明内容下标

   /* 是否货到付款 */

   $modules[$i]['is_cod']  = '0';

   /* 是否支持在线支付 */

   $modules[$i]['is_online']  = '1';

   /* 作者 */

   $modules[$i]['author']  = 'XIHUAN';

   /* 网址 */

   $modules[$i]['website'] = 'http://www.ecshop.com';

   /* 版本号 */

   $modules[$i]['version'] = '1.0.0';

   /* 配置信息 表单元素*/

   $modules[$i]['config']  = array(

       array('name' => 'chinaPay_MerId',/*对应语言文件中的下标*/       'type' => 'text',   'value' => ''),//商户号

       array('name' => 'chinaPay_MerPrk', /*对应语言文件中的下标*/     'type' => 'text',   'value' => ''),//商户签名私钥地址

       array('name' => 'chinaPay_PgPubk', /*对应语言文件中的下标*/     'type' => 'text',   'value' => '')//ChinaPay签名私钥地址

   );

   return;

include ROOT_PATH.'/includes/modules/netpayclient.php'//如果解密了这个文件可以把代码定到这里就不用这句代码

/**

* 类

*/

class chinaPay{

   function chinaPay()

   {

   }

   function __construct()

       $this->chinaPay();

   //获取指定长度的字符串  不足以0填充

   function str($str,$len,$fill='0')

       if(strlen($str)<$len)

       {

           return str_repeat($fill, $len-strlen($str)).$str;

       }

       return substr($str, 0,$len);

   //金额处理

   function order_amount($amount)

       if(strpos($amount, '.'))

           return $this->str(str_replace('.', '', $amount), 12);

       else return $this->str($amount.'00', 12);

   /**

    * 生成支付代码

    * @param   array   $order      订单信息

    * @param   array   $payment    支付方式信息

    * 这里必须根据要求生成银联商务可用的连接代码

    */

   function get_code($order, $payment)

       //创建签名钥

       if(empty($payment['chinaPay_MerId'])||empty($payment['chinaPay_MerPrk'])||!buildKey($payment['chinaPay_MerPrk']))return '<p>支付出错!请联系园田居!</p>';

       $order_no=$this->str($order['order_sn'], 16);//处理定单

       $TransAmt=$this->order_amount($order['order_amount']);//订单交易金额

       $Priv1='chinaPay';

       $CuryId='156';//订单交易币种

       $TransDate=date('Ymd');//订单交易日期

       $TransType='0001';//交易类型

       $msg=$payment['chinaPay_MerId'].$order_no.$TransAmt.$CuryId.$TransDate.$TransType.$Priv1;

       $button='<form action="http://payment-test.chinapay.com/pay/TransGet" METHOD="POST" target="_blank">'.// (这里action的内容为提交交易数据的URL地址)

       '<input type="hidden" name="MerId" value="'.$payment['chinaPay_MerId'].'"/>'.// (MerId为ChinaPay统一分配给商户的商户号,15位长度,必填)

       '<input type="hidden" name="OrdId" value="'.$order_no.'"/>'. //(商户提交给ChinaPay的交易订单号,16位长度,必填)

       '<input type="hidden" name="TransAmt" value="'.$TransAmt.'"/>'. //(订单交易金额,12位长度,左补0, 必填,单位为分)

       '<input type="hidden" name="CuryId" value="'.$CuryId.'"/>'.// (订单交易币种,3位长度,固定为人民币156, 必填)

       '<input type="hidden" name="TransDate" value="'.$TransDate.'"/>'.//(订单交易日期,8位长度,必填)

       '<input type="hidden" name="TransType" value="0001"/>'.// (交易类型,4位长度,必填)

       '<input type="hidden" name="Version" value="20070129"/>'.// (支付接入版本号,必填)

       '<input type="hidden" name="BgRetUrl" value="'.$GLOBALS['ecs']->url() . 'respond.php'.'"/>'.// (后台交易接收URL,长度不要超过80个字节,必填)

       '<input type="hidden" name="PageRetUrl" value="'.$GLOBALS['ecs']->url() . 'respond.php'.'"/>'.// (页面交易接收URL,长度不要超过80个字节,必填)

       '<input type="hidden" name="GateId" value=""/>'.//(支付网关号,可选)

       '<input type="hidden" name="Priv1" value="'.$Priv1.'"/>'.//(商户私有域,长度不要超过60个字节) 传参数用的

       '<input type="hidden" name="ChkValue" value="'.sign($msg).'"/>'.//(256字节长的ASCII码,为此次交易提交关键数 据的数字签名,必填)

       '<input type="submit" value="立即使用银联支付"/>

       </form>';

       return $button;

    * 响应操作

这里主要处理银联回传的数据  并且要处理付款的形式  是否为付款成功  或付款中  这里的状态很重要

回传的数据  验证最重要的

   function respond()

       /*

       当消费支付交易完成时,ChinaPay会将交易应答信息发送给商户,

       对于页面易接收地址和后台交易接收地址都会收到交易接收数据,

       应答的数据域段包括如下内容:(以页面Form数据为例,注意大小写,

       后台应答数据的发送的域段名和下面的一致)

       <form name="SendToMer" method="post" action=""> (这里action的内容为提交交易数据的URL地址)

       <input type="hidden" name="merid" value="808000000000001"/>(MerId为ChinaPay统一分配给商户的商户号,15位长度,必填)

       <input type="hidden" name="orderno" value="0000000010096806"/> (商户提交给ChinaPay的交易订单号,16位长度,必填)

       <input type="hidden" name="transdate" value="20070801"/> (订单交易日期,8位长度,必填)

       <input type="hidden" name="amount" value="000000001234"/> (订单交易金额,12位长度,左补0, 必填,单位为分)

       <input type="hidden" name="currencycode" value="156"/>(订单交易币种,3位长度,固定为人民币156, 必填)

       <input type="hidden" name="transtype" value="0001"/> (交易类型,4位长度,必填)

       <input type="hidden" name="status" value="1001"/> (交易状态,4位长度,必填)

       <input type="hidden" name="checkvalue" value=" X…X "/> (256字节长的ASCII码,为此次交易提交关键数 据的数字签名,必填)

       <input type="hidden" name="GateId" value=" 0001"/> (支付网关号,可选)

       <input type="hidden" name="Priv1" value=" Memo"/> (商户私有域,长度不要超过60个字节) 传参数用的

       </form>

       status 表示交易转态,只有"1001"的时候才为交易成功,其他均为失败,因此在验证签名数据为ChinaPay发出的以后,还需要判定交易状态代码为"1001"。

        */

       $sql = "SELECT pay_config FROM " . $GLOBALS['ecs'] ->table('payment') . " WHERE pay_code = 'chinaPay' AND enabled = '1'";

       $pay = $GLOBALS['db']->getRow($sql);//取出内容

       if(empty($pay['pay_config']))return false;//支付配置数据不存在

       $payment = unserialize($pay['pay_config']);

       foreach ($payment as $value)

           if($value['name']=='chinaPay_PgPubk')

           {

               $PgPubk=$value['value'];

               break;

           }

       //创建验证钥

       if(!isset($PgPubk)||!buildKey($PgPubk))return false;

       if (empty($_POST)||!is_array($_POST))return false;//交易失败

       $respond=array('merid','orderno','transdate','amount','currencycode','transtype','status','checkvalue','GateId');

       foreach ($respond as $val)

           if(array_key_exists($val, $_POST));else return false;//交易失败返回数据不合法或缺少

       /* 检查支付的金额是否相符 */

       $order_no=substr($_POST['orderno'], -13);//取出定单号这块可以不去处理SQL注入,后面调用的函数都会判断这个变量的值是否为全数字

       $log_id=get_order_id_by_sn($order_no);//取出支付编号

       //判断是为为充值定单

       if(empty($log_id))$log_id=get_order_id_by_sn($order_no,true);//取出支付编号

       if (!check_money($log_id, (float)substr_replace($_POST['amount'], '.', -2,0)))

           return false;

       //判断交易状态

       if($_POST['status']!='1001')return false;//交易失败

       /* 检查数字签名是否正确 */

       //验证交易应答

       if(!verifyTransResponse($_POST['merid'], $_POST['orderno'], $_POST['amount'], $_POST['currencycode'], $_POST['transdate'], $_POST['transtype'], $_POST['status'], $_POST['checkvalue']))

       return false;//交易失败

           /* 改变订单状态 */

       order_paid($log_id);

      return true;//支付成功

?>

以上是整个前端处理核心代码。

  然后这个可能建立一个语言文件

ecshop网站添加“银联商务”支付功能

   文件名与支付文件名一样。如果有多个语言可以在/languages/en_us/payment/ ;/languages/zh_cn/payment/ ;/languages/zh_wt/payment/  下都建立一个同样的文件(只要处理好显示的内容为不同的语言就可以)。

添加以下代码:

global $_LANG;

$_LANG['chinaPay'] = '银联商务';

$_LANG['chinaPay_desc'] = '银联商务网站(http://www.chinaums.com/) 是国内先进的网上支付平台。无预付/年费,单笔费率0.6%-0.8%,无流量限制。<br/><a href="http://www.chinaums.com/" target="_blank"><font color="red">立即在线申请</font></a>';

$_LANG['chinaPay_MerId'] = '商户号';

$_LANG['chinaPay_MerPrk'] = '商户签名私钥地址';

$_LANG['chinaPay_PgPubk'] = 'ChinaPay签名私钥地址';

$_LANG['pay_button'] = '立即使用银联商务支付';

到这里客户用使用代码基本写完。后面还得添加后台管理内容。

把测试用的私钥两个文件上传到要测试的服务器中,尽量不要放在服务器的目录下。

进入 系统后台 -> 系统设置  -> 支付方式 菜单就可以看到多了一个支付方式,“银联商务”。

在“银联商务”中可以看到最后面一列中有个“安装”链接,点击安装。

ecshop网站添加“银联商务”支付功能

继续阅读