TP5 -- 微信支付整合(APP,JSAPI)
生活随笔
收集整理的這篇文章主要介紹了
TP5 -- 微信支付整合(APP,JSAPI)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
原本項目上有一個提現(xiàn)功能,因原客戶商戶號和流水原因一直沒做。
最近因為剛剛符合條件的原因,今天才開始做。
順便瀏覽下博客,發(fā)現(xiàn)原來寫的微信支付有些那個啥了。
因為最近項目前后端分離居多,而且項目也多JSAPI、APP、NATIVE等多種一起居多
所以就將原來的微信支付 重新整合了下
與原來的相比,整合過后的更適用于前后端分離來做
如果沒有前后端分離,還可以借鑒原來的公眾號支付:tp5 -- 微信公眾號支付
不過最好還是自己調整下,畢竟那個代碼比較久了
好了,話不多說,還是直接上代碼吧
因為此支付是自己封裝,同樣還是在 extend/ 文件下 的Wxpay.php
代碼如下:
<?php
namespace pay;
class Wxpay{
private $config =[
"appid" => "", // 開放平臺或商戶平臺APPID
"mch_id" => "", // 商戶平臺 商戶號
"key" => "", // 商戶平臺 秘鑰KEY
"TOKEN" => "", // 此參數(shù)非必傳 有的前端在jsapi 支付時會要求返回signature 參數(shù) 此參數(shù)即為此準備
];
public function index($param,$openid="")
{
$order = [
'out_trade_no' => $param['out_trade_no'],// 訂單號
'total_fee' => intval($param['total_fee']*100),// 訂單金額 以(分)為單位
'body' => $param['body'],// 商品描述
'notify_url' => $param['notify_url'], //回調地址
'spbill_create_ip' => $param['spbill_create_ip'], //對應IP
'trade_type' => $param['trade_type'] //對應支付類型
];
#當支付類型為JAPI時 openid 必傳
if($param['trade_type'] == "JSAPI")
{
$order['openid'] = $openid;
}
#統(tǒng)一下單 獲取prepay_id
$unified_order=$this->unifiedOrder($order);
#獲取當前時間戳
$time = time();
#JSAPI
if($param['trade_type'] == 'JSAPI')
{
#組合jssdk需要用到的數(shù)據(jù)
$data = [
'appId' => $this->config['appid'], //appid
'timeStamp' => strval($time), //時間戳
'nonceStr' =>$unified_order['nonce_str'],// 隨機字符串
'package' => 'prepay_id='.$unified_order['prepay_id'],// 預支付交易會話標識
'signType' => 'MD5' //加密方式
];
// 生成簽名
$data['paySign']=$this->makeSign($data);
// #有的可能會有需求signature 此參數(shù)的在此加密一下即可
// $token = $this->config['token'];
// $tmpArr = array($token, strval($time),$unified_order['nonce_str']);
// sort($tmpArr, SORT_STRING);
// $tmpStr = implode( $tmpArr );
// $tmpStr = sha1($tmpStr);
// $data['signature'] = $tmpStr;
}
#APP
elseif($param['trade_type'] == 'APP')
{
$data = [
'appid' => $this->config['appid'],
'partnerid' => $this->config['mch_id'],
'prepayid' => $unified_order['prepay_id'],
'package' => 'Sign=WXPay',
'noncestr' => $unified_order['nonce_str'],// 隨機字符串
'timestamp' => strval($time), //時間戳
];
//生成簽名
$data['sign'] = $this->makeSign($data);
}
return $data;
}
/**
* 統(tǒng)一下單
* @param array $order 訂單 必須包含支付所需要的參數(shù) body(產品描述)、total_fee(訂單金額)、out_trade_no(訂單號)、product_id(產品id)、trade_type(類型:JSAPI,NATIVE,APP)
*/
public function unifiedOrder($order)
{
$config =[
'appid' => $this->config['appid'], //appid
'mch_id' => $this->config['mch_id'], //商戶號ID
'nonce_str' => $this->getNonceStr()
];
# 合并配置數(shù)據(jù)和訂單數(shù)據(jù)
$data=array_merge($order,$config);
# 生成簽名
$sign=$this->makeSign($data);
$data['sign']=$sign;
#轉換成xml
$xml=$this->toXml($data);
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //接收xml數(shù)據(jù)的文件
$header[] = "Content-type: text/xml"; //定義content-type為xml,注意是數(shù)組
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 兼容本地沒有指定curl.cainfo路徑的錯誤
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$response = curl_exec($ch);
if(curl_errno($ch)){
# 顯示報錯信息;終止繼續(xù)執(zhí)行
die(curl_error($ch));
}
curl_close($ch);
#轉換成數(shù)組
$result=$this->toArray($response);
#顯示錯誤信息
if ($result['return_code']=='FAIL')
{
die($result['return_msg']);
}
$result['sign']=$sign;
$result['nonce_str']=$this->getNonceStr();
return $result;
}
/**
* 生成簽名
* @return 簽名,本函數(shù)不覆蓋sign成員變量,如要設置簽名需要調用SetSign方法賦值
*/
public function makeSign($data)
{
# 去空
$data=array_filter($data);
#簽名步驟一:按字典序排序參數(shù)
ksort($data);
#將數(shù)組轉成url形式
$string_a=http_build_query($data);
$string_a=urldecode($string_a);
#簽名步驟二:在string后加入KEY
$string_sign_temp=$string_a."&key=".$this->config['key'];
#簽名步驟三:MD5加密
$sign = md5($string_sign_temp);
# 簽名步驟四:所有字符轉為大寫
$result=strtoupper($sign);
return $result;
}
/**
* 將xml轉為array
* @param string $xml xml字符串
* @return array 轉換得到的數(shù)組
*/
public function toArray($xml){
#禁止引用外部xml實體
libxml_disable_entity_loader(true);
$result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
}
/**
*
* 產生隨機字符串,不長于32位
* @param int $length
* @return 產生的隨機字符串
*/
public function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ )
{
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/**
* 輸出xml字符
* @throws WxPayException
**/
public function toXml($data)
{
if(!is_array($data) || count($data) <= 0)
{
throw new WxPayException("數(shù)組數(shù)據(jù)異常!");
}
$xml = "<xml>";
foreach ($data as $key=>$val){
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* 驗證
* @return array 返回數(shù)組格式的notify數(shù)據(jù)
*/
public function notify()
{
// 獲取xml
$xml=file_get_contents('php://input', 'r');
# 轉成php數(shù)組
$data=$this->toArray($xml);
# 保存原sign
$data_sign=$data['sign'];
# sign不參與簽名
unset($data['sign']);
$sign=$this->makeSign($data);
# 判斷簽名是否正確 判斷支付狀態(tài)
if ($sign===$data_sign && $data['return_code']=='SUCCESS' && $data['result_code']=='SUCCESS')
{
$result=$data;
}else{
$result=false;
}
# 返回狀態(tài)給微信服務器
if ($result)
{
$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}else{
$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名失敗]]></return_msg></xml>';
}
return $result;
}
}
?>
下面就是調用方法超級簡單:
<?php
namespace appindexcontroller;
header("Content-Type: text/html;charset=utf-8");
use thinkController;
use payWxpay;
class Buy extends Controller
{
#新的微信支付類調用
public function newpay()
{
$pay_sn = date('YmdHis').rand(1000,9999);
$total_fee = '0.01';
$body = "商品描述";
$spbill_create_ip = '192.168.0.1';
$notify_url = "你的回調地址"; #根據(jù)不同類型回調地址不同
$trade_type = 'APP';
#JSAPI--JSAPI支付(或小程序支付)、
#NATIVE--Native支付、
#APP--app支付,
#MWEB--H5支付,
#不同trade_type決定了調起支付的方式,請根據(jù)支付產品正確上傳
#新的需要參數(shù)為六個
# out_trade_no 商戶訂單號
# total_fee 訂單總額
# body 商品描述
# spbill_create_ip 終端IP
# notify_url 回調通知地址
# trade_type 交易類型
$wxpay = new Wxpay();
$date = [
'out_trade_no' => $pay_sn,
'total_fee' => $total_fee,
'body' => $body,
'spbill_create_ip' => getIp(),
'notify_url' => $notify_url,
'trade_type' => $trade_type
];
#根據(jù) trade_type 類型不同,是否傳遞openid
#APP 類型支付調用
$res = $wxpay->index($date);
#JSAPI 類型支付調用
$res = $wxpay->index($date,$openid);
#獲得后將對應內容返回前端即可
return $res;
}
}
?>
最后就是回調咯:
<?php
namespace appindexcontroller;
header("Content-Type: text/html;charset=utf-8");
use thinkController;
use payWxpay;
class Pays extends Controller
{
public function notify()
{
$wxpay = new Wxpay();
$result = $wxpay->notify();
#根據(jù)拿到的數(shù)據(jù) 來進行自己的數(shù)據(jù)邏輯
if($result)
{
$out_trade_no = $result['out_trade_no'];
echo "success";exit;
}
echo "error";
}
}
?>
以上就是本次整合的微信支付咯
感謝各位大大的觀看。
2020年4月17日
總結
以上是生活随笔為你收集整理的TP5 -- 微信支付整合(APP,JSAPI)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php mysql_connect 不支
- 下一篇: html中div边框线的设置方法