【网站支付PHP篇】thinkPHP集成汇潮支付(ecpss)
系列目录
支付宝集成:http://www.cnblogs.com/nerve/p/3437879.html
系列说明
最近在帮朋友的系统安装支付模块(兑换网站积分),现在总结一些开发心得,希望对大家有用。这个系列会讲以下第三方支付平台的集成:
- 支付宝 https://www.alipay.com/
- 汇潮支付 http://www.ecpss.cn/new/index.htm
- 智付支付 http://www.dinpay.com/
- 环迅支付 http://www.ips.com/Default.aspx
以后有更新其他平台也会写出来。
这次的支付系统是用来网站的积分充值。为了简化,这里采用的是1元RMB=1个网站积分的兑换。
这里,不会描述怎么申请支付平台的收款帐号。
开发环境
ThinkPHP 3.1.2 (我用的是标准版)
win7 + Apache2
mysql 5.1
汇潮支付有自己的接口文档:http://download.csdn.net/detail/ssrc0604hx/6635299
为了方便使用,我将此支付接口封装成Ecpss.php, 放在 ThinkPhp 的Vendor目录下:
在此类中,填写相应的商户号跟MD5Key(这些在申请了 汇潮支付后,都可以从汇潮网站得到的)。
然后在Ecpss类中,封装了html form 的生成,可以直接跳转到支付页面,下面是Ecpss.php的代码:
<?php /** * Ecpss.php *============================== *汇潮支付时用的库 *============================== * by:0604hx 1053214511@qq.com * Nov 20, 2013 9:02:58 PM */ class Ecpss{ /* * 支付请求的配置 */ var $config; var $MD5Key = ""; var $pay_url = "https://pay.ecpss.cn/sslpayment"; /** * 构造函数 * 参数中应该包括: * BillNo 订单号 * Amount 交易金额 * ReturnURL 返回路径 * products 商品信息 * * @param unknown_type $c */ public function __construct($c=array()){ $this->config['MerNo'] = ""; //商户号,必须 $this->config['orderTime'] = date("YmdHis"); //请求时间,格式为 YYYYMMDDHHMMSS $this->config['AdviceURL'] = ""; $this->config['defaultBankNumber'] = ""; $this->config['Remark'] = ""; //合并两个数组 $this->config = array_merge($this->config, $c); } /** * 生成支付html * * 默认使用post方式提交 */ public function buildSubmitHtml(){ $this->config['SignInfo'] = $this->createSignInfo(); //生成表单 $sHtml = "<form id='ecpssForm' name='ecpssForm' action='".$this->pay_url."' method='post'>"; foreach ($this->config as $key => $val) { $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>"; } //submit按钮控件请不要含有name属性 $sHtml = $sHtml."<input type='submit' value='去支付'></form>"; $sHtml = $sHtml."<script>document.forms['ecpssForm'].submit();</script>"; return $sHtml; } /** * 生成签名 * 方式: * MerNo&BillNo&Amount&ReturnURL&MD5key * 连接起来进行 MD5 加密后字符串,并进行大写转换 * * 参数之间必须添加&符号,比如:16885&B00001&1.00&http://ecpss.cn&keyvalue,各参数之间添加&符号进行连接 */ private function createSignInfo(){ $sign = $this->config['MerNo']."&".$this->config['BillNo'] ."&".$this->config['Amount']."&".$this->config['ReturnURL']."&".$this->MD5Key; $sign = md5($sign); //转换成大写 return strtoupper($sign); } /** * 对服务器返回的数据进行验证 * 参数的 md5校验串, BillNo & Amount & Succeed & MD5key */ public function verify(){ //$sign = $_REQUEST['BillNo']."&".$_REQUEST['Amount']."&".$_REQUEST['Succeed']."&".$this->MD5Key; //return md5($sign) == $_REQUEST['MD5info']; return $_REQUEST['Succeed'] == 88; } } ?>
注意:
Ecpss中的 verify方法是对汇潮服务器返回数据的校对,我按照接口文档的说明进行验证,结果一直无法验证通过,问了技术客服,也得不到答案。
后来我直接判断返回的数据中‘Succeed’一栏是否==88(88就是支付成功)
请大家慎重使用。
然后要使用这个类也比较方便, 下面列出使用方法:
/* * ------------------------------------------------------------------------------------------------ * Start 汇潮支付 * ------------------------------------------------------------------------------------------------ */ private function payWithEcpss($order){ vendor("Ecpss.Ecpss"); $e['BillNo'] = $order['tradeNo']; $e['Amount'] = $order['price']; $e['ReturnURL'] = C("HOST")."index.php/Order/backOnEcpss"; $e['AdviceURL'] = C("HOST")."index.php/Order/notifyOnEcpss"; $e['products'] = $order['subject']; $ecpss = new Ecpss($e); echo $ecpss->buildSubmitHtml(); } /** * 汇潮支付成功后返回的处理action */ public function backOnEcpss(){ $this->dealWithEcpssBack(true); } /** * 从ecpss得到的notify通知 */ public function notifyOnEcpss(){ $this->dealWithEcpssBack(false); } /** * 处理汇潮的返回值 * * @param unknown_type $isReturn true为return,false 为notify返回 */ private function dealWithEcpssBack($isReturn=true){ vendor("Ecpss.Ecpss"); $orderLogDao = new OrderLogModel(); $ecpss = new Ecpss(); $orderLog['addDate'] = sqlDate(); $log = "notify from Ecpss,"; /** * 通过验证 */ if($ecpss->verify()){ //根据订单号获取订单 $DAO = new OrderModel(); $order = $DAO->where("tradeNo='".$_REQUEST['BillNo']."'")->find(); /* * 如果status不为0,那么就不需要处理,防止重复处理 */ if(isset($order)){ $orderLog['order_id'] = $order['id']; if($order['status'] == 0){ $resultInfo = $this->doAfterPaySuccess($DAO, $order); $log.= $resultInfo; }else{ $log.= "但是订单已经被处理过了,无需重复处理!"; } }else{ $orderLog['order_id'] = -1; $log.= "但是订单号在本地数据库不存在!"; } }else{ //验证不通过时,也记录下来 $log.= "但是验证不通过"; $orderLog['order_id'] = -1; } $orderLog['log'] = $log." [返回值为:sign=".$_REQUEST['MD5info']." ".$this->buildEcpssInfo()." ]"; $orderLogDao->add($orderLog); if($isReturn) redirect(__APP__."/Order/payResult?orderId=".$orderLog['order_id'], 0); else echo "ok"; } private function buildEcpssInfo(){ return '订单号='.$_REQUEST['BillNo']." 金额=".$_REQUEST['Amount']." 结果代码=".$_REQUEST['Succeed']." result code=".$_REQUEST['Result']; } /* * ------------------------------------------------------------------------------------------------ * End 汇潮支付 * ------------------------------------------------------------------------------------------------ */
(关于Order的字段,在“支付宝集成”中有相关说明)