extensionPaymentEntity->where([ 'order_id' => $order['id'], 'pay_type' => self::PAYMENT_TYPE, 'biz_type' => $bizType, ])->findOrEmpty(); if (!$payment->isEmpty()) { // todo 判断订单是否支付成功 // 支付时间结束关闭订单 // 订单未支付可重新支付 // 交易已关闭请重新下单 //订单已付款请勿重复操作 // 订单已退款请重新下单 //订单已撤销请重新下单 // 订单支付中请稍后再试 // 订单支付失败请重新下单 throw new \RuntimeException('开发测试中,请稍后再试'); } $payment->transaction(function () use ($bizType, $order, $payment) { $payment->save([ 'user_id' => $order['user_id'], 'order_id' => $order['id'], 'order_sn' => $order['order_sn'], 'biz_type' => $bizType, 'pay_type' => self::PAYMENT_TYPE, 'amount' => $order['pay_amount'], 'status' => PaymentStatusEnum::PENDING ]); $expireTime = time() + 3600; $payment->expire_time = $expireTime; $openid = WechatUser::openid($order['user_id']); if ($openid === null) { Helper::throw_logic_exception('用户需要先使用微信登录绑定微信身份'); } $payment->payment_param = $this->wechatPay( openid: $openid, outTradeNo: $payment['out_trade_no'], total: (int)($payment['amount'] * 100), description: '订单:' . $order['order_sn'], expireTime: $expireTime ); $payment->payment_param = $this->paymentParams($payment->payment_param->prepay_id); $payment->save(); }); return new PaymentResponse(orderNo: $payment->out_trade_no, type: self::PAYMENT_TYPE, raw: $payment->toArray()); } public function notify(array $request): PaymentNotifyResult { throw new \Exception('Not implemented'); } public function query(int $recordID): PaymentQueryResult { $payment = $this->extensionPaymentEntity->findOrEmpty($recordID); if ($payment->status === PaymentStatusEnum::PENDING) { try { $paymentResult = $this->queryByOutTradeNo($payment['out_trade_no']); } catch (ClientException $e) { if ($e->getCode() === 404) { throw new NotFoundException(sprintf('订单%s不存在', $payment['out_trade_no'])); } throw $e; } $payment->payment_result = $paymentResult; if ($paymentResult->trade_state === 'SUCCESS') { $payment->transaction_id = $paymentResult->transaction_id; $payment->status = PaymentStatusEnum::SUCCESS; $payment->save(); Event::trigger(new PaymentSuccessEvent($payment['order_sn'], self::PAYMENT_TYPE, $payment->toArray(), $payment->biz_type)); } else { throw_logic_exception($paymentResult->trade_state_desc); } } return new PaymentQueryResult( orderNo: $payment['out_trade_no'], status: $payment['status'], amount: (float)$payment['amount'], raw: $payment->toArray() ); } public function refund(int $recordID, PaymentRefundRequest $param): PaymentRefundResult { $payment = $this->extensionPaymentEntity->find($recordID); $reund = Db::transaction(function () use ($param, $payment) { $reund = $this->extensionRefundEntity->create([ 'payment_id' => $payment->id, 'order_sn' => $payment->out_trade_no, 'reason' => $param->getReason(), 'amount' => $param->getAmount(), 'status' => RefundStatusEnum::REFUNDING, 'refund_param' => $param->getRaw(), 'status_desc' => '正在申请微信接口退款', ]); $this->domesticRefunds( $reund->out_refund_no, $payment->out_trade_no, $param->getAmount(), $payment->amount, $param->getReason() ); return $reund; }); return new PaymentRefundResult($reund); } public function refundQuery(int $refundID): PaymentRefundResult { $refund = $this->extensionRefundEntity->with('payment')->find($refundID); if ($refund->status === RefundStatusEnum::REFUNDING) { $result = $this->queryRefund($refund->out_refund_no); $refund->refund_id = $result->refund_id; $refund->refund_result = $result; if ($result->status === 'SUCCESS') { $refund->status = RefunddStatusEnum::SUCCESS; $refund->success_time = strtotime($result->success_time); Event::trigger(new RefundSuccessEvent( $refund->model(), $refund->payment, new PaymentRefundRequest($refund->amount,$refund->reason, $refund->refund_param)) ); } $refund->save(); } return new PaymentRefundResult($refund->model()); } }