zoukankan      html  css  js  c++  java
  • laravel 使用EasyWechat 3分钟完成微信支付(以APP支付为例)

    上一篇写了支付宝支付,然后这段时间我又把微信支付给接上了,作为萌新的我还是很有成就感的,哈哈~~好了,该写正事了。

    第一步:创建应用及配配置

       首先到微信的官方平台注册应用https://pay.weixin.qq.com/index.php/core/info(我这个我我们产品经理注册的,具体步骤就不说了啊,慢慢捣鼓吧)

      注册完应用有一个APPID和一个API密钥(需设置),主要是这两个;

    第二步:引入easywechat这个包

      composer require "overtrue/laravel-wechat:~4.0"  

      这个步骤安装查看他的官方文档https://www.easywechat.com/

      记得生成wechat.php配置文件,里面的回调地址notify_url你自己设置就好了,不需要像支付宝那样去官网设置的。

       

      1 <?php
      2 
      3 /*
      4  * This file is part of the overtrue/laravel-wechat.
      5  *
      6  * (c) overtrue <i@overtrue.me>
      7  *
      8  * This source file is subject to the MIT license that is bundled
      9  * with this source code in the file LICENSE.
     10  */
     11 
     12 return [
     13     'secret' => env('WECHAT_SECRET', ''),
     14     /*
     15      * 默认配置,将会合并到各模块中
     16      */
     17     'defaults' => [
     18         /*
     19          * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
     20          */
     21         'response_type' => 'array',
     22 
     23         /*
     24          * 使用 Laravel 的缓存系统
     25          */
     26         'use_laravel_cache' => true,
     27 
     28         /*
     29          * 日志配置
     30          *
     31          * level: 日志级别,可选为:
     32          *                 debug/info/notice/warning/error/critical/alert/emergency
     33          * file:日志文件位置(绝对路径!!!),要求可写权限
     34          */
     35         'log' => [
     36             'level' => env('WECHAT_LOG_LEVEL', 'debug'),
     37             'file' => env('WECHAT_LOG_FILE', storage_path('logs/wechat.log')),
     38         ],
     39     ],
     40 
     41     /*
     42      * 路由配置
     43      */
     44     'route' => [
     45         /*
     46          * 开放平台第三方平台路由配置
     47          */
     48         // 'open_platform' => [
     49         //     'uri' => 'serve',
     50         //     'action' => OvertrueLaravelWeChatControllersOpenPlatformController::class,
     51         //     'attributes' => [
     52         //         'prefix' => 'open-platform',
     53         //         'middleware' => null,
     54         //     ],
     55         // ],
     56     ],
     57 
     58     /*
     59      * 公众号
     60      */
     61     'official_account' => [
     62         'default' => [
     63             'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'your-app-id'),         // AppID
     64             'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', 'your-app-secret'),    // AppSecret
     65             'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'your-token'),           // Token
     66             'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),                 // EncodingAESKey
     67 
     68             /*
     69              * OAuth 配置
     70              *
     71              * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
     72              * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
     73              */
     74             // 'oauth' => [
     75             //     'scopes'   => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
     76             //     'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/examples/oauth_callback.php'),
     77             // ],
     78         ],
     79     ],
     80 
     81     /*
     82      * 开放平台第三方平台
     83      */
     84 //     'open_platform' => [
     85 //         'default' => [
     86 //             'app_id'  => env('WECHAT_OPEN_PLATFORM_APPID', ''),
     87 //             'secret'  => env('WECHAT_OPEN_PLATFORM_SECRET', '7795af6a2da27474b025b2cbfe83ad51'),
     88 //             'token'   => env('WECHAT_OPEN_PLATFORM_TOKEN', ''),
     89 //             'aes_key' => env('WECHAT_OPEN_PLATFORM_AES_KEY', ''),
     90 //         ],
     91 //     ],
     92 
     93     /*
     94      * 小程序
     95      */
     96     // 'mini_program' => [
     97     //     'default' => [
     98     //         'app_id'  => env('WECHAT_MINI_PROGRAM_APPID', ''),
     99     //         'secret'  => env('WECHAT_MINI_PROGRAM_SECRET', ''),
    100     //         'token'   => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
    101     //         'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),
    102     //     ],
    103     // ],
    104 
    105     /*
    106      * 微信支付
    107      */
    108      'payment' => [
    109          'default' => [
    110              'sandbox'            => env('WECHAT_PAYMENT_SANDBOX', false),
    111              'app_id'             => env('WECHAT_PAYMENT_APPID', ''),
    112              'mch_id'             => env('WECHAT_PAYMENT_MCH_ID', ''),
    113              'key'                => env('WECHAT_PAYMENT_KEY', ''),
    114              'cert_path'          => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'),    // XXX: 绝对路径!!!!
    115              'key_path'           => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'),      // XXX: 绝对路径!!!!
    116              'notify_url'         => 'http://test.com/payments/wechat-notify',               // 默认支付结果通知地址
    117          ],
    118          // ...
    119      ],
    120 
    121     /*
    122      * 企业微信
    123      */
    124     // 'work' => [
    125     //     'default' => [
    126     //         'corp_id' => 'xxxxxxxxxxxxxxxxx',
    127     ///        'agent_id' => 100020,
    128     //         'secret'   => env('WECHAT_WORK_AGENT_CONTACTS_SECRET', ''),
    129     //          //...
    130     //      ],
    131     // ],
    132 ];

    第三步:创建WechatController控制器

      先生成实例,我是先参考的easyWeChat的方法,

     1 use EasyWeChatFactory;
     2 
     3 $config = [
     4     // 必要配置
     5     'app_id'             => 'xxxx',
     6     'mch_id'             => 'your-mch-id',
     7     'key'                => 'key-for-signature',   // API 密钥
     8 
     9     // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
    10     'cert_path'          => 'path/to/your/cert.pem', // XXX: 绝对路径!!!!
    11     'key_path'           => 'path/to/your/key',      // XXX: 绝对路径!!!!
    12 
    13     'notify_url'         => '默认的订单回调地址',     // 你也可以在下单时单独设置来想覆盖它
    14 ];
    15 
    16 $app = Factory::payment($config);

    然后生成订单

    1 $result = $app->order->unify([
    2     'body' => '腾讯充值中心-QQ会员充值',
    3     'out_trade_no' => '20150806125346',
    4     'total_fee' => 88,
    5     'spbill_create_ip' => '123.12.12.123', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
    6     'notify_url' => 'https://pay.weixin.qq.com/wxpay/pay.action', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
    7     'trade_type' => 'JSAPI',
    8     'openid' => 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o',
    9 ]);

    结果一直报错,原因还没查明,

    后来我换了个实例化的方法

    1  $app = app('wechat.payment');

    然后就正常了。

    上面的result返回类似

     1  [
     2   "return_code" => "SUCCESS"
     3   "return_msg" => "OK"
     4   "appid" => "wx24b673e63c158b89"
     5   "mch_id" => "1502479801"
     6   "nonce_str" => "721IkW6I2rokEEgz"
     7   "sign" => "D85AACC9B51BD59E4011F36042BA362D"
     8   "result_code" => "SUCCESS"
     9   "prepay_id" => "wx10145943342718f4169407463160082537"
    10   "trade_type" => "APP"
    11 ]

    这些信息返回给APP还是不行的,因为需要二次签名!!!我就是忘记二次签名了,结果APP一直报签名错误,找了半天的原因,结果是少了一次签名。

     1 if( $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
     2     $result = $app->jssdk->appConfig($result['prepay_id']);//第二次签名
     3     return [
     4         'code' => 'success',
     5         'msg' => $result
     6     ];
     7  }else{
     8    Log::error('微信支付签名失败:'.var_export($result,1));
     9     return false;
    10  }

    再去调用方法再签一次就好了。这样把$result里面的信息返回给APP就可以了!

    第四步:处理回调

    再APP完成支付后,微信服务器会发送一个post请求,请求地址为你未知文件中填写的notify_url

    1 Route::any('payments/wechat-notify', 'WeChatController@paySuccess');

    一定要是any,因为微信服务器先get请求一次数据,然后会再post请求一次

    然后处理回调

     1  public function paySuccess(){
     2         3         $app = app('wechat.payment');
     4         $response = $app->handlePaidNotify(function ($message, $fail) {
               //处理订单等,你的业务逻辑
    54                 return true;
    55             }
    56             // 或者错误消息
    57             $fail('Order not exists.');
    58         });
    59 
    60         return $response;
    61     }

    $message的数据类似

    这样完整的微信支付就完成了!

    本文属于个人原创,欢迎转载,转载请附链接:http://www.cnblogs.com/x-x-j/p/9019839.html

  • 相关阅读:
    计算机专业术语中英对照
    PhpStorm如何下载github上的代码到本地
    PDO学习
    Shell中特殊的变量
    Shell中变量的使用
    修改cmd的字体
    Shell的输入输出
    Shell入门第一课
    设计模式--观察者(Observer)
    eclipse中使用git提交代码到github
  • 原文地址:https://www.cnblogs.com/x-x-j/p/9019839.html
Copyright © 2011-2022 走看看