tp5.1 樂百分支付(分期)

注意:樂百分是分測試與正式帳號

3,注意事項:
1.交易金額範圍(600—50000)元。

2.交易測試賬號:接口使用(商戶名稱、商戶編號、接口密碼)樂百分管理後臺使用(商戶登錄賬號、登錄密碼、退款密碼、PC端登陸地址)。

3.測試環境只能使用測試卡信息表中的卡號、cvn、有效期等信息做測試交易,身份證號可以填寫真實個人身份證,若填寫真實的卡號等信息是無法做交易的。

4.測試時需要接收短信驗證碼,因此手機號要爲真實有效的手機號碼。若無法接收短信,切勿多次觸發短信驗證碼,可檢查是否手機網絡問題,或同一手機號測試交易過多,換其他手機號測試。

5.爲了測試方便測試環境的扣款間隔爲兩天一期,若需測試退款請在交易第二天(清算後)操作。

6.測試完成,要接到樂百分生產環境時需更換商戶編號、商戶名稱、商戶簡稱、接口密碼、生產環境域名,證書不用更換。

 

 

兩個文件放到 \extend\lfqpay  php文件

LebaifenPay.php

參數都在緩存取得

<?php
namespace lfqpay;


/**
 * 樂百分 支付
 *
 * Created by .
 * User: going1000
 * Date: 9/19/16
 * Time: 4:34 PM
 */

class LebaifenPay
{

//  private  $version = '1.0.0';
//  private  $encoding = 'utf-8';
    const VS = '1.0.0';//$version
    const ED = 'utf-8';//$encoding
    
    public $lbfpay_conf;
    public $cert_addr;
    public $lfqpay_cert_password;
    public $create_api;
    public $cancel_api;
    public $query_api;
    public $front_url;
    public $back_url;
    
    public function __construct()
    {
    	//初始化,取得微信支付參數
    	$system_cofing=system_cofing();
    	$this->lbfpay_conf = $system_cofing;
        $lfqpay_cert_addr=explode('/uploads/',$system_cofing['lfqpay_cert_addr']);//http://www.cg.com/uploads/file/20191230\e675796c651a74dd9272a8705dbb22e3.pfx
        $this->cert_addr='./uploads/'.$lfqpay_cert_addr[1];//證書絕對路徑 
        $this->lfqpay_cert_password=$system_cofing['lfqpay_cert_password'];
        
        $system_website=$this->lbfpay_conf['system_website'];
        $this->front_url=$system_website.'/pay/index/lfqpay_notify_url';//交易完成或失敗通過此地址同步返回交易結果到商戶頁面   同步回調  http://www.1.com/lbf_pay/frontUrl.php
        $this->back_url=$system_website.'/pay/index/lfqpay_notify';//異步通知交易結果以及後期 異步回調 http://www.1.com/lbf_pay/backUrl.php
        
        if($system_cofing['lfqpay_test_is']){//1=正式環境(正式上線支付)
        	$this->create_api='https://interface.lfqpay.com/lfq-pay/gateway/api/frontTransRequest.do';
        	$this->cancel_api='https://interface.lfqpay.com/lfq-pay/gateway/api/backCancelRequest.do';
        	$this->query_api='https://interface.lfqpay.com/lfq-pay/gateway/api/singleQueryRequest.do';
        }else{//0=測試環境 
        	$this->create_api='https://tt.lfqpay.com/lfq-pay/gateway/api/frontTransRequest.do';
        	$this->cancel_api='https://tt.lfqpay.com/lfq-pay/gateway/api/backCancelRequest.do';
        	$this->query_api='https://tt.lfqpay.com/lfq-pay/gateway/api/singleQueryRequest.do';
        }
        //分期數
        $this->choose_installments_num=$system_cofing['lfqpay_txnTerms'];
//      dump($data['choose_installments_num']);exit;
    }

    /**
     * 創建-pc
     *
     * @param $data
     * @return string
     * @throws ErrorException
     */
    public function buildRequestForm($data)
    {
    	
//		分期數
        if($data['choose_installments_num']){
        	$choose_installments_num=$data['choose_installments_num'];
        }else{
        	$choose_installments_num=$this->choose_installments_num;
        }

        $rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $certdata = openssl_x509_parse($cert['cert']);
        
        if(empty($certdata) || !$this->front_url || !$this->back_url || !$this->lbfpay_conf['lfqpay_merId'] || !$this->lbfpay_conf['lfqpay_merName'] || !$this->lbfpay_conf['lfqpay_merPwd']){
        	$sHtml='缺少必要參數!';
        }else{//正確
	        $param =array(
	            'certId' => $certdata['serialNumber'],
	            'version' => self::VS,
	            'txnType' => '01', // 創建
	            'frontUrl' => $this->front_url, // 同步回調
	            'backUrl' => $this->back_url, // 異步回調
	            'encoding' => self::ED,
	            'merId' => $this->lbfpay_conf['lfqpay_merId'],
	            'merName' => $this->lbfpay_conf['lfqpay_merName'],//商戶名稱
	            'merAbbr' => $this->lbfpay_conf['lfqpay_merName'],//商戶簡稱
	            'merPwd' => $this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送
	            'orderId' => $data['out_trade_no'], // 訂單號
	            'txnTime' => date('YmdHis'), // 發送時間
	            'txnAmt' => round($data['total_fee'] * 100), // 訂單總額 (單位分)
	            'txnTerms' => $choose_installments_num?$choose_installments_num:6, // 分期數
	            'txnTermsList' => 15, // 前臺交易時可通過此參數控制頁面顯示的分期數列表。不同分期之間用逗號分開,如“3,6”。
	            'merNote' => $data['body'], // 物品信息
	            'userMac' => ',',
	            //'monthAmount' => round($data['price_per_installments_without_lbf_price'] * 100),
	            //'discount' => round($data['ahs_subsidies'] * 100),
	            'validTime' => date('YmdHis')+ 60*60*24*3 // 超時時間 yyyyMMddHHmmss
	        );
	//      dump($param);die;
	        $sign = $this->_sign($param);
	        $param['signature'] = $sign;
	        $sHtml = "<form name='xxform' action='{$this->create_api}' method='get'>";
	        foreach ($param as $key => $val) {
	            $sHtml .= " <input type='hidden' name='" . $key . "' value='" . $val . "'/> ";
	        }
			$sHtml = $sHtml . "</form>";
	   		$sHtml = $sHtml . "<script>document.forms['xxform'].submit();</script>";
        }
// 		dump($sHtml);exit;
        return $sHtml;
    }
    /**
     * 創建-移動app
     *
     * @param $data
     * @return string
     * @throws ErrorException
     */
    public function buildRequestFormApp($data)
    {
    	
//		分期數
        if($data['choose_installments_num']){
        	$choose_installments_num=$data['choose_installments_num'];
        }else{
        	$choose_installments_num=$this->choose_installments_num;
        }
        $choose_installments_num=$choose_installments_num?$choose_installments_num:6;

        $rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $certdata = openssl_x509_parse($cert['cert']);
        
        
        if(empty($certdata) || !$this->front_url || !$this->back_url || !$this->lbfpay_conf['lfqpay_merId'] || !$this->lbfpay_conf['lfqpay_merName'] || !$this->lbfpay_conf['lfqpay_merPwd']){
        	$param=[];
        }else{//正確
        	$txnTime=date('YmdHis');
        	$validTime=$txnTime + 60*60*24*3;
        	//用於簽名
	        $param_sign =array(
	            'certId' => $certdata['serialNumber'],
	            'version' => self::VS,
	            'txnType' => '01', // 創建
	            'frontUrl' => $this->front_url, // 同步回調
	            'backUrl' => $this->back_url, // 異步回調
	            'encoding' => self::ED,
	            'merId' => $this->lbfpay_conf['lfqpay_merId'],
	            'merName' => $this->lbfpay_conf['lfqpay_merName'],//商戶名稱
	            'merAbbr' => $this->lbfpay_conf['lfqpay_merName'],//商戶簡稱
	            'merPwd' => $this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送
	            'orderId' => $data['out_trade_no'], // 訂單號
	            'txnTime' => $txnTime, // 發送時間
	            'txnAmt' => round($data['total_fee'] * 100), // 訂單總額 (單位分)
	            'txnTerms' => $choose_installments_num, // 分期數
	            'txnTermsList' => 15, // 前臺交易時可通過此參數控制頁面顯示的分期數列表。不同分期之間用逗號分開,如“3,6”。
	            'merNote' => $data['body'], // 物品信息
	            'userMac' => ',',
	            //'monthAmount' => round($data['price_per_installments_without_lbf_price'] * 100),
	            //'discount' => round($data['ahs_subsidies'] * 100),
	            'validTime' => $validTime // 超時時間 yyyyMMddHHmmss
	        );
//	        dump($param_sign);
	        $param =array(
	            'certId' => 'certId='.$certdata['serialNumber'],
	            'version' => '&version='.self::VS,
	            'txnType' => '&txnType='.'01', // 創建
	            'frontUrl' => '&frontUrl='.$this->front_url, // 同步回調
	            'backUrl' => '&backUrl='.$this->back_url, // 異步回調
	            'encoding' => '&encoding='.self::ED,
	            'merId' => '&merId='.$this->lbfpay_conf['lfqpay_merId'],
	            'merName' => '&merName='.$this->lbfpay_conf['lfqpay_merName'],//商戶名稱
	            'merAbbr' => '&merAbbr='.$this->lbfpay_conf['lfqpay_merName'],//商戶簡稱
	            'merPwd' => '&merPwd='.$this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送
	            'orderId' => '&orderId='.$data['out_trade_no'], // 訂單號
	            'txnTime' => '&txnTime='.$txnTime, // 發送時間
	            'txnAmt' => '&txnAmt='.round($data['total_fee'] * 100), // 訂單總額 (單位分)
	            'txnTerms' => '&txnTerms='.$choose_installments_num, // 分期數
	            'txnTermsList' => '&txnTermsList=15', // 前臺交易時可通過此參數控制頁面顯示的分期數列表。不同分期之間用逗號分開,如“3,6”。
	            'merNote' => '&merNote='.$data['body'], // 物品信息
	            'userMac' => '&userMac=,',
	            //'monthAmount' => round($data['price_per_installments_without_lbf_price'] * 100),
	            //'discount' => round($data['ahs_subsidies'] * 100),
	            'validTime' => '&validTime='.$validTime // 超時時間 yyyyMMddHHmmss
	        );
//	      	dump($param);exit;
	        $sign = $this->_sign($param_sign);
	        $param['signature'] = '&signature='.urlencode($sign);
	        $param['url'] = $this->create_api.'?';
        }

        return $param;
    }

   /**
     * 取消訂單
     *
     * @param $contractsCode
     * @return bool
     * @throws ErrorException
     * @throws UserException
     */
    public function cancel($contractsCode) {
//      $lbfpay_conf = Config::get('onlinepay.lbfpay');

//      $rs = openssl_pkcs12_read(file_get_contents(__DIR__ . $lbfpay_conf['cert_addr']), $cert, $lbfpay_conf['cert_password']);
		$rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $certdata = openssl_x509_parse($cert['cert']);

        $param=array(
            'certId' => $certdata['serialNumber'],
            'version' => self::VS,
            'encoding' => self::ED,

            'txnType' => '04', // 退款
            'txnTime' => date('YmdHis'), // 發送時間

            'merId' => $this->lbfpay_conf['lfqpay_merId'],
            'merName' => $this->lbfpay_conf['lfqpay_merName'],
            'merAbbr' => $this->lbfpay_conf['lfqpay_merName'],
            'merPwd' => $this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送

            'backUrl' => $this->back_url,

            'contractsCode' => $contractsCode
       );

        $sign = $this->_sign($param);

        $param['signature'] = $sign;

        $rs = CurlHandler::post($this->cancel_api, $param);

        $arr = json_decode($rs, true);

        if($arr['respCode'] === '0000' && $contractsCode == $arr['contractsCode'] && $arr['state'] === '1') {
            return true;
        } else {
            throw new UserException($rs);
        }
    }

    /**
     * 確認收貨
     *
     * @param $contractsCode
     * @return bool
     * @throws ErrorException
     * @throws UserException
     */
    public function confirm($data) {
//      $lbfpay_conf = Config::get('onlinepay.lbfpay');
//
//      $rs = openssl_pkcs12_read(file_get_contents(__DIR__ . $lbfpay_conf['cert_addr']), $cert, $lbfpay_conf['cert_password']);
		$rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $certdata = openssl_x509_parse($cert['cert']);

        $param =  array(
            'certId' => $certdata['serialNumber'],
            'version' => self::VS,
            'encoding' => self::ED,

            'txnType' => '91', // 確認收貨
            'txnTime' => date('YmdHis'), // 發送時間

            'merId' => $this->lbfpay_conf['lfqpay_merId'],
            'merName' => $this->lbfpay_conf['lfqpay_merName'],
            'merAbbr' => $this->lbfpay_conf['lfqpay_merName'],
            'merPwd' => $this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送

            'backUrl' => $this->back_url,

            'contractsCode' => $contractsCode
        );

        $sign = $this->_sign($param);

        $param['signature'] = $sign;

        $rs = CurlHandler::post($lbfpay_conf['confirm_api'], $param);
        
        $arr = json_decode($rs, true);

        if($arr['respCode'] === '0000' && $contractsCode == $arr['contractsCode']) {
            return true;
        } else {
//          throw new UserException($arr['respMsg']);
//          throw new \Exception($arr['respMsg']);
            return false;
        }
    }
    /**
     * 查詢定單
     *
     * @param $data
     * @return bool

     */
    public function query($data) {
    	
		$rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $certdata = openssl_x509_parse($cert['cert']);

        $param =  array(
            'certId' => $certdata['serialNumber'],
            'version' => self::VS,
            'encoding' => self::ED,
            'txnType' => '73', // 訂單查詢
            'txnTime' => date('YmdHis'), // 發送時間
			'orderId' => $data['out_trade_no'], // 訂單號
            'merId' => $this->lbfpay_conf['lfqpay_merId'],
            'merName' => $this->lbfpay_conf['lfqpay_merName'],
            'merAbbr' => $this->lbfpay_conf['lfqpay_merName'],
            'merPwd' => $this->lbfpay_conf['lfqpay_merPwd'], // 商戶密碼,必送
        );

        $sign = $this->_sign($param);
        $param['signature'] = $sign;
//		dump($param);
//		dump($this->query_api);
		
		$returndata=postCurl($this->query_api,$param);
//		dump($returndata);
		return $returndata;
    }


    /**
     * 簽名數據
     *
     * @param $data
     * @return string
     * @throws ErrorException
     */
    function _sign($data)
    {
//      $lbfpay_conf = Config::get('onlinepay.lbfpay');
//      $rs = openssl_pkcs12_read(file_get_contents(__DIR__ . $lbfpay_conf['cert_addr']), $cert, $lbfpay_conf['cert_password']);
//      dump($this->cert_addr);
		$rs = openssl_pkcs12_read(file_get_contents($this->cert_addr), $cert, $this->lfqpay_cert_password);
//		dump($rs);
        if($rs) {
		    $a= new OpensslAuth ;
            $sign = $a ->generate_signature($this->_sha1_from_param($data), $cert['pkey']);
        } else {
//          throw new ErrorException('證書獲取失敗');
            throw new \Exception('證書獲取失敗');
        }
        

        return $sign;
    }

    /**
     * 驗籤
     *
     * @param $data
     * @return bool
     */
    function _vertify_sign($data)
    {
//      $lbfpay_conf = Config::get('onlinepay.lbfpay');

        // 過濾 signature
        $sign = $data['signature'];
        unset($data['signature']);

//      openssl_pkcs12_read(file_get_contents(__DIR__ . $lbfpay_conf['cert_addr']), $cert, $lbfpay_conf['cert_password']);
		$rs = openssl_pkcs12_read(file_get_contents( $this->cert_addr), $cert, $this->lfqpay_cert_password);
        $a=new OpensslAuth;
		$verify_rs =  $a->vertify_signature($this->_sha1_from_param($data), $cert['cert'], $sign);

        return $verify_rs;
    }

    /**
     * 從參數中提取 sha1 摘要
     *
     * @param $data
     * @return string
     */
    private function _sha1_from_param($data) {
        // 排序
        ksort($data);
        // 簽名
        $tmp_str = '';
        foreach ($data as $k => $v) {
            $tmp_str .= $k . '=' . $v . '&';
        }
        $tmp_str = trim($tmp_str, '&');
        // sha1 摘要
        $tmp_str = sha1($tmp_str);

        return $tmp_str;
    }
}

OpensslAuth.php

<?php
namespace lfqpay;

class OpensslAuth
{

    private $_private_key;
    private $_public_key;

    function set_private_key($key)
    {
        $this->_private_key = $key;
    }

    function get_private_key()
    {
        return $this->_private_key;
    }

    function set_public_key($key)
    {
        $this->_public_key = $key;
    }

    function get_public_key()
    {
        return $this->_public_key;
    }

    /**
     * 生成簽名
     *
     * @param $salt
     * @param $private_key
     * @return string
     * @throws \Exception
     */
    function generate_signature($salt, $private_key)
    {
        $res = openssl_pkey_get_private($private_key);
        if (!openssl_sign($salt, $signature, $res)) {
            throw new ErrorException('open ssl error');
        }
        return base64_encode($signature);
    }

    /**
     * 驗證簽名是否正確
     *
     * @param $salt
     * @param $public_key
     * @param $signature
     * @return bool
     */
    function vertify_signature($salt, $public_key, $signature)
    {
        $signature = base64_decode($signature);
        $res = openssl_pkey_get_public($public_key);
        if (openssl_verify($salt, $signature, $res) === 1) {
            return true;
        } else {
            return false;
        }
    }

}

1.PC控制器方法

	        $params = [
	            'choose_installments_num' => $choose_installments_num,//分期數
	            'body' => $body,//訂單名稱 商品簡單描述
	            'out_trade_no' => $out_trade_no,//訂單號
	            'total_fee' => $price,//總價格 如果購買多個商品,就是多個商品的總價 ,
	        ];
	    	$returnDa = new \lfqpay\LebaifenPay;
	    	$result=$returnDa->buildRequestForm($params);

2.移動方法(API接口方式)

參數組成一個網址形式返回給前端網頁,收到網址就是打開一個外部連接網址

https://tt.lfqpay.com/lfq-pay/gateway/api/frontTransRequest.do?certId=&version=&txnType=&frontUrl=&backUrl=&encoding=&merId=&merName=&merAbbr=&orderId=&txnTime=&txnAmt=&txnTerms=txnTermsList&merNote=&userMac=&validTime=&signature=

			        $params = [
			            'choose_installments_num' => $choose_installments_num,//分期數
			            'body' => $body,//訂單名稱 商品簡單描述
			            'out_trade_no' => $out_trade_no,//訂單號
			            'total_fee' => $price,//總價格 如果購買多個商品,就是多個商品的總價 ,
			        ];
			    	$returnDa = new \lfqpay\LebaifenPay;
			    	$result=$returnDa->buildRequestFormApp($params);
			    	if(empty($result)){
			    		throw new \Exception(json_encode(array('code'=>7001,'msg'=>'缺少必要參數','out_trade_no'=>$out_trade_no)));
			    	}
			    	$returnArr['url']=$result['url'].$result['certId'].$result['version'].$result['txnType'].$result['frontUrl'].$result['backUrl'].$result['encoding'].$result['merId'].$result['merName'].$result['merAbbr'].$result['merPwd'].$result['orderId'].$result['txnTime'].$result['txnAmt'].$result['txnTerms'].$result['txnTermsList'].$result['merNote'].$result['userMac'].$result['validTime'].$result['signature'];

重點:簽名那裏要urlencode($sign),不然網址帶+空變是空格的,會驗證失敗

 

3.回調

   //同步調回接口  樂百分分期 支付
    public function lfqpay_notify_url(){
    	$postStr=input('get.');
    	
    	if($postStr['respCode']=='0000'){//成功
    		$this->lfqpayNotify($postStr);
    	}else{
    		
            if($postStr['respCode']=='0140'){//單筆交易金額不在規定範圍內
            	$msg=',金額在600-50000元之間';
            }
            $respMsg=$postStr['respMsg'].$msg;
            
    		$this->error($respMsg,'index/user/order');
    	}
    	
    }
    
    //異步調回接口 樂百分分期 支付
    public function lfqpay_notify(){
		
		$data=input('post.');
		$orderId=input('post.orderId');
		$respMsg=input('post.respMsg');
		$respCode=input('post.respCode');

		//收到支付成功通知變更訂單狀態
		if($orderId&&$respMsg=='成功'&&$respCode=='0000'){
		 	//收到支付成功通知變更訂單狀態
			$this->lfqpayNotify($data);
			//處理完所有訂單狀態等信息後輸出success
			echo "success";
		}
		
    }
    
    //樂百分分期支付成功後回調共同的操作
    public function lfqpayNotify($data){
			//判斷合法性 
	    	$returnDa = new \lfqpay\LebaifenPay;
	    	$sign_is=$returnDa->_vertify_sign($data);
	    	if(!empty($sign_is)){
                //成功
	    	}
		    
    }

php原生demo我放個到個人百度網盤中,就不分享出來了,,有些證書不適合。。。。

發佈了1170 篇原創文章 · 獲贊 288 · 訪問量 459萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章