微信掃碼支付用起來還是很友善的,如果使用微信支付官方的sdk開發也是可以的,不過還是選擇了easywechat,主要還是因為easywechat內建了各種功能,基本上和微信相關的接口都做了比較不錯的封裝,因為要同時使用很多功能,索性微信掃碼支付也一并用easywechat做了,而且不得不說使用方法是十分的簡單,不多說了直接上步驟:
1,使用composer在thinkphp5項目的根目錄安裝easywechat:
$ composer require overtrue/wechat:~3.1 -vvv
2,安裝好之後在控制器中開始使用,示例代碼:
① 配置,我這裡的相關配置項是放在extra目錄的wechat.php,内容如下:
return [
/**
* Debug 模式,bool 值:true/false
*
* 當值為 false 時,所有的日志都不會記錄
*/
'debug' => true,
/**
* 賬号基本資訊,請從微信公衆平台/開放平台擷取
*/
'app_id' => 'wx851*****5f7e8', // AppID
'secret' => 'fdb592c******3828fdfd273', // AppSecret
'token' => 'TOKEN', // Token
'aes_key' => '', // EncodingAESKey,安全模式下請一定要填寫!!!
/**
* 日志配置
*
* level: 日志級别, 可選為:
* debug/info/notice/warning/error/critical/alert/emergency
* permission:日志檔案權限(可選),預設為null(若為null值,monolog會取0644)
* file:日志檔案位置(絕對路徑!!!),要求可寫權限
*/
'log' => [
'level' => 'debug',
'permission' => 0777,
'file' => ROOT_PATH . 'runtime/wechat/easywechat.log',
],
/**
* OAuth 配置
*
* scopes:公衆平台(snsapi_userinfo / snsapi_base),開放平台:snsapi_login
* callback:OAuth授權完成後的回調頁位址
*/
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => '/examples/oauth_callback.php',
],
/**
* 微信支付
*/
'payment' => [
'merchant_id' => '135*****602',
'key' => '80b8682*****8fdac7784',
'cert_path' => ROOT_PATH . 'public/certs/wechat/apiclient_cert.pem', // XXX: 絕對路徑!!!!
'key_path' => ROOT_PATH . 'public/certs/wechat/apiclient_key.pem', // XXX: 絕對路徑!!!!
'notify_url' => 'http://*******/notify/wxpay',
],
/**
* Guzzle 全局設定
*
* 更多請參考: http://docs.guzzlephp.org/en/latest/request-options.html
*/
'guzzle' => [
'timeout' => 3.0, // 逾時時間(秒)
//'verify' => false, // 關掉 SSL 認證(強烈不建議!!!)
],
];
掃碼支付主要需要的配置是appid 已經payment相關的配置項,配置好之後,在控制器内開始使用:
②控制器代碼:
<?php
/**
* FileName:Pay.php
* Author:Graent <[email protected]> at www.diyi01.com
* Copyright:
* CreateTime:2017/10/12 18:43
* Description:
*/
namespace app\payment\controller;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment\Order;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\ErrorCorrectionLevel;
class Wxpay extends Prepay
{
public function index(){
//擷取微信配置
$wxConf = config('wechat');
//執行個體化easyWeChat
$wxApp = new Application($wxConf);
//支付訂單參數
$attributes = [
'trade_type' => 'NATIVE', // JSAPI,NATIVE,APP...
'body' => '這裡是body',
'detail' => '這裡是detail,可選',
'out_trade_no' => '自己生成自己站點的唯一單号',
'total_fee' => 1 * 100, // 機關:分// 支付結果通知網址,如果不設定則會使用配置裡的預設位址
];
//初始化訂單
$order = new Order($attributes);
//執行個體化支付
$payment = $wxApp->payment;
//預支付
$result = $payment->prepare($order);
if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
$prepayId = $result->prepay_id;
$codeUrl = $result->code_url;
//生成二維碼
$Qr = new QrCode($codeUrl);
$Qr->setSize(300)
->setWriterByName('png')
->setMargin(10)
->setEncoding('utf-8')
->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH)
->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0])
->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255])
// ->setLogoPath(ROOT_PATH . 'template/common/images/wxpay.png')
// ->setLogoWidth(65)
->setValidateResult(false);
$Qr->writeFile(ROOT_PATH . "uploads/qrcode.png");
$imgData= imgToBase64(ROOT_PATH . "uploads/qrcode.png");
return json(['errcode'=>0,'msg'=>'發起支付成功','imgData'=>$imgData]);
}else{
return json(['errcode'=>1,'msg'=>'發起支付失敗,稍後再試吧']);
}
}
}
代碼中使用的是Endroid生成的二維碼,預支付成功之後微信支付伺服器傳回的是用于生成二維碼的内容(code_url),可以自己通過一些類庫生成二維碼展現給客戶掃描就可以了,我這裡生成二維碼之後轉換成了base64傳回前端的,也可以不這樣,看你自己的需求吧,這樣發起支付基本就可以工作了,最後就是回調通知,這一步是必須的,使用者支付完成後微信支付伺服器會發post請求到商戶設定的notify_url通知商戶支付狀态已經傳回諸如商戶單号等參數,友善商戶操作站點内的訂單的狀态等:
<?php
/**
* FileName:Notify.php
* Author:Graent <[email protected]> at www.diyi01.com
* Copyright:
* CreateTime:2017/10/14 13:18
* Description:
*/
namespace app\payment\controller;
use app\payment\model\MemberFreezingAmount;
use EasyWeChat\Foundation\Application;
use think\Db;
class Notify extends Prepay
{
public function notify(){
$payType = input('paytype');
if($payType == 'wxpay'){
//微信支付notify
$wxConf = config('wechat');
$wxApp = new Application($wxConf);
$response = $wxApp->payment->handleNotify(function ($notify,$successful){
if($successful){
$rstArr = json_decode($notify,true);
$ord = (new MemberFreezingAmount())
->where('trade_no','=',$rstArr['out_trade_no'])
->find();
if($ord['status'] != 0){
Db::name('member_freezing_amount')
->where('trade_no','=',$rstArr['out_trade_no'])
->update([
'status' => 0,
'transaction_id' => $rstArr['transaction_id'],
'pay_time' => time()
]);
Db::name('mht_goods')
->where('id','=',$ord['gid'])
->setInc('bmnum');
}
return true;
}else{
return false;
}
});
return $response;
}else{
//預留處理
return false;
}
}
}
easywechat幫我們封裝了回調的處理直接使用即可 $response = $wxApp->payment->handleNotify(function ($notify,$successful){})其中$notify就是微信支付傳回的資訊,$successful是狀态,true即為成功,那麼商戶就可以進行自己的業務操作了,參考上面的帶可以實作基本的處理,如果有更多自己的邏輯自己在對應的位置增加自己的處理即可。
注意,在發起支付的時候很多人遇到過簽名錯誤的問題,一般情況仔細檢查下商戶的支付key是一下是否一緻,一般就可以解決這個問題,好了,另外微信傳回的二維碼有效期是2個小時,朋友們可以自行處理,微信掃碼支付就這麼做完了,希望可以給一些朋友提供一些參考。
最後貼一張效果截圖:
原創文字,轉載請注明出處。