老莫的笔记本  
  
请选择 进入手机版 | 继续访问电脑版
查看: 684|回复: 1

微信支付全部流程

[复制链接]

662

主题

878

帖子

5113

积分

超级版主

Rank: 8Rank: 8

积分
5113
发表于 2021-8-30 16:26:16 | 显示全部楼层 |阅读模式
本帖最后由 周大胖子 于 2021-8-30 16:40 编辑

先说下微信支付的本项目开发状况:
1.项目前后端分离.
2.项目前端采用 react umi  ; 后端采用 laravel-admin / easywechat ;
3.项目是网页,但是是在公众号中的网页; 所以对象目前是微信浏览器.
4.项目前后端 是我一个人开发.   
5.注意你支付的页面url 需要在商户号的配置中添加  ,也就是你在哪个页点支付按钮的页面url   , 后台返回的url 不需要注册 .6.商户 公众号 需要互相绑定

微信支付提前意识:
1. 本环境适合的支付模式是 jsapi [ 基本上都是使用这个 在网页上,小程序APP啥的 例外 ]
2. 支付的 具体流程:
        2.1  客户选中商品 [前端]
        2.2  [前端] 发送信息给后端 ,后端生成一条订单 ;
        2.3  后端通过自己内部的订单号 -> 获取系统内部配置[appid 之类] ->生成一条微信订单 [ 传统说法叫做向微信下单  ]
        2.4  后端把配置返回给 [前端]
        2.5  [前端] 接收后台传回来的配置  -> 使用 WeixinJSBridge 开启微信支付 . ( WeixinJSBridge 这是微信浏览器内置的一个东西,不需要引入,直接 就在前端项目里用 )
        2.6  [前端] 展示成功或者失败的状态给客户, (这里有个知识点: 成功失败 是不需要传给后台的,后台是通过预留给微信的返回URL 来改变订单的状态 )  到这[前端]就算是结束了.
        2.7  后端,生成订单配置的时候留了一条完整的 URL 会写在配置里, 这个URL是接收微信返回值的 [ 客户支付成功或者失败后,微信会不断给你的预留接口发值,你得确认接收,并且告诉微信你处理完了,他就不发了 ].


好了 开始上代码 :  先上后台的[  也就是 2.3 / 2.4 步骤  (2.1的下单,2.2的生成订单  省略 就点一下 ,然后后台产生个单号) ]
  1. // 支付路由
  2.     public function pay( Request $request)
  3.     {

  4.         $userinfo = $request->get('userinfo');
  5.         
  6.         $ord_id =  $request->input('ord');

  7.         $config = [
  8.             // 必要配置
  9.             'app_id'             => '公众号ID',
  10.             'mch_id'             => '商户号',
  11.             'key'                => '',   // API 密钥

  12.             // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
  13.             'cert_path'          => 'we/apiclient_cert.pem', // XXX: 绝对路径!!!!
  14.             'key_path'           => 'we/apiclient_key.pem',      // XXX: 绝对路径!!!!
  15.   
  16.             'notify_url'         => 'https://****/api/payback',     //回调地址 后面的 api/payback 不是固定格式  你也可以在下单时单独设置来想覆盖它  
  17.         ];

  18.         $app = Factory::payment($config);

  19.         $result = $app->order->unify([
  20.             'body' => '加油费用',
  21.             'out_trade_no' => $ord_id,
  22.             'total_fee' => 1,
  23.             'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
  24.             'notify_url' => 'https://you.qancloud.com/api/payback', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  25.             'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
  26.             'openid' => '需要支付的用户的OPENID',
  27.         ]);
  28.         
  29.         
  30.         $payment = Factory::payment($config);

  31.         $jssdk = $payment->jssdk;

  32.         $json = $jssdk->bridgeConfig($result['prepay_id']);

  33.     //   dd( json_decode($json) );

  34.         return [
  35.             'code'=>0,
  36.             'message' =>'获取信息成功',
  37.             'data' => json_decode($json)
  38.         ];



  39.     }





复制代码




[ 前端 2.5/ 2.6步骤 ,前端 要做的 就这么多 ,大部分其实在后端]
  1. WeixinJSBridge.invoke(
  2.                         'getBrandWCPayRequest', 这个参数填上面返回的json,也就是 data 里的值 ,
  3.                         function (res) {
  4.                             if (res.err_msg === "get_brand_wcpay_request:ok") {
  5.         history.push('/web/paybacksuccess');
  6.                                 // 支付成功
  7.                             } else if (res.err_msg === "get_brand_wcpay_request:cancel") {
  8.                                 //用户取消支付
  9.        history.push('/web/paybackfail');
  10.                             } else if (res.err_msg === "get_brand_wcpay_request:fail") {
  11.                                 //  支付失败
  12.     history.push('/web/paybackfail');
  13.                             }
  14.                         }
  15.                     )
复制代码


[后端 2.7步骤  处理微信后台 不断给我发来的返回值 ]
  1. // 支付回调路由
  2.     public function payBack( Request $request )
  3.     {
  4.         $config = [
  5.             // 必要配置

  6.         ];

  7.         $app = Factory::payment($config);
  8.         $response = $app->handlePaidNotify(function($message, $fail){
  9.             // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
  10.             // $order = 查询订单($message['out_trade_no']);
  11.             $order = JyOrder::where('ord_id', $message['out_trade_no'])->first();
  12.             
  13.             
  14.             Cache::put('paymessage', $message ,now()->addMinutes(60));
  15.         
  16.             if (!$order || $order->paid_at) { // 如果订单不存在 或者 订单已经支付过了
  17.                 return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
  18.             }
  19.         
  20.             ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况,确认是已经支付 /////////////
  21.         
  22.             if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
  23.                 // 用户是否支付成功
  24.                 if (array_get($message, 'result_code') === 'SUCCESS') {
  25.                     $order->paid_at = date("Y-m-d H:i:s",time()) ; // 更新支付时间为当前时间
  26.                     $order->payment_status = 3;
  27.                     $this->addLogs( $message['out_trade_no'], 5, "客户已微信支付" );
  28.                     
  29.                 // 用户支付失败
  30.                 } elseif (array_get($message, 'result_code') === 'FAIL') {
  31.                     $order->payment_status = 7;
  32.                 }
  33.             } else {
  34.                 return $fail('通信失败,请稍后再通知我');
  35.             }
  36.         
  37.             $order->save(); // 保存订单
  38.         
  39.             return true; // 返回处理完成
  40.         });
  41.         
  42.         $response->send(); // return $response;
  43.         // Cache::put('wxpay',  $request ,now()->addMinutes(60));

  44.     }




复制代码



完结









回复

使用道具 举报

662

主题

878

帖子

5113

积分

超级版主

Rank: 8Rank: 8

积分
5113
 楼主| 发表于 2021-8-30 16:38:55 | 显示全部楼层
贴一个微信返回的数据格式:
{
        "appid": "",
        "bank_type": "OTHERS",
        "cash_fee": "1",
        "fee_type": "CNY",
        "is_subscribe": "Y",
        "mch_id": "",
        "nonce_str": "",
        "openid": "",
        "out_trade_no": "20212068",
        "result_code": "SUCCESS",
        "return_code": "SUCCESS",
        "sign": "60B5F638DF7B2CB88F1BDD8F3947A074",
        "time_end": "20210830145512",
        "total_fee": "1",
        "trade_type": "JSAPI",
        "transaction_id": "4200001198202108302865001992"
}


参考链接: https://www.easywechat.com/docs/5.x/payment/notify  

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表