config = WeChatPayMerchantConfigService::getPayConfig(); $this->app = new Application($this->config); } public function wechatPayServiceMerchantAppPay($order) { try { $pay = PayConfig::where(['pay_way' => PayEnum::WECHAT_PAY])->findOrEmpty()->toArray(); $response = $this->app->getClient()->postJson('/v3/pay/partner/transactions/app', [ 'sp_appid' => $pay['config']['app_id'], 'sp_mchid' => $pay['config']['mch_id'], 'sub_mchid' => $order['collection_account'], 'description' => PayOrderEnum::getPayOrderTypeDesc($order['order_type']), 'out_trade_no' => $order['order_no'], 'notify_url' => $this->config['notify_url'], 'amount' => [ 'total' => intval($order['total_fee']), 'currency' => 'CNY' ], 'attach' => $order['order_no'], ]); \think\facade\Log::info(['微信服务商APP支付api-config', $this->config]); $result = $response->toArray(false); \think\facade\Log::info(['微信服务商APP支付api-微信支付返回值', $result]); $this->checkResultFail($result); $re = $this->app->getUtils()->buildAppConfig($result['prepay_id'], $pay['config']['app_id']); $re['partnerid'] = $order['collection_account']; return $re; } catch (\Exception $e) { $this->setError($e->getMessage()); return false; } } /** * @notes 退款 * @param array $refundData * @return mixed * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @author 段誉 * @date 2023/2/28 16:53 */ public function refund($refundOrder) { $payOrder = PayOrder::where(['order_no' => $refundOrder['order_sn'], 'pay_status'=>PayOrderEnum::PAY_STATUS_ISPAID])->find(); $response = $this->app->getClient()->postJson('/v3/refund/domestic/refunds', [ 'sub_mchid' => $payOrder['collection_account'], 'out_refund_no' => $payOrder['order_no'], 'notify_url' => (string)url('wechat_pay_service_merchant_pay/notifyApp', [], false, true), 'amount' => [ 'refund' => $refundOrder['refund_amount'], 'total' => $refundOrder['refund_amount'], 'currency' => 'CNY', ] ]); $result = $response->toArray(false); $this->checkResultFail($result); return $result; } /** * @notes 查询退款 * @param $refundSn * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @author 段誉 * @date 2023/3/1 11:16 */ public function queryRefund($refundSn) { $response = $this->app->getClient()->get("v3/refund/domestic/refunds/{$refundSn}"); return $response->toArray(false); } /** * @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::info(['支付回调信息', $message]); if ($message['trade_state'] === 'SUCCESS') { $this->handlePaid($message); } else { Log::info('支付失败', $message); } return true; }); return $server->serve(); } /** * @return void * 修改支付状态,回写回调信息。 * 通知业务系统 */ public function handlePaid($message) { try { $transaction_id = $message['transaction_id']; $out_trade_no = $message['out_trade_no']; $order = PayOrder::where('order_no', $out_trade_no)->find(); if (empty($order)) { throw new Exception('回调订单不存在'); } $order->transaction_id = $transaction_id; $order->pay_status = PayOrderEnum::PAY_STATUS_ISPAID; $order->finish_time = time(); $order->save(); // 回调业务系统 PaymentLogic::callBusiness($order['business_callback_url'], ['out_trade_no'=>$order['business_order_no'], 'transaction_id'=>$transaction_id, 'pay_status'=>1]); } catch (\Exception $e) { Log::error(['支付回调信息处理失败', $e->getMessage(),$message]); return; } } public function refundNotify() { $server = $this->app->getServer(); // 退款通知 $server->handleRefunded(function (Message $message) { Log::info(['退款回调信息', $message]); return true; }); return $server->serve(); } }