分享

 Laravel使用EasyWechat,3分钟完成微信支付

 中间件 2021-08-11

一.准备工作

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 应用

  1. 注册 ServiceProvider:
Overtrue\LaravelWechat\ServiceProvider::class,
  1. 创建配置文件:
php artisan vendor:publish --provider="Overtrue\LaravelWechat\ServiceProvider"
  1. 请修改应用根目录下的 config/wechat.php 中对应的项即可;

  2. (可选)添加外观到 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需要自己建哦。

 

 

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

 

 

 

 

 

 

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

 

 

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

 

  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:///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. }


渲染页面的方法

 

 

 

 

  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. }


然后前端实现

 

 

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

 

 

 

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多