extensionPaymentEntity->where([ 'order_id' => $order['id'], 'pay_type' => Extension::EXTENSION_ID, 'biz_type' => $bizType, ])->findOrEmpty(); if (!$payment->isEmpty()) { // todo 判断订单是否支付成功 // 支付时间结束关闭订单 // 订单未支付可重新支付 // 交易已关闭请重新下单 //订单已付款请勿重复操作 // 订单已退款请重新下单 //订单已撤销请重新下单 // 订单支付中请稍后再试 // 订单支付失败请重新下单 throw new \RuntimeException('开发测试中,请稍后再试'); } $payment->transaction(function () use ($bizType, $order, $payment) { $randomDiscount = mt_rand(0, intval($this->config->random_discount_max * 100)) / 100; $order['pay_amount'] = $order['pay_amount'] - $randomDiscount; $order['pay_amount'] = max(0.01, round($order['pay_amount'], 2)); $payment->save([ 'user_id' => $order['user_id'], 'order_id' => $order['id'], 'order_sn' => $order['order_sn'], 'biz_type' => $bizType, 'pay_type' => Extension::EXTENSION_ID, 'amount' => $order['pay_amount'], 'status' => PaymentStatusEnum::PENDING ]); $expireDuration = 15; // 分钟 $payment->expire_time = time() + $expireDuration * 60; $payment->payment_param = $this->createPaymentParam($order, $payment, $expireDuration); $payment->transaction_id = $payment->payment_param->trade_no; $payment->save(); }); return new PaymentResponse(orderNo: $payment->out_trade_no, type: Extension::EXTENSION_ID, raw: $payment->toArray()); } #[\Override] public function notify(array $request): PaymentNotifyResult { throw new \Exception('Not implemented'); } #[\Override] public function query(int $recordID): PaymentQueryResult { $payment = $this->extensionPaymentEntity->read($recordID); if ($payment->status === PaymentStatusEnum::PENDING) { $response = TransactionService::queryTrade($payment->transaction_id); // INIT-初始化 CREATE-下单成功 SUCCESS-交易成功 FAIL-交易失败 DEAL-交易处理中 UNKNOWN-未知状态 CLOSE-订单关闭 PART_REFUND-部分退款 REFUND-全部退款(或订单被撤销) $payment->status = match ($response->trade_state) { 'DEAL' => PaymentStatusEnum::PENDING, 'SUCCESS' => PaymentStatusEnum::SUCCESS, 'FAIL' => PaymentStatusEnum::FAIL, 'CLOSE' => PaymentStatusEnum::CLOSED, default => PaymentStatusEnum::PENDING, }; if ($payment->status !== PaymentStatusEnum::PENDING) { $payment->status_desc = $response->trade_state_desc; $payment->payment_result = $response; if ($payment->status === PaymentStatusEnum::SUCCESS) { $payment->payment_time = time(); $payment->save(); Event::trigger(new PaymentSuccessEvent($payment['order_sn'], Extension::EXTENSION_ID, $payment->toArray(), $payment->biz_type)); } else { $payment->save(); } } } return new PaymentQueryResult( orderNo: $payment['out_trade_no'], status: $payment['status'], amount: (float)$payment['amount'], raw: $payment->toArray() ); } #[\Override] public function refund(int $recordID, PaymentRefundRequest $param): PaymentRefundResult { throw new \Exception('Not implemented'); } #[\Override] public function refundQuery(int $refundID): PaymentRefundResult { throw new \Exception('Not implemented'); } private function createPaymentParam(array $order, ExtensionPaymentEntity $payment, int $expireDuration): object { $accBusiFields = new TradePreorderWechaAccBusiFields(); $accBusiFields->setTimeoutExpress($expireDuration); $accBusiFields->setSubAppid($this->config->sub_appid); $accBusiFields->setUserId($order['params']['openid']); /*$detail = new TradePreorderWechaDetail(); $detail->setCostPrice((float)$order['pay_amount']); $detail->setReceiptId(''); $goodsDetailList = []; foreach ($order['order_goods'] as $goods) { $goodsDetail = new TradePreorderWechaGoodsDetail(); $goodsDetail->setGoodsId((string)$goods['goods_id']); $goodsDetail->setQuantity($goods['num']); $goodsDetail->setWxpayGoodsId(''); $goodsDetail->setPrice(round($goods['price']*100, 0)); $goodsDetail->setGoodsName($goods['goods_name']); $goodsDetailList[] = $goodsDetail; } $detail->setGoodsDetail($goodsDetailList); $accBusiFields->setDetail($detail);*/ return TransactionService::preOrder( outTradeNo: $payment['out_trade_no'], totalAmount: $payment['amount'], locationInfo: new LocationInfo(requestIP: $order['params']['ip']), subject: '订单:' . $order['order_sn'], settleType: '1', // 拉卡拉分账 remark: $order['description'], accBusiFields: $accBusiFields, ); } }