2023.6.23,yansongda/pay微信支付配置,新版endroid/qr-code生成二维码
L05 Laravel 教程 - 电商实战 ( Laravel 8.x)
7.8. 完善支付后逻辑
- 微信商户平台产品中心的扫码支付现在改为native支付
- 回调链接新版设置
$config['wechat']['default']['notify_url'] = ngrok_url('payment.wechat.notify');
- 根据官方文档 pay.weixin.qq.com/wiki/doc/apiv3/a... ,支付通知功能必须设置apiv3秘钥
下载微信平台公钥证书,设置到配置文件pay.php
下载方式参考文档底部的说明pay.yansongda.cn/docs/v3/quick-sta...
// 下载微信平台公钥证书,下载一次就可以了,没失效就可以一直用
public function getWechatPublicCerts(){
$config = config('pay');
//判断当前项目运行环境是否为线上环境
if (app()->environment() !== 'production') {
$config['logger']['level'] = 'debug';
} else {
$config['logger']['level'] = 'info';
}
$config['wechat']['default']['notify_url'] = ngrok_url('payment.wechat.notify');
Pay::config($config);
$params = [
'_config' => 'default' // 多租户配置时使用
];
\Yansongda\Pay\get_wechat_public_certs($params, resource_path('wechat_pay'));
dd('保存成功');
}
public function payByWechat(Order $order, Request $request) {
// 校验权限
$this->authorize('own', $order);
// 校验订单状态
if ($order->paid_at || $order->closed) {
throw new InvalidRequestException('订单状态不正确');
}
// scan 方法为拉起微信扫码支付
// 之前是直接返回,现在把返回值放到一个变量里
$wechatOrder = app(Wechat::class)->scan([
'out_trade_no' => $order->no,
'description' => '支付 Laravel Shop 的订单:' . $order->no,
'amount' => [
'total' => $order->total_amount * 100, // 以分为单位,传int类型
],
]);
// "endroid/qr-code": "^4.8"新版本生成二维码
$qrCode = Builder::create()
->writer(new PngWriter())
->writerOptions([])
->data($wechatOrder->code_url)
->encoding(new Encoding('UTF-8'))
->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
->size(300)
->margin(10)
->roundBlockSizeMode(new RoundBlockSizeModeMargin())
// ->logoPath(__DIR__.'/assets/symfony.png')
// ->logoResizeToWidth(50)
// ->logoPunchoutBackground(true)
// ->labelText('请使用微信支付')
// ->labelFont(new NotoSans(20))
// ->labelAlignment(new LabelAlignmentCenter())
->validateResult(false)
->build();
// 将生成的二维码图片数据以字符串形式输出,并带上相应的响应类型
return response($qrCode->getString(), 200, ['Content-Type' => $qrCode->getMimeType()]);
}
public function wechatNotify() {
$wechatPay = app(Wechat::class);
// 校验回调参数是否正确
$data = $wechatPay->callback();
$trade_state = $data['resource']['ciphertext']['trade_state'] ?? false;
$payment_no=$data['resource']['ciphertext']['transaction_id'];
$out_trade_no=$data['resource']['ciphertext']['out_trade_no'];
// \Log::info('收到微信支付通知', $data->toArray());
// \Log::info($trade_state);
if ($trade_state !== 'SUCCESS') {
return $wechatPay->success();
}
// 找到对应的订单
$order = Order::where('no', $out_trade_no)->first();
// 订单不存在则告知微信支付
if (!$order) {
\Log::info('订单不存在');
return 'fail';
}
// 订单已支付
if ($order->paid_at) {
// 告知微信支付此订单已处理
return $wechatPay->success();
}
// 将订单标记为已支付
$order->update([
'paid_at' => Carbon::now(),
'payment_method' => 'wechat',
'payment_no' => $payment_no,
]);
// 触发订单已支付事件
$this->afterPaid($order);
return $wechatPay->success();
}
protected function afterPaid(Order $order)
{
event(new OrderPaid($order));
}
2023.6当前版本的微信支付回调的返回值和支付宝的不一样,如果按教程来,会获取不到transaction_id,进而出问题
支付宝:
微信:
最后测试支付成功
数据库订单状态更新
发送邮件
本作品采用《CC 协议》,转载必须注明作者和本文链接
yansongda 文档的绿色和橙色方框很漂亮,要是各种文档都这么好看就好了。