微信支付全部流程
本帖最后由 周大胖子 于 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后端通过自己内部的订单号 -> 获取系统内部配置 ->生成一条微信订单 [ 传统说法叫做向微信下单]
2.4后端把配置返回给 [前端]
2.5[前端] 接收后台传回来的配置-> 使用 WeixinJSBridge 开启微信支付 . ( WeixinJSBridge 这是微信浏览器内置的一个东西,不需要引入,直接 就在前端项目里用 )
2.6[前端] 展示成功或者失败的状态给客户, (这里有个知识点: 成功失败 是不需要传给后台的,后台是通过预留给微信的返回URL 来改变订单的状态 )到这[前端]就算是结束了.
2.7后端,生成订单配置的时候留了一条完整的 URL 会写在配置里, 这个URL是接收微信返回值的 [ 客户支付成功或者失败后,微信会不断给你的预留接口发值,你得确认接收,并且告诉微信你处理完了,他就不发了 ].
好了 开始上代码 :先上后台的[也就是 2.3 / 2.4 步骤(2.1的下单,2.2的生成订单省略 就点一下 ,然后后台产生个单号) ] // 支付路由
public function pay( Request $request)
{
$userinfo = $request->get('userinfo');
$ord_id =$request->input('ord');
$config = [
// 必要配置
'app_id' => '公众号ID',
'mch_id' => '商户号',
'key' => '', // API 密钥
// 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
'cert_path' => 'we/apiclient_cert.pem', // XXX: 绝对路径!!!!
'key_path' => 'we/apiclient_key.pem', // XXX: 绝对路径!!!!
'notify_url' => 'https://****/api/payback', //回调地址 后面的 api/payback 不是固定格式你也可以在下单时单独设置来想覆盖它
];
$app = Factory::payment($config);
$result = $app->order->unify([
'body' => '加油费用',
'out_trade_no' => $ord_id,
'total_fee' => 1,
'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
'notify_url' => 'https://you.qancloud.com/api/payback', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
'openid' => '需要支付的用户的OPENID',
]);
$payment = Factory::payment($config);
$jssdk = $payment->jssdk;
$json = $jssdk->bridgeConfig($result['prepay_id']);
// dd( json_decode($json) );
return [
'code'=>0,
'message' =>'获取信息成功',
'data' => json_decode($json)
];
}
[ 前端 2.5/ 2.6步骤 ,前端 要做的 就这么多 ,大部分其实在后端]
WeixinJSBridge.invoke(
'getBrandWCPayRequest', 这个参数填上面返回的json,也就是 data 里的值 ,
function (res) {
if (res.err_msg === "get_brand_wcpay_request:ok") {
history.push('/web/paybacksuccess');
// 支付成功
} else if (res.err_msg === "get_brand_wcpay_request:cancel") {
//用户取消支付
history.push('/web/paybackfail');
} else if (res.err_msg === "get_brand_wcpay_request:fail") {
//支付失败
history.push('/web/paybackfail');
}
}
)
[后端 2.7步骤处理微信后台 不断给我发来的返回值 ] // 支付回调路由
public function payBack( Request $request )
{
$config = [
// 必要配置
];
$app = Factory::payment($config);
$response = $app->handlePaidNotify(function($message, $fail){
// 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
// $order = 查询订单($message['out_trade_no']);
$order = JyOrder::where('ord_id', $message['out_trade_no'])->first();
Cache::put('paymessage', $message ,now()->addMinutes(60));
if (!$order || $order->paid_at) { // 如果订单不存在 或者 订单已经支付过了
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况,确认是已经支付 /////////////
if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
// 用户是否支付成功
if (array_get($message, 'result_code') === 'SUCCESS') {
$order->paid_at = date("Y-m-d H:i:s",time()) ; // 更新支付时间为当前时间
$order->payment_status = 3;
$this->addLogs( $message['out_trade_no'], 5, "客户已微信支付" );
// 用户支付失败
} elseif (array_get($message, 'result_code') === 'FAIL') {
$order->payment_status = 7;
}
} else {
return $fail('通信失败,请稍后再通知我');
}
$order->save(); // 保存订单
return true; // 返回处理完成
});
$response->send(); // return $response;
// Cache::put('wxpay',$request ,now()->addMinutes(60));
}
完结
贴一个微信返回的数据格式:
{
"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
页:
[1]