注意:乐百分是分测试与正式帐号的
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接口方式)
参数组成一个网址形式返回给前端网页,收到网址就是打开一个外部连接网址
- $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我放个到个人百度网盘中,就不分享出来了,,有些证书不适合。。。。



















