partnerPaymentConfig = $config['partnerPayment']; $this->wechatPartnerConfig = [ 'mch_id' => $this->partnerPaymentConfig['sp_mchid'], 'secret_key' => $this->partnerPaymentConfig['secret_key'], 'certificate' => $this->partnerPaymentConfig['certificate'], 'private_key' => $this->partnerPaymentConfig['sp_mchid'], 'notify_url' => $this->partnerPaymentConfig['notify_url'], 'http' => [ 'throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启 'timeout' => 5.0, ], ]; } /** * 微信公众号、小程序支付示例(合作伙伴服务商模式) * 支付接口是需要登录的,测试结束后,请在最上方$noNeedLogin数组中去掉 pay * @param Request $request * @return void * @throws \Exception * @author jsjxsz * order_no 订单号 * body 描述 * pay_price 支付金额 * openid 用户openid * transaction_no 交易号 */ public function pay(Request $request): void { if ($request->isPost()) { $params = $request->only(['order_no', 'body', 'pay_price', 'openid', 'transaction_no']); // miniProgram: 小程序支付; offiAccount: 公众号支付 $params['pay_type'] = 'miniProgram'; $result = PartnerPayService::getInstance()->pay($params); if ($result !== false) { $this->success('success', $result); } else { $this->error('error'); } } } /** * 退款申请(退款状态需在退款回调中获取) * @param Request $request * @return void * @author jsjxsz * out_trade_no 原支付交易对应的商户订单号 * out_refund_no 商户退款单号,商户系统内部的退款单号,退款时生成,唯一 * reason 退款原因 * refund_price 退款金额 * pay_price 原交易金额 */ public function refunds(Request $request): void { if ($request->isPost()) { $params = $request->only(['pay_price', 'refund_price', 'out_trade_no','out_refund_no','reason']); $result = PartnerPayService::getInstance()->refunds($params); if ($result !== false) { $this->success('success', $result); } else { $this->error('error'); } } } /** * 服务商模式支付回调 * 注意仔细看下面的注释内容 * @return \Psr\Http\Message\ResponseInterface|void * @author jsjxsz */ public function payNotify() { try { $app = new Application($this->wechatPartnerConfig); $server = $app->getServer(); $server->handlePaid(function (Message $message, \Closure $next) use ($app) { $noyifyData = json_decode($message, true); $success_time = strtotime($noyifyData['success_time']); $out_trade_no = $noyifyData['out_trade_no']; /** * 这里写你自己的逻辑 start */ // 这里查询你自己的数据表!!! $order = Db::name('order')->where('transaction_no', $out_trade_no)->find(); if (!$order || $order['pay_status'] == 1) { // 如果订单不存在 或者 订单已经支付过了 // 告诉微信,我已经处理完了,订单没找到,别再通知我了 return ['code' => 'SUCCESS', 'message' => '成功']; } // return_code 表示通信状态,不代表支付状态 if ($noyifyData['trade_state'] === 'SUCCESS') { // pay success $total_fee = $noyifyData['amount']['payer_total'] / 100;//单位分 // 这里写你自己的回调逻辑 } elseif ($message['result_code'] === 'FAIL') { // pay fail } /** * 这里写你自己的逻辑 end */ return $next($message); }); return $server->serve(); } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) { Log::info('服务商微信支付回调通知:' . $e->getMessage()); } } /** * 服务商模式退款回调 * 注意仔细看下面的注释内容 * @return \Psr\Http\Message\ResponseInterface|void * @author jsjxsz */ public function refundsNotify() { try { $app = new Application($this->wechatPartnerConfig); $server = $app->getServer(); $server->handleRefunded(function (Message $message, \Closure $next) use ($app) { $noyifyData = json_decode($message, true); $success_time = strtotime($noyifyData['success_time']); // 退款时间 $out_refund_no = $noyifyData['out_refund_no']; /** * 这里写你自己的逻辑 start */ // 这里查询你自己的数据表!!! $order_refunds = Db::name('order_refunds')->where('out_refund_no', $out_refund_no)->find(); if (!$order_refunds || $order_refunds['refund_status'] == 1) { // 如果订单不存在 或者 订单已经支付过了 // 告诉微信,我已经处理完了,订单没找到,别再通知我了 return ['code' => 'SUCCESS', 'message' => '成功']; } // return_code 表示通信状态,不代表支付状态 if ($noyifyData['refund_status'] === 'SUCCESS') { // success } elseif ($message['result_code'] === 'FAIL') { // pay fail } /** * 这里写你自己的逻辑 end */ return $next($message); }); return $server->serve(); } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) { Log::info('服务商微信退款回调通知:' . $e->getMessage()); } } }