ThinkPHP3.2中集成财付通支付

jerry thinkphp 2015年11月19日 收藏
ThinkPHP3.2中集成财付通支付
在项目过程中用到了支付宝和财付通的支付接口问题,发现在TP还未有人写财付通的实例,我仿照前辈们写的一个案例http://www.thinkphp.cn/code/240.html写了一个

一、把接口集成开发包中文件提出来,用的php(utf8)版

把classes文件夹中的文件复制到TP目录下的Library\Think 新建一个Tenpay目录。
二,加入命名空间,方便调用


三、在项目配置文件中加入接口配置参数
  1.   //财付通配置参数
  2.     'tenpay_config' => array(
  3.         'partner' => '**********', //这里是你在成功申请财付通接口后获取到的商户号;
  4.         'key' => '*******************', //这里是你在成功申请财付通接口后获取到的密钥
  5.         'return_url' => '********/tenreturnurl',
  6.         'notify_url' => '********/tennotifyurl',
  7.     ),
三、在支付操作的控制器中加入代码如下
  1.     public function tenpay($data) {
  2.         $tenpay_config = C('tenpay_config');
  3.         /* 获取提交的订单号 */
  4.         $out_trade_no = $data["orderid"];
  5.         /* 获取提交的商品名称 */
  6.         $product_name = $data["title"];
  7.         /* 获取提交的商品价格 */
  8.         $order_price = $data["money"];
  9.         /* 获取提交的备注信息 */
  10.         $remarkexplain = $data["remark"];
  11.         /* 支付方式 */
  12.         $trade_mode = 1; 

  13.         $strDate = date("Ymd");
  14.         $strTime = date("His");

  15.         /* 商品价格(包含运费),以分为单位 */
  16.         $total_fee = $order_price * 100;

  17.         /* 商品名称 */
  18.         $desc = "商品:" . $product_name . ",备注:" . $remarkexplain;

  19.         /* 创建支付请求对象 */
  20.         $reqHandler = new \Think\Tenpay\RequestHandler();
  21.         $reqHandler->init();
  22.         $reqHandler->setKey(trim($tenpay_config['key']));
  23.         $reqHandler->setGateUrl("https://gw.tenpay.com/gateway/pay.htm");

  24. //----------------------------------------
  25. //设置支付参数 
  26. //----------------------------------------
  27.         $reqHandler->setParameter("partner", trim($tenpay_config['partner']));
  28.         $reqHandler->setParameter("out_trade_no", $out_trade_no);
  29.         $reqHandler->setParameter("total_fee", $total_fee);  //总金额
  30.         $reqHandler->setParameter("return_url", $tenpay_config['return_url']);
  31.         $reqHandler->setParameter("notify_url", $tenpay_config['notify_url']);
  32.         $reqHandler->setParameter("body", $desc);
  33.         $reqHandler->setParameter("bank_type", "DEFAULT");     //银行类型,默认为财付通
  34. //用户ip
  35.         $reqHandler->setParameter("spbill_create_ip", $_SERVER['REMOTE_ADDR']); //客户端IP
  36.         $reqHandler->setParameter("fee_type", "1");               //币种
  37.         $reqHandler->setParameter("subject", $desc);          //商品名称,(中介交易时必填)
  38. //系统可选参数
  39.         $reqHandler->setParameter("sign_type", "MD5");       //签名方式,默认为MD5,可选RSA
  40.         $reqHandler->setParameter("service_version", "1.0");    //接口版本号
  41.         $reqHandler->setParameter("input_charset", "utf-8");      //字符集
  42.         $reqHandler->setParameter("sign_key_index", "1");       //密钥序号
  43. //业务可选参数
  44.         $reqHandler->setParameter("attach", "");                //附件数据,原样返回就可以了
  45.         $reqHandler->setParameter("product_fee", "");           //商品费用
  46.         $reqHandler->setParameter("transport_fee", "0");         //物流费用
  47.         $reqHandler->setParameter("time_start", date("YmdHis"));  //订单生成时间
  48.         $reqHandler->setParameter("time_expire", "");             //订单失效时间
  49.         $reqHandler->setParameter("buyer_id", "");                //买方财付通帐号
  50.         $reqHandler->setParameter("goods_tag", "");               //商品标记
  51.         $reqHandler->setParameter("trade_mode", $trade_mode);              //交易模式(1.即时到帐模式,2.中介担保模式,3.后台选择(卖家进入支付中心列表选择))
  52.         $reqHandler->setParameter("transport_desc", "");              //物流说明
  53.         $reqHandler->setParameter("trans_type", "1");              //交易类型
  54.         $reqHandler->setParameter("agentid", "");                  //平台ID
  55.         $reqHandler->setParameter("agent_type", "");               //代理模式(0.无代理,1.表示卡易售模式,2.表示网店模式)
  56.         $reqHandler->setParameter("seller_id", "");                //卖家的商户号
  57. //请求的URL
  58.         $reqUrl = $reqHandler->getRequestURL();
  59. //获取debug信息,建议把请求和debug信息写入日志,方便定位问题
  60.         /**/
  61.         $reqHandler->doSend2($reqUrl);
  62.         $debugInfo = $reqHandler->getDebugInfo();
  63.     }
声明一下,$data是商品的参数,里面必须包含订单号,商品名称,订单描述,商品价格。上述代码中的doSend2函数是一个跳转函数,修改的是ResponseHandler.class.php中的dosend函数。
  1. function doSend2($url) {
  2.         header("Location:" . $url);
  3.         exit;
  4.     }
四、支付成功跳转处理
  1. /*
  2.       财付通页面跳转处理方法;

  3.      */

  4.     function tenreturnurl() {
  5.         /* 创建支付应答对象 */
  6.         $tenpay_config = C('tenpay_config');
  7.         $resHandler = new \Think\Tenpay\ResponseHandler();
  8.         $resHandler->setKey(trim($tenpay_config['key']));

  9. //判断签名
  10.         if ($resHandler->isTenpaySign()) {
  11.             //通知id
  12.             $notify_id = $resHandler->getParameter("notify_id");
  13.             //商户订单号
  14.             $out_trade_no = $resHandler->getParameter("out_trade_no");
  15.             //财付通订单号
  16.             $transaction_id = $resHandler->getParameter("transaction_id");
  17.             //金额,以分为单位
  18.             $total_fee = $resHandler->getParameter("total_fee");
  19.             //如果有使用折扣券,discount有值,total_fee+discount=原请求的total_fee
  20.             $discount = $resHandler->getParameter("discount");
  21.             //支付结果
  22.             $trade_state = $resHandler->getParameter("trade_state");
  23.             //交易模式,1即时到账
  24.             $trade_mode = $resHandler->getParameter("trade_mode");
  25.             //支付完成时间
  26.             $time_end = $resHandler->getParameter("time_end");
  27.             $parameter = array(
  28.                 "out_trade_no" => $out_trade_no, //商户订单编号;
  29.                 "trade_no" => $transaction_id, //财付通订单号;
  30.                 "total_fee" => $total_fee, //交易金额;
  31.                 "trade_status" => $trade_state, //交易状态
  32.                 "notify_id" => $notify_id, //通知校验ID。
  33.                 "notify_time" => $time_end, //通知的发送时间。
  34.             );
  35.             if ("1" == $trade_mode) {
  36.                 if ("0" == $trade_state) {
  37.                     $status = CommonController::checkorderstatus($out_trade_no);
  38.                     if (!$status) {
  39.                         CommonController::orderhandle($parameter);
  40.                         //进行订单处理,并传送从支付宝返回的参数;
  41.                     }
  42.                     $this->success("支付成功", U('Home/Order/Payscuess', array('id' => $out_trade_no)));
  43.                 } else {
  44.                     //当做不成功处理
  45.                     $this->error("支付失败");
  46.                 }
  47.             }
  48.         } else {
  49.             $this->error("认证签名失败," . $resHandler->getDebugInfo());
  50.         }
  51.     }

  52.     /*
  53.       财付通异步通知处理方法;

  54.      */

  55.     function tennotifyurl() {
  56.         $tenpay_config = C('tenpay_config');
  57.         /* 创建支付应答对象 */
  58.         $resHandler = new \Think\Tenpay\ResponseHandler();
  59.         $resHandler->setKey(trim($tenpay_config['key']));
  60.         //判断签名
  61.         if ($resHandler->isTenpaySign()) {

  62.             //通知id
  63.             $notify_id = $resHandler->getParameter("notify_id");

  64.             //通过通知ID查询,确保通知来至财付通
  65.             //创建查询请求
  66.             $queryReq = new \Think\Tenpay\RequestHandler();
  67.             $queryReq->init();
  68.             $queryReq->setKey(trim($tenpay_config['key']));
  69.             $queryReq->setGateUrl("https://gw.tenpay.com/gateway/simpleverifynotifyid.xml");
  70.             $queryReq->setParameter("partner", trim($tenpay_config['partner']));
  71.             $queryReq->setParameter("notify_id", $notify_id);

  72.             //通信对象
  73.             $httpClient = new \Think\Tenpay\client\TenpayHttpClient();
  74.             $httpClient->setTimeOut(5);
  75.             //设置请求内容
  76.             $httpClient->setReqContent($queryReq->getRequestURL());

  77.             //后台调用
  78.             if ($httpClient->call()) {
  79.                 //设置结果参数
  80.                 $queryRes = new \Think\Tenpay\client\ClientResponseHandler();
  81.                 $queryRes->setContent($httpClient->getResContent());
  82.                 $queryRes->setKey(trim($tenpay_config['key']));

  83.                 if ($resHandler->getParameter("trade_mode") == "1") {
  84.                     //判断签名及结果(即时到帐)
  85.                     //只有签名正确,retcode为0,trade_state为0才是支付成功
  86.                     if ($queryRes->isTenpaySign() && $queryRes->getParameter("retcode") == "0" && $resHandler->getParameter("trade_state") == "0") {

  87.                         //通知id
  88.                         $notify_id = $resHandler->getParameter("notify_id");
  89.                         //商户订单号
  90.                         $out_trade_no = $resHandler->getParameter("out_trade_no");
  91.                         //财付通订单号
  92.                         $transaction_id = $resHandler->getParameter("transaction_id");
  93.                         //金额,以分为单位
  94.                         $total_fee = $resHandler->getParameter("total_fee");
  95.                         //如果有使用折扣券,discount有值,total_fee+discount=原请求的total_fee
  96.                         $discount = $resHandler->getParameter("discount");
  97.                         //支付结果
  98.                         $trade_state = $resHandler->getParameter("trade_state");
  99.                         //交易模式,1即时到账
  100.                         $trade_mode = $resHandler->getParameter("trade_mode");
  101.                         //支付完成时间
  102.                         $time_end = $resHandler->getParameter("time_end");
  103.                         $parameter = array(
  104.                             "out_trade_no" => $out_trade_no, //商户订单编号;
  105.                             "trade_no" => $transaction_id, //财付通订单号;
  106.                             "total_fee" => $total_fee, //交易金额;
  107.                             "trade_status" => $trade_state, //交易状态
  108.                             "notify_id" => $notify_id, //通知校验ID。
  109.                             "notify_time" => $time_end, //通知的发送时间。
  110.                         );
  111.                         $status = CommonController::checkorderstatus($out_trade_no);
  112.                         if (!$status) {
  113.                             CommonController::orderhandle($parameter);
  114.                             //进行订单处理,并传送从支付宝返回的参数;
  115.                         }
  116.                         echo "success";
  117.                     } else {

  118.                         echo "fail";
  119.                     }
  120.                 }
  121.             } else {
  122.                 //通信失败
  123.                 echo "fail";
  124.                 //后台调用通信失败,写日志,方便定位问题
  125.                 echo "<br>call err:" . $httpClient->getResponseCode() . "," . $httpClient->getErrInfo() . "<br>";
  126.             }
  127.         } else {
  128.             echo "<br/>" . "认证签名失败" . "<br/>";
  129.             echo $resHandler->getDebugInfo() . "<br>";
  130.         }
  131.     }   
其中的checkorderstatus和orderhandle用的是上述支付宝即时交易案例中的订单处理函数
  1.   //处理订单函数
  2.     //更新订单状态,写入订单支付后返回的数据
  3.     function orderhandle($parameter) {
  4.         $ordid = $parameter['out_trade_no'];
  5.         $data['trade_no'] = $parameter['trade_no'];
  6.         $data['trade_status'] = $parameter['trade_status'];
  7.         $data['notify_id'] = $parameter['notify_id'];
  8.         $data['notify_time'] = $parameter['notify_time'];
  9.         $data['buyer_email'] = $parameter['buyer_email'];
  10.         $data['paystatus'] = 1;
  11.         $Ord = M('order');
  12.         $Ord->where('orderid=' . $ordid)->save($data);
  13.     }
  14.     //在线交易订单支付处理函数
  15.     //函数功能:根据支付接口传回的数据判断该订单是否已经支付成功;
  16.     //返回值:如果订单已经成功支付,返回true,否则返回false;
  17.     function checkorderstatus($ordid) {
  18.         $Ord = M('order');
  19.         $ordstatus = $Ord->where('orderid=' . $ordid)->getField('paystatus');
  20.         if ($ordstatus == 1) {
  21.             return true;
  22.         } else {
  23.             return false;
  24.         }
  25.     }
其他请参看http://www.thinkphp.cn/code/240.html中的案例,支付接口的方法大致都是一样的,下面提供财付通集成开发包

附件php(utf8).zip ( 60.83 KB 下载:280 次 )