微信扫码支付用起来还是很方便的,如果使用微信支付官方的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相关的配置项,配置好之后,在控制器内开始使用:
②控制器代码:
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通知商户支付状态已经传回诸如商户单号等参数,方便商户操作站点内的订单的状态等:
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个小时,朋友们可以自行处理,微信扫码支付就这么做完了,希望可以给一些朋友提供一些参考。
最后贴一张效果截图:
原创文字,转载请注明出处。