注意:樂百分是分測試與正式帳號的
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我放個到個人百度網盤中,就不分享出來了,,有些證書不適合。。。。