terminal = $terminal; $this->config = WeChatConfigService::getPayConfigByTerminal($terminal); $this->app = new Application($this->config); if ($userId !== null) { $this->auth = MasterWorkerAuth::where(['worker_id' => $userId, 'terminal' => $terminal])->findOrEmpty(); } } /** * @notes 发起微信支付统一下单 * @param $from * @param $order * @return array|false|string * @author 段誉 * @date 2021/8/4 15:05 */ public function pay($from, $order) { try { switch ($this->terminal) { case UserTerminalEnum::WECHAT_MMP: $config = WorkerWeChatConfigService::getMnpConfig(); $result = $this->jsapiPay($from, $order, $config['app_id']); break; default: throw new \Exception('支付方式错误'); } return [ 'config' => $result, 'pay_way' => PayEnum::WECHAT_PAY ]; } catch (\Exception $e) { $this->setError($e->getMessage()); return false; } } /** * @notes jsapiPay * @param $from * @param $order * @param $appId * @return mixed * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @author 段誉 * @date 2023/2/28 12:12 */ public function jsapiPay($from, $order, $appId) { $response = $this->app->getClient()->postJson("v3/pay/transactions/jsapi", [ "appid" => $appId, "mchid" => $this->config['mch_id'], "description" => $this->payDesc($from), "out_trade_no" => $order['pay_sn'], "notify_url" => $this->config['notify_url'], "amount" => [ "total" => intval($order['order_amount'] * 100), ], "payer" => [ "openid" => $this->auth['openid'] ], 'attach' => $from ]); $result = $response->toArray(false); $this->checkResultFail($result); return $this->getPrepayConfig($result['prepay_id'], $appId); } /** * @notes 支付描述 * @param $from * @return string * @author 段誉 * @date 2023/2/27 17:54 */ public function payDesc($from) { $desc = [ 'goods' => '商品', 'recharge' => '充值', ]; return $desc[$from] ?? '商品'; } /** * @notes 捕获错误 * @param $result * @throws \Exception * @author 段誉 * @date 2023/2/28 12:09 */ public function checkResultFail($result) { if (!empty($result['code']) || !empty($result['message'])) { throw new \Exception('微信:'. $result['code'] . '-' . $result['message']); } } /** * @notes 预支付配置 * @param $prepayId * @param $appId * @return mixed[] * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @author 段誉 * @date 2023/2/28 17:38 */ public function getPrepayConfig($prepayId, $appId) { return $this->app->getUtils()->buildBridgeConfig($prepayId, $appId); } /** * @notes 支付回调 * @return \Psr\Http\Message\ResponseInterface * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException * @throws \ReflectionException * @throws \Throwable * @author 段誉 * @date 2023/2/28 14:20 */ public function notify() { $server = $this->app->getServer(); // 支付通知 $server->handlePaid(function (Message $message) { Log::write(json_encode($message,JSON_UNESCAPED_UNICODE)); if ($message['trade_state'] === 'SUCCESS') { $extra['transaction_id'] = $message['transaction_id']; $attach = $message['attach']; $message['out_trade_no'] = mb_substr($message['out_trade_no'], 0, 18); switch ($attach) { case 'recharge': $order = RechargeOrder::where(['sn' => $message['out_trade_no']])->findOrEmpty(); if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { return true; } PayNotifyLogic::handle('recharge', $message['out_trade_no'], $extra); break; case 'goods': $order = RechargeOrder::where(['sn' => $message['out_trade_no']])->findOrEmpty(); if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { return true; } PayNotifyLogic::handle('goods', $message['out_trade_no'], $extra); break; case 'shop_goods': $order = ShopOrders::where(['sn' => $message['out_trade_no']])->findOrEmpty(); if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { return true; } PayNotifyLogic::handle('shop_goods', $message['out_trade_no'], $extra); break; } } return true; }); // 退款通知 $server->handleRefunded(function (Message $message) { return true; }); return $server->serve(); } }