一.准备工作
1.下载微信官方PHP的SDK,里面有个rootca.pem要用到,在php.ini里配置curl.cainfo=你存放rootca.pem的绝对路径,重启PHP
2.composer集成easywechat的laravel版本,具体怎么使用点这里
2.1
composer require "overtrue/laravel-wechat:~3.0"
2.2
Laravel 应用
- 注册
ServiceProvider :
Overtrue\LaravelWechat\ServiceProvider::class,
- 创建配置文件:
php artisan vendor:publish --provider="Overtrue\LaravelWechat\ServiceProvider"
-
请修改应用根目录下的 config/wechat.php 中对应的项即可; -
(可选)添加外观到 config/app.php 中的 aliases 部分:
'EasyWeChat' => Overtrue\LaravelWechat\Facade::class,
二.创建控制器WechatController.php
或许有些人看到这里有一些懵,讲一下流程:
1.自己创建一个订单(就是数据库里新建一个订单记录,相信谁都会吧。。),这个订单里有金额,购买人的user_id,支付状态status等信息
2.创建好订单后,这时我们就要去微信端申请支付了,目的是申请微信的预支付ID,有了预支付ID才能付款。拿订单id是为了拿到里面的金额money信息,而且还要给这个订单添加一个out_trade_no的字段信息,这个out_trade_no的信息,就是将来微信回调的时候来找你这个订单的。
3.支付完成后,微信会一直POST你的回调地址(注意是post,所以要去中间件里,关掉这个回调地址的csrf验证),这个回调方法就是通过out_trade_no找到这个订单,然后更改订单状态的。
PS:我这里给出的都是function方法,具体路由还是去routes.php需要自己建哦。
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Input; use App\Models\ExampleOrder; //这是我的模型 use EasyWeChat\Foundation\Application; use EasyWeChat\Payment\Order; class WechatController extends Controller protected function options(){ //选项设置 'app_id' => 'xxxxxxxxx', //你的APPID 'secret' => 'xxxxxxxxx', // AppSecret // 'token' => 'your-token', // Token // 'aes_key' => '', // EncodingAESKey,安全模式下请一定要填写!!! 'merchant_id' => '你的商户ID,MCH_ID', // 'cert_path' => 'path/to/your/cert.pem', // XXX: 绝对路径!!!! // 'key_path' => 'path/to/your/key', // XXX: 绝对路径!!!! 'notify_url' => '你的回调地址', // 你也可以在下单时单独设置来想覆盖它 // 'device_info' => '013467007045764', // 'sub_merchant_id' => '', //传入订单ID即可,我这里是通过订单,来查询该订单的金额,当然你也可以自定义金额 $id = Input::get('order_id');//传入订单ID $order_find = ExampleOrder::find($id); //找到该订单 $mch_id = xxxxxxx;//你的MCH_ID $options = $this->options(); $app = new Application($options); $payment = $app->payment; $out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号 'trade_type' => 'APP', // JSAPI,NATIVE,APP... 'detail' => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义 'out_trade_no' => $out_trade_no, 'total_fee' => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100 // 'notify_url' => 'http:///order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 // 'openid' => '当前用户的 openid', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识, $order = new Order($attributes); $result = $payment->prepare($order); if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){ $order_find->out_trade_no = $out_trade_no; //在这里更新订单的支付ID // return response()->json(['result'=>$result]); $prepayId = $result->prepay_id; $config = $payment->configForAppPayment($prepayId); return response()->json($config); public function paySuccess(){ $options = $this->options(); $app = new Application($options); $response = $app->payment->handleNotify(function($notify, $successful){ // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 $order = ExampleOrder::where('out_trade_no',$notify->out_trade_no)->first(); if (count($order) == 0) { // 如果订单不存在 return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 if ($order->pay_time) { // 假设订单字段“支付时间”不为空代表已经支付 return true; // 已经支付成功了就不再更新了 $order->pay_time = time(); // 更新支付时间为当前时间 $order->status = 6; //支付成功, $order->status = 2; //待付款
大功告成,是不是很EASY呀~
改成微信网页端支付也很简单,多传一个参数open_id,然后把类型改为JSAPI,然后去渲染一个页面就行
$id = Input::get('order_id');//传入订单ID $order_find = ExampleOrder::find($id); //找到该订单 $mch_id = xxxxxxx;//你的MCH_ID $options = $this->options(); $app = new Application($options); $payment = $app->payment; $out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'detail' => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义 'out_trade_no' => $out_trade_no, 'total_fee' => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100 // 'notify_url' => 'http:///order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => '当前用户的 openid', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识, $order = new Order($attributes); $result = $payment->prepare($order); if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){ $order_find->out_trade_no = $out_trade_no; //在这里更新订单的支付ID // return response()->json(['result'=>$result]); $prepayId = $result->prepay_id; $config = $payment->configForAppPayment($prepayId); return response()->json($config);
渲染页面的方法
public function payOrder(){ //支付订单页面 $order_id = Input::get('order_id'); $order = ExampleOrder::find($order_id); $config = $this->payment($order->pay_id); return view('home.mobile.pay_order')
然后前端实现
<h1>支付{{$order->money}}元</h1> <input type="button" value="支付" id="pay"> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> wx.config(<?php echo $js->config(array('chooseWXPay'), false) ?>); //这里改成true就可以打开微信js的调试模式 // timestamp: {{$config["timestamp"]}}, // nonceStr: '{{$config["nonceStr"]}}', // package: '{{$config["package"]}}', // signType: '{{$config["signType"]}}', // paySign: '{{$config["paySign"]}}', // 支付签名 // success: function (res) { // window.location.href='/myorder'; $('#pay').click(function(){ timestamp: {{$config['timestamp']}}, nonceStr: '{{$config['nonceStr']}}', package: '{{$config['package']}}', signType: '{{$config['signType']}}', paySign: '{{$config['paySign']}}', // 支付签名 success: function (res) { window.location.href='/mobile';
|