Laravel使用EasyWechat微信支付 超级简单

一.准备工作

1.下载微信官方PHP的SDK,里面有个rootca.pem要用到,在php.ini里配置curl.cainfo=你存放rootca.pem的绝对路径,重启PHP

2.composer集成easywechat的laravel版本,具体怎么使用点这里

[plain]  view plain  copy
  1. composer require "overtrue/laravel-wechat:~3.0"  


二.创建控制器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需要自己建哦。


[php]  view plain  copy
  1.   
  2. namespace App\Http\Controllers;  
  3.   
  4. use Illuminate\Http\Request;  
  5.   
  6. use App\Http\Requests;  
  7. use App\Http\Controllers\Controller;  
  8. use Illuminate\Support\Facades\Input;  
  9. use Auth,Redirect;  
  10. use Validator;  
  11.   
  12. use App\Models\ExampleOrder; //这是我的模型  
  13.   
  14. use EasyWeChat\Foundation\Application;  
  15. use EasyWeChat\Payment\Order;  
  16.   
  17. class WechatController extends Controller  
  18. {  
  19.     protected function options(){ //选项设置  
  20.         return [  
  21.             // 前面的appid什么的也得保留哦  
  22.             'app_id' => 'xxxxxxxxx'//你的APPID  
  23.             'secret'  => 'xxxxxxxxx',     // AppSecret  
  24.             // 'token'   => 'your-token',          // Token  
  25.             // 'aes_key' => '',                    // EncodingAESKey,安全模式下请一定要填写!!!  
  26.             // ...  
  27.             // payment  
  28.             'payment' => [  
  29.                 'merchant_id'        => '你的商户ID,MCH_ID',  
  30.                 'key'                => '你的KEY',  
  31.                 // 'cert_path'          => 'path/to/your/cert.pem', // XXX: 绝对路径!!!!  
  32.                 // 'key_path'           => 'path/to/your/key',      // XXX: 绝对路径!!!!  
  33.                 'notify_url'         => '你的回调地址',       // 你也可以在下单时单独设置来想覆盖它  
  34.                 // 'device_info'     => '013467007045764',  
  35.                 // 'sub_app_id'      => '',  
  36.                 // 'sub_merchant_id' => '',  
  37.                 // ...  
  38.             ],  
  39.         ];  
  40.     }  
  41. //传入订单ID即可,我这里是通过订单,来查询该订单的金额,当然你也可以自定义金额  
  42.     public function pay(){  
  43.     $id = Input::get('order_id');//传入订单ID  
  44.     $order_find = ExampleOrder::find($id); //找到该订单  
  45.     $mch_id = xxxxxxx;//你的MCH_ID  
  46.         $options = $this->options();  
  47.         $app = new Application($options);  
  48.         $payment = $app->payment;  
  49.         $out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号  
  50.         $attributes = [  
  51.             'trade_type'       => 'APP'// JSAPI,NATIVE,APP...  
  52.             'body'             => '购买CSDN产品',  
  53.             'detail'           => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义  
  54.             'out_trade_no'     => $out_trade_no,  
  55.             'total_fee'        => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100  
  56.             // 'notify_url'       => 'http://xxx.com/order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址  
  57.             // 'openid'           => '当前用户的 openid', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,  
  58.             // ...  
  59.         ];  
  60.         $order = new Order($attributes);  
  61.         $result = $payment->prepare($order);  
  62.     if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){  
  63.         $order_find->out_trade_no = $out_trade_no//在这里更新订单的支付ID  
  64.         $order_find->save();  
  65.         // return response()->json(['result'=>$result]);  
  66.             $prepayId = $result->prepay_id;  
  67.             $config = $payment->configForAppPayment($prepayId);          
  68.             return response()->json($config);  
  69.     }  
  70.   
  71.     }  
  72. //下面是回调函数  
  73.     public function paySuccess(){  
  74.         $options = $this->options();  
  75.         $app = new Application($options);  
  76.         $response = $app->payment->handleNotify(function($notify$successful){  
  77.             // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单  
  78.             $order = ExampleOrder::where('out_trade_no',$notify->out_trade_no)->first();  
  79.             if (count($order) == 0) { // 如果订单不存在  
  80.                 return 'Order not exist.'// 告诉微信,我已经处理完了,订单没找到,别再通知我了  
  81.             }  
  82.             // 如果订单存在  
  83.             // 检查订单是否已经更新过支付状态  
  84.             if ($order->pay_time) { // 假设订单字段“支付时间”不为空代表已经支付  
  85.                 return true; // 已经支付成功了就不再更新了  
  86.             }  
  87.             // 用户是否支付成功  
  88.             if ($successful) {  
  89.                 // 不是已经支付状态则修改为已经支付状态  
  90.                 $order->pay_time = time(); // 更新支付时间为当前时间  
  91.                 $order->status = 6; //支付成功,  
  92.             } else { // 用户支付失败  
  93.                 $order->status = 2; //待付款  
  94.             }  
  95.             $order->save(); // 保存订单  
  96.             return true; // 返回处理完成  
  97.         });  
  98.     }  
  99.   
  100.   
  101.       
  102. }  



大功告成,是不是很EASY呀~


改成微信网页端支付也很简单,多传一个参数open_id,然后把类型改为JSAPI,然后去渲染一个页面就行

[php]  view plain  copy
  1.    public function pay(){  
  2.     $id = Input::get('order_id');//传入订单ID  
  3.     $order_find = ExampleOrder::find($id); //找到该订单  
  4.     $mch_id = xxxxxxx;//你的MCH_ID  
  5.        $options = $this->options();  
  6.        $app = new Application($options);  
  7.        $payment = $app->payment;  
  8.        $out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号  
  9.        $attributes = [  
  10.            'trade_type'       => 'JSAPI'// JSAPI,NATIVE,APP...  
  11.            'body'             => '购买CSDN产品',  
  12.            'detail'           => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义  
  13.            'out_trade_no'     => $out_trade_no,  
  14.            'total_fee'        => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100  
  15.            // 'notify_url'       => 'http://xxx.com/order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址  
  16.            'openid'           => '当前用户的 openid'// trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,  
  17.            // ...  
  18.        ];  
  19.        $order = new Order($attributes);  
  20.        $result = $payment->prepare($order);  
  21. if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){  
  22.     $order_find->out_trade_no = $out_trade_no//在这里更新订单的支付ID  
  23.     $order_find->save();  
  24.     // return response()->json(['result'=>$result]);  
  25.            $prepayId = $result->prepay_id;  
  26.            $config = $payment->configForAppPayment($prepayId);          
  27.            return response()->json($config);  
  28. }  
  29.   
  30.    }  

渲染页面的方法

[php]  view plain  copy
  1. public function payOrder(){ //支付订单页面  
  2.         $order_id = Input::get('order_id');  
  3.         $order = ExampleOrder::find($order_id);  
  4.         $config = $this->payment($order->pay_id);  
  5.         $js = EasyWeChat::js();  
  6.         return view('home.mobile.pay_order')  
  7.             ->withConfig($config)  
  8.             ->withJs($js)  
  9.             ->withOrder($order);  
  10.     }  

然后前端实现

[html]  view plain  copy
  1. <div>  
  2.     <h1>支付{{$order->money}}元h1>  
  3.     <br>  
  4.     <input type="button" value="支付" id="pay">  
  5. div>  
  6.   
  7. <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8">script>  
  8.   
  9. <script type="text/javascript" charset="utf-8">  
  10.         wx.config(php echo $js->config(array('chooseWXPay'), false) ?>); //这里改成true就可以打开微信js的调试模式  
  11.   
  12.         // wx.ready(function(){  
  13.         //     wx.chooseWXPay({  
  14.         //         timestamp: {{$config["timestamp"]}},  
  15.         //         nonceStr: '{{$config["nonceStr"]}}',  
  16.         //         package: '{{$config["package"]}}',  
  17.         //         signType: '{{$config["signType"]}}',  
  18.         //         paySign: '{{$config["paySign"]}}', // 支付签名  
  19.         //         success: function (res) {  
  20.         //             // 支付成功后的回调函数  
  21.         //             window.location.href='/myorder';  
  22.         //         }  
  23.         //     });  
  24.         // });  
  25.         $('#pay').click(function(){  
  26.             wx.chooseWXPay({  
  27.                 timestamp: {{$config['timestamp']}},  
  28.                 nonceStr: '{{$config['nonceStr']}}',  
  29.                 package: '{{$config['package']}}',  
  30.                 signType: '{{$config['signType']}}',  
  31.                 paySign: '{{$config['paySign']}}', // 支付签名  
  32.                 success: function (res) {  
  33.                     // 支付成功后的回调函数  
  34.                     window.location.href='/mobile';  
  35.                 }  
  36.             });  
  37.         });  
  38.           
  39.           
  40. script>  

你可能感兴趣的:(php)