diff --git a/addons/shopro/controller/Pay.php b/addons/shopro/controller/Pay.php new file mode 100644 index 0000000..e75e280 --- /dev/null +++ b/addons/shopro/controller/Pay.php @@ -0,0 +1,451 @@ +request->get('order_sn'); + + list($order, $prepay_type) = $this->getOrderInstance($order_sn); + $order = $order->where('order_sn', $order_sn)->find(); + + try { + if (!$order) { + throw new \Exception("订单不存在"); + } + if ($order->status > 0) { + throw new \Exception("订单已支付"); + } + if ($order->status < 0) { + throw new \Exception("订单已失效"); + } + + $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/alipay/platform/H5'; + $pay = new \addons\shopro\library\PayService('alipay', 'url', $notify_url); + + $order_data = [ + 'order_id' => $order->id, + 'out_trade_no' => $order->order_sn, + 'total_fee' => $order->total_fee, + 'subject' => '商城订单支付', + ]; + + $result = $pay->create($order_data); + + $result = $result->getContent(); + + echo $result; + } catch (\Exception $e) { + echo $e->getMessage(); + } + + // $this->assign('result', $result); + + // return $this->view->fetch(); + } + + /** + * 拉起支付 + */ + public function prepay() + { + checkEnv('yansongda'); + + $order_sn = $this->request->post('order_sn'); + $orderId = $this->request->post('order_id'); + $payment = $this->request->post('payment'); + $openid = $this->request->post('openid', ''); + $user = $this->auth->getUser(); + $platform = request()->header('platform'); + // 重新获取订单号 + if (strpos($order_sn, 'TO') !== 0) { + $order_sn = Db::name('shopro_order') + ->where(['id' => $orderId]) + ->value('order_sn'); + } + + list($order, $prepay_type) = $this->getOrderInstance($order_sn); + $order = $order->nopay()->where('order_sn', $order_sn)->find(); + + if (!$order) { + $this->error("订单不存在"); + } + + if (!$payment || !in_array($payment, ['wechat', 'alipay', 'wallet', 'group'])) { + $this->error("支付类型不能为空"); + } + + if ($payment == 'wallet' && $prepay_type == 'order') { + // 余额支付 + $this->walletPay($order, $payment, $platform); + } + + $order_data = [ + 'order_id' => $order->id, + 'out_trade_no' => $order->order_sn, + 'total_fee' => $order->total_fee, + ]; + + if (strpos($order_sn, 'TO') !== 0) { + // 保持 order_sn 不变,避免支付回调时找不到订单 + if ($payment == 'group') { + $payment = 'wechat'; + // 重新计算价格 + $order_data['total_fee'] = bcsub($order_data['total_fee'], $user->money, 2); + // 更新组合付款余额 + Db::name('shopro_order')->update([ + 'id' => $order->id, + 'pay_type' => 'group', + 'pay_money' => $user->money + ]); + } else { + Db::name('shopro_order')->update([ + 'id' => $order->id, + 'pay_type' => $payment, + 'pay_money' => 0 + ]); + } + } + + // 微信公众号,小程序支付,必须有 openid + if ($payment == 'wechat') { + if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) { + if (isset($openid) && $openid) { + // 如果传的有 openid + $order_data['openid'] = $openid; + } else { + // 没有 openid 默认拿下单人的 openid + $oauth = \addons\shopro\model\UserOauth::where([ + 'user_id' => $order->user_id, + 'provider' => 'Wechat', + 'platform' => $platform + ])->find(); + + $order_data['openid'] = $oauth ? $oauth->openid : ''; + } + + if (empty($order_data['openid'])) { + // 缺少 openid + return $this->success('缺少 openid', 'no_openid'); + } + } + + $order_data['body'] = '商城订单支付'; + } else { + $order_data['subject'] = '商城订单支付'; + } + + $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/' . $payment . '/platform/' . $platform; + $pay = new \addons\shopro\library\PayService($payment, $platform, $notify_url); + + try { + $result = $pay->create($order_data); + } catch (\Yansongda\Pay\Exceptions\Exception $e) { + $this->error("支付配置错误:" . $e->getMessage()); + } + + if ($platform == 'App') { + // $result = json_decode($result->getContent(), true); + $result = $result->getContent(); + } + if ($platform == 'H5' && $payment == 'wechat') { + $result = $result->getContent(); + } + + return $this->success('获取预付款成功', [ + 'pay_data' => $result, + 'pay_action' => $pay->method, + ]); + } + + // 余额支付 + public function walletPay($order, $type, $method) + { + $order = Db::transaction(function () use ($order, $type, $method) { + // 重新加锁读,防止连点问题 + $order = Order::nopay()->where('order_sn', $order->order_sn)->lock(true)->find(); + if (!$order) { + $this->error("订单已支付"); + } + $total_fee = $order->total_fee; + + // 扣除余额 + $user = User::info(); + + if (is_null($user)) { + // 没有登录,请登录 + $this->error(__('Please login first'), null, 401); + } + + User::money(-$total_fee, $user->id, 'wallet_pay', $order->id, '', [ + 'order_id' => $order->id, + 'order_sn' => $order->order_sn, + ]); + + // 支付后流程 + $notify = [ + 'order_sn' => $order['order_sn'], + 'transaction_id' => '', + 'notify_time' => date('Y-m-d H:i:s'), + 'buyer_email' => $user->id, + 'pay_fee' => $order->total_fee, + 'pay_type' => 'wallet' // 支付方式 + ]; + $notify['payment_json'] = json_encode($notify); + $order->paymentProcess($order, $notify); + + return $order; + }); + + $this->success('支付成功', $order); + } + + /** + * 支付成功回调 + */ + public function notifyx() + { + Log::write('notifyx-comein:'); + + $payment = $this->request->param('payment'); + $platform = $this->request->param('platform'); + + $pay = new \addons\shopro\library\PayService($payment, $platform); + + $result = $pay->notify(function ($data, $pay) use ($payment, $platform) { + Log::write('notifyx-result:' . json_encode($data)); + // { // 微信回调参数 + // "appid":"wx39cd0799d4567dd0", + // "bank_type":"OTHERS", + // "cash_fee":"1", + // "fee_type":"CNY", + // "is_subscribe":"N", + // "mch_id":"1481069012", + // "nonce_str":"dPpcZ6AzCDU8daNC", + // "openid":"oD9ko4x7QMDQPZEuN8V5jtZjie3g", + // "out_trade_no":"202010240834057843002700", + // "result_code":"SUCCESS", + // "return_code":"SUCCESS", + // "sign":"3103B6D06F13D2B3959C5B3F7F1FD61C", + // "time_end":"20200407102424", + // "total_fee":"1", + // "trade_type":"JSAPI", + // "transaction_id":"4200000479202004070804485027" + // } + + // { // 支付宝支付成功回调参数 + // "gmt_create":"2020-04-10 19:15:00", + // "charset":"utf-8", + // "seller_email":"xptech@qq.com", + // "subject":"\u5546\u57ce\u8ba2\u5355\u652f\u4ed8", + // "sign":"AOiYZ1a2mEMOuIbHFCi6V6A0LJ97UMiHsCWgNdSU9dlzKFl15Ts8b0mL\/tN+Hhskl+94S3OUiNTBD3dD0Kv923SqaTWxNdj533PCdo2GDKsZIZgKbavnOvaccSKUdmQRE9KtmePPq9V9lFzEQvdUkKq1M8KAWO5K9LTy2iT2y5CUynpiu\/04GVzsTL9PqY+LDwqj6K+w7MgceWm1BWaFWg27AXIRw7wvsFckr3k9GGajgE2fufhoCYGYtGFbhGOp6ExtqS5RXBuPODOyRhBLpD8mwpOX38Oy0X+R4YQIrOi02dhqwPpvw79YjnvgXY3qZEQ66EdUsrT7EBdcPHK0Gw==", + // "buyer_id":"2088902485164146", + // "invoice_amount":"0.01", + // "notify_id":"2020041000222191501064141414240102", + // "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]", + // "notify_type":"trade_status_sync", + // "trade_status":"TRADE_SUCCESS", + // "receipt_amount":"0.01", + // "buyer_pay_amount":"0.01", + // "app_id":"2021001114666742", + // "sign_type":"RSA2", + // "seller_id":"2088721922277739", + // "gmt_payment":"2020-04-10 19:15:00", + // "notify_time":"2020-04-10 19:15:01", + // "version":"1.0", + // "out_trade_no":"202007144778322770017000", + // "total_amount":"0.01", + // "trade_no":"2020041022001464141443020240", + // "auth_app_id":"2021001114666742", + // "buyer_logon_id":"157***@163.com", + // "point_amount":"0.00" + // } + + // { // 支付宝退款成功(交易关闭)回调参数 + // "gmt_create": "2020-08-15 14:48:32", + // "charset": "utf-8", + // "seller_email": "xptech@qq.com", + // "gmt_payment": "2020-08-15 14:48:32", + // "notify_time": "2020-08-15 16:11:45", + // "subject": "商城订单支付", + // "gmt_refund": "2020-08-15 16:11:45.140", + // "sign": "b6ArkgzLIRteRL9FMGC6i\/jf6VwFYQbaGDGRx002W+pdmN5q9+O4edZ3ALF74fYaijSl9ksNr0dKdvanu3uYxBTcd\/GIS4N1CWzmCOv6pzgx5rO\/YvGoHLM3Yop0GKKuMxmnNsZ6jhYKEY7SYD3Y0L6PU9ZMdHV7yIiVj+zZmbKzUgK9MPDCEXs+nzpNAiSM8GTqYRSUvKobAK68hswG2k1QIcqr5z+ZmVYa\/nHHkoC9qXt5zwyGi4P+2eOsr6V2PjA3x8qqe7TN5aI1DeoZD5KqHPYYaYF17J2q6YPlgl3WUl1RhE7H86bivB1fIuYEv\/3+JR74WN\/o7krGw1RPHg==", + // "out_biz_no": "R202004114414846255015300", + // "buyer_id": "2088902485164146", + // "version": "1.0", + // "notify_id": "2020081500222161145064141453349793", + // "notify_type": "trade_status_sync", + // "out_trade_no": "202002460317545607015300", + // "total_amount": "0.01", + // "trade_status": "TRADE_CLOSED", + // "refund_fee": "0.01", + // "trade_no": "2020081522001464141438570535", + // "auth_app_id": "2021001114666742", + // "buyer_logon_id": "157***@163.com", + // "gmt_close": "2020-08-15 16:11:45", + // "app_id": "2021001114666742", + // "sign_type": "RSA2", + // "seller_id": "2088721922277739" + // } + + try { + $out_trade_no = $data['out_trade_no']; + $out_refund_no = $data['out_biz_no'] ?? ''; + + list($order, $prepay_type) = $this->getOrderInstance($out_trade_no); + + // 判断是否是支付宝退款(支付宝退款成功会通知该接口) + if ($payment == 'alipay' // 支付宝支付 + && $data['notify_type'] == 'trade_status_sync' // 同步交易状态 + && $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭 + && $out_refund_no // 退款单号 + ) { + // 退款回调 + if ($prepay_type == 'order') { + // 退款回调 + $this->refundFinish($out_trade_no, $out_refund_no); + } else { + // 其他订单如果支持退款,逻辑这里补充 + } + + return $pay->success()->send(); + } + + // 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应 + if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') { + // 不是交易成功的通知,直接返回成功 + return $pay->success()->send(); + } + if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) { + // 微信交易未成功,返回 false,让微信再次通知 + return false; + } + + // 支付成功流程 + $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100; + + // 你可以在此编写订单逻辑 + $order = $order->nopay()->where('order_sn', $out_trade_no)->lock(true)->find(); + + if (!$order) { + // 已支付则直接返回成功,否则记录日志并通知微信重试 + $paidOrder = Order::where('order_sn', $out_trade_no)->where('status', '>', 0)->find(); + if ($paidOrder) { + return $pay->success()->send(); + } + Log::write('notifyx-order-not-found:' . $out_trade_no); + return false; + } + + Db::transaction(function () use ($order, $data, $payment, $platform, $pay_fee, $prepay_type) { + $notify = [ + 'order_sn' => $data['out_trade_no'], + 'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'], + 'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])), + 'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'], + 'payment_json' => json_encode($data->all()), + 'pay_fee' => $pay_fee, + 'pay_type' => $order->pay_type == 'group' ? 'group' : $payment // 支付方式 + ]; + + $order->paymentProcess($order, $notify); + }); + + return $pay->success()->send(); + } catch (\Exception $e) { + Log::write('notifyx-error:' . $e->getMessage()); + return false; + } + }); + + return $result; + } + + /** + * 退款成功回调 + */ + public function notifyr() + { + Log::write('notifyreturn-comein:'); + + $payment = $this->request->param('payment'); + $platform = $this->request->param('platform'); + + $pay = new \addons\shopro\library\PayService($payment, $platform); + + $result = $pay->notifyRefund(function ($data, $pay) use ($payment, $platform) { + Log::write('notifyr-result:' . json_encode($data)); + try { + $out_refund_no = $data['out_refund_no']; + $out_trade_no = $data['out_trade_no']; + + // 退款 + $this->refundFinish($out_trade_no, $out_refund_no); + + return $pay->success()->send(); + } catch (\Exception $e) { + Log::write('notifyreturn-error:' . json_encode($e->getMessage())); + } + }); + + return $result; + } + + private function refundFinish($out_trade_no, $out_refund_no) + { + $order = Order::where('order_sn', $out_trade_no)->find(); + $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find(); + + if (!$order || !$refundLog || $refundLog->status != 0) { + // 订单不存在,或者订单已退款 + return true; + } + + $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find(); + + Db::transaction(function () use ($order, $item, $refundLog) { + \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog); + }); + + return true; + } + + /** + * 根据订单号获取订单实例 + * + * @param [type] $order_sn + * @return void + */ + private function getOrderInstance($order_sn) + { + $prepay_type = 'order'; + if (strpos($order_sn, 'TO') === 0) { + // 充值订单 + $prepay_type = 'recharge'; + $order = new TradeOrder(); + } else { + // 订单 + $order = new Order(); + } + + return [$order, $prepay_type]; + } +} diff --git a/addons/shopro/library/PayService.php b/addons/shopro/library/PayService.php new file mode 100644 index 0000000..f501410 --- /dev/null +++ b/addons/shopro/library/PayService.php @@ -0,0 +1,273 @@ +platform = $platform; + $this->payment = $payment; + $this->notify_url = $notify_url; + $this->type = $type; + + $this->setPaymentConfig(); + } + + private function setPaymentConfig() + { + if ($this->platform === 'App' && $this->payment != 'alipay') { + $paymentConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'wechat_app'])->value, true); + } else { + $paymentConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->payment])->value, true); + } + + // 如果是支付,并且不是 复制地址的支付宝支付 + if ($this->type == 'pay' && $this->platform != 'url' && !in_array($this->platform, $paymentConfig['platform'])) { + new Exception('暂不支持该方式付款'); + } + + $this->config = $paymentConfig; + $this->config['notify_url'] = $this->notify_url; + + if ($this->payment === 'wechat') { + // 根据不同平台设置相应的 appid + $this->setWechatAppId(); + } + + // 设置支付证书路径 + $this->setCert(); + } + + private function setWechatAppId() + { + switch ($this->platform) { + case 'wxOfficialAccount': + $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true); + if (isset($this->config['mode']) && $this->config['mode'] === 'service') { + $this->config['sub_app_id'] = $platformConfig['app_id']; + } else { + $this->config['app_id'] = $platformConfig['app_id']; + } + break; + case 'wxMiniProgram': + $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true); + if (isset($this->config['mode']) && $this->config['mode'] === 'service') { + $this->config['sub_miniapp_id'] = $platformConfig['app_id']; + // $this->config['sub_app_id'] = $platformConfig['app_id']; + } else { + $this->config['miniapp_id'] = $platformConfig['app_id']; + $this->config['app_id'] = $platformConfig['app_id']; // 小程序微信企业付款 + } + break; + case 'H5': + $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true); + if (isset($this->config['mode']) && $this->config['mode'] === 'service') { + $this->config['sub_app_id'] = $platformConfig['app_id']; + } else { + $this->config['app_id'] = $platformConfig['app_id']; + } + break; + case 'App': + $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'App'])->value, true); + if (isset($this->config['mode']) && $this->config['mode'] === 'service') { + $this->config['sub_appid'] = $platformConfig['app_id']; + $this->config['sub_app_id'] = $platformConfig['app_id']; + } else { + $this->config['appid'] = $platformConfig['app_id']; // 微信 App 支付使用这个 + $this->config['app_id'] = $platformConfig['app_id']; // 微信 App 支付退款使用的是这个 + } + + break; + } + } + + // 处理证书路径 + private function setCert() + { + // 处理证书路径 + if ($this->payment == 'wechat') { + // 微信支付证书 + $this->config['cert_client'] = ROOT_PATH . 'public' . $this->config['cert_client']; + $this->config['cert_key'] = ROOT_PATH . 'public' . $this->config['cert_key']; + } else { + // 支付宝证书路径 + $end = substr($this->config['ali_public_key'], -4); + if ($end == '.crt') { + $this->config['ali_public_key'] = ROOT_PATH . 'public' . $this->config['ali_public_key']; + } + $this->config['app_cert_public_key'] = ROOT_PATH . 'public' . $this->config['app_cert_public_key']; + $this->config['alipay_root_cert'] = ROOT_PATH . 'public' . $this->config['alipay_root_cert']; + } + } + + + private function setPaymentMethod() + { + $method = [ + 'wechat' => [ + 'wxOfficialAccount' => 'mp', //公众号支付 Collection + 'wxMiniProgram' => 'miniapp', //小程序支付 + 'H5' => 'wap', //手机网站支付 Response + 'App' => 'app' //APP 支付 JsonResponse + ], + 'alipay' => [ + 'wxOfficialAccount' => 'wap', //手机网站支付 Response + 'wxMiniProgram' => 'wap', //小程序支付 + 'H5' => 'wap', //手机网站支付 Response + 'url' => 'wap', //手机网站支付 Response + 'App' => 'app' //APP 支付 JsonResponse + ], + ]; + + $this->method = $method[$this->payment][$this->platform]; + } + + public function create($order) + { + // $order = [ + // 'out_trade_no' => time(), + // 'total_fee' => '1', // **单位:分** + // 'body' => 'test body - 测试', + // 'openid' => 'onkVf1FjWS5SBIixxxxxxx', //微信需要带openid过来 + // ]; + // 设置支付方式 + $this->setPaymentMethod(); + + $method = $this->method; + + switch ($this->payment) { + case 'wechat': + if (isset($this->config['mode']) && $this->config['mode'] === 'service') { + $order['sub_openid'] = $order['openid']; + unset($order['openid']); + } + + $order['total_fee'] = $order['total_fee'] * 100; + $pay = Pay::wechat($this->config)->$method($order); + break; + case 'alipay': + if (in_array($this->platform, ['wxOfficialAccount', 'wxMiniProgram', 'H5'])) { + // 返回支付宝支付链接 + $pay = request()->domain() . '/addons/shopro/pay/alipay?order_sn=' . $order['out_trade_no']; + } else { + if ($this->method == 'wap') { + // 支付宝 wap 支付,增加 return_url + // 获取 h5 域名 + $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'shopro'])->value, true); + // 如果域名存在,增加 return_url + if ($platformConfig && isset($platformConfig['domain'])) { + $start = substr($platformConfig['domain'], -1) == '/' ? "" : "/"; + $orderType = strpos($order['out_trade_no'], 'TO') === 0 ? 'recharge' : 'goods'; + $this->config['return_url'] = $platformConfig['domain'] . $start . "pages/order/payment/result?orderId=" . $order['order_id'] . "&type=alipay&payState=success&orderType=" . $orderType; + } + } + + $pay = Pay::alipay($this->config)->$method($order); + } + + break; + } + return $pay; + } + + // 企业付款 + public function transfer($payload) + { + $code = 0; + $response = []; + switch ($this->payment) { + case 'wechat': + $payload['amount'] = $payload['amount'] * 100; + $response = Pay::wechat($this->config)->transfer($payload); + if ($response['return_code'] === 'SUCCESS' && $response['result_code'] === 'SUCCESS') { + $code = 1; + } + break; + case 'alipay': + $response = Pay::alipay($this->config)->transfer($payload); + if ($response['code'] === '10000' && $response['status'] === 'SUCCESS') { + $code = 1; + } + break; + } + + return [$code, $response]; + } + + + public function notify($callback) + { + $pay = $this->getPay(); + + try { + $data = $pay->verify(); // 是的,验签就这么简单! + + $result = $callback($data, $pay); + + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + \think\Log::error('notify-error:' . $e->getMessage()); + return false; + } + + return $result; + } + + + public function refund($order_data) + { + $pay = $this->getPay(); + + $order_data['type'] = $this->platform == 'wxMiniProgram' ? 'miniapp' : ''; + + $result = $pay->refund($order_data); + + return $result; + } + + + public function notifyRefund($callback) + { + $pay = $this->getPay(); + + try { + $data = $pay->verify(null, true); // 是的,验签就这么简单! + + $result = $callback($data, $pay); + + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + // $e->getMessage(); + } + + return $result; + } + + + private function getPay() + { + switch ($this->payment) { + case 'wechat': + $pay = Pay::wechat($this->config); + break; + case 'alipay': + $pay = Pay::alipay($this->config); + break; + default: + new Exception('支付方式不支持'); + } + + return $pay; + } +} diff --git a/addons/shopro/library/traits/model/order/OrderOper.php b/addons/shopro/library/traits/model/order/OrderOper.php new file mode 100644 index 0000000..3c770bf --- /dev/null +++ b/addons/shopro/library/traits/model/order/OrderOper.php @@ -0,0 +1,977 @@ +where(['type' => 'express']) + ->field(['id', 'name', 'type_ids']) + ->select(); + if (!empty($expressList) && !empty($dispatchData)) { + foreach ($expressList as &$v) { + if ($v['id'] === $dispatchData['dispatch_id']) { + $v['active'] = 1; + $expressName = $v['name']; + } else { + $v['active'] = 0; + } + } + } + + // 处理返回结果 + return self::preReturnParams( + $goods_original_amount, + $goods_amount, + $origin_dispatch_amount, + $dispatch_amount, + $total_amount, + $total_fee, + $discount_fee, + $coupon_fee, + $activity_discount_money, + $dispatch_discount_money, + $activity_type, + $score_amount, + $new_goods_list, + $need_address, + $activity_discount_infos, + $user_coupons, + $user_address, + $invoice_amount, + $deliveryFee, + $expressList, + $expressName + ); + } + + // 获取可用优惠券列表 + public static function coupons($params, $goods_amount = 0) + { + $user = User::info(); + extract($params); + $order_type = $order_type ?? 'goods'; + $groupon_id = $groupon_id ?? 0; // 拼团的 团 id + $buy_type = $buy_type ?? 'alone'; // 拼团的 购买方式: alone=单独购买,groupon=开团 + + // 商品总金额 + if (!$goods_amount) { + // 下单的时候把计算好的 goods_amount 传进来了,接口直接获取可用列表的时候,需要计算 + foreach ($goods_list as $k => $goods) { + $goods_amount += ($goods['goods_price'] * $goods['goods_num']); + } + } + + $coupons = Coupons::getCouponsList(Coupons::COUPONS_CAN_USE); + + $new_coupons = []; + // 过滤,如果有一个产品不适用,则优惠券不允许使用,不显示 + foreach ($coupons as $key => $coupon) { + if ($coupon['goods_ids'] === '0') { + // 所有商品可用 + $can_use = true; + } else { + $goods_ids = explode(',', $coupon['goods_ids']); + + $can_use = true; + foreach ($goods_list as $k => $goods) { + if (!in_array($goods['goods_id'], $goods_ids)) { + $can_use = false; + break; + } + } + } + + // 商品可用 并且 商品金额满足 + if ($can_use && $coupon->enough <= $goods_amount) { + $new_coupons[] = $coupon; + } + } + + $new_coupons = array_values($new_coupons); + + return $new_coupons; + } + + public static function createOrder($params) + { + $user = User::info(); + + // 入参 + extract($params); + $remark = $remark ?? null; + $order_type = $order_type ?? 'goods'; + $groupon_id = $groupon_id ?? 0; // 拼团的 团 id + $buy_type = $buy_type ?? 'alone'; // 拼团的 购买方式: alone=单独购买,groupon=开团 + $invoice = $invoice ?? null; // 发票申请 + + // 订单计算数据 + extract(self::pre($params, "create")); + + $order = Db::transaction(function () use ( + $user, + $order_type, + $groupon_id, + $buy_type, + $goods_original_amount, + $goods_amount, + $dispatch_amount, + $total_amount, + $score_amount, + $total_fee, + $discount_fee, + $coupon_fee, + $activity_discount_money, + $dispatch_discount_money, + $activity_discount_infos, + $new_goods_list, + $activity_type, + $user_coupons, + $user_address, + $remark, + $from, + $invoice, + $invoice_amount, + $deliveryFee, + $expressName + ) { + // 订单创建前 + $data = [ + 'user' => $user, + 'order_type' => $order_type, + 'groupon_id' => $groupon_id, + 'buy_type' => $buy_type, + 'goods_original_amount' => $goods_original_amount, + 'goods_amount' => $goods_amount, + 'dispatch_amount' => $dispatch_amount, + 'total_amount' => $total_amount, + 'score_amount' => $score_amount, + 'total_fee' => $total_fee, + 'discount_fee' => $discount_fee, + 'coupon_fee' => $coupon_fee, + 'activity_discount_money' => $activity_discount_money, + 'dispatch_discount_money' => $dispatch_discount_money, + 'activity_discount_infos' => $activity_discount_infos, + 'new_goods_list' => $new_goods_list, + 'activity_type' => $activity_type, + 'user_coupons' => $user_coupons, + 'user_address' => $user_address, + 'remark' => $remark, + 'from' => $from + ]; + + // 如果是抢购需看是否有名额才能下单 + $activityId = 0; + if ($activity_type === 'robbuy') { + $activityId = $new_goods_list[0]['detail']['activity']['id']; + $id = RobOrderModel::where([ + 'user_id' => $user->id, + 'activity_id' => $activityId, + 'goods_id' => $new_goods_list[0]['detail']['id'], + 'is_rob' => 1 + ])->value('id'); + + if (empty($id)) { + return [ + 'create_result' => 401, + 'msg' => '你未获得抢购资格暂无法购买' + ]; + } + } + + // 如果是活动,这里面减掉 redis 库存 + \think\Hook::listen('order_create_before', $data); + + // 团信息, 如果是参与旧团拼团才会不为 null,(开新团放到支付成功) + $groupon = cache('grouponinfo-' . $user->id); + $groupon = $groupon ? json_decode($groupon, true) : null; + // 立即清除缓存 + cache('grouponinfo-' . $user->id, NULL); + + $orderData = []; + $orderData['order_sn'] = self::getSn($user->id); + $orderData['user_id'] = $user->id; + $orderData['type'] = $order_type; + $orderData['activity_type'] = $activity_type; + $orderData['goods_amount'] = $goods_amount; + $orderData['dispatch_amount'] = $dispatch_amount; + $orderData['store_delivery_fee'] = $deliveryFee; + $orderData['total_amount'] = $total_amount; + $orderData['pay_fee'] = $total_amount; + $orderData['score_amount'] = $score_amount; + $orderData['total_fee'] = $total_fee; + $orderData['discount_fee'] = $discount_fee; + $orderData['score_fee'] = $score_amount; // 记录score 支付数 + $orderData['coupon_fee'] = $coupon_fee; + $orderData['activity_discount_money'] = $activity_discount_money; + $orderData['dispatch_discount_money'] = $dispatch_discount_money; + $orderData['goods_original_amount'] = $goods_original_amount; + $orderData['last_total_fee'] = 0; + $orderData['activity_id'] = $activityId; + $orderData['express_name'] = $expressName; + + if ($user_address) { + $orderData['phone'] = $user_address->phone; + $orderData['consignee'] = $user_address->consignee; + $orderData['province_name'] = $user_address->province_name; + $orderData['city_name'] = $user_address->city_name; + $orderData['area_name'] = $user_address->area_name; + $orderData['address'] = $user_address->address; + $orderData['province_id'] = $user_address->province_id; + $orderData['city_id'] = $user_address->city_id; + $orderData['area_id'] = $user_address->area_id; + } + + // 处理发票申请 + if ($invoice_amount > 0) { + if (!empty($invoice) && $invoice['amount'] == $invoice_amount) { + $orderData['invoice_status'] = 1; // 已申请 + } else { + $orderData['invoice_status'] = 0; // 未申请 + } + } else { + $orderData['invoice_status'] = -1; // 不可开具发票 + + } + $orderData['status'] = 0; + $orderData['remark'] = $remark; + $orderData['coupons_id'] = $user_coupons ? $user_coupons->id : 0; + $orderData['platform'] = request()->header('platform'); + + $ext = $activity_discount_infos ? ['activity_discount_infos' => $activity_discount_infos] : []; // 促销活动信息 + $orderData['ext'] = json_encode($ext); + $order = new Order(); + $order->allowField(true)->save($orderData); + + // 将优惠券使用掉 + if ($user_coupons) { + $user_coupons->use_order_id = $order->id; + $user_coupons->usetime = time(); + $user_coupons->save(); + } + + // 如果需要支付积分,扣除积分 + if ($score_amount) { + // $user 为 Common\Auth 对象 + User::score(-$score_amount, $user->id, 'score_pay', $order->id, '', [ + 'order_id' => $order->id, + 'order_sn' => $order->order_sn, + ]); + } + + // 添加发票数据 + if ($order->invoice_status == 1) { + \addons\shopro\model\OrderInvoice::create([ + 'order_id' => $order->id, + 'user_id' => $order->user_id, + 'amount' => $invoice['amount'], + 'type' => $invoice['type'], + 'header_name' => $invoice['header_name'], + 'tax_no' => $invoice['tax_no'], + 'mobile' => $invoice['mobile'], + ]); + } + + // 添加 订单 item + foreach ($new_goods_list as $key => $buyinfo) { + $detail = $buyinfo['detail']; + $current_sku_price = $detail['current_sku_price']; + + $orderItem = new OrderItem(); + + $orderItem->user_id = $user->id; + $orderItem->order_id = $order->id; + $orderItem->goods_id = $buyinfo['goods_id']; + $orderItem->goods_type = $detail['type']; + $orderItem->goods_sku_price_id = $buyinfo['sku_price_id']; + + $item_activity_type = (isset($current_sku_price['activity_type']) && $current_sku_price['activity_type']) ? $current_sku_price['activity_type'] : ''; + $item_activity_type .= $buyinfo['activity_type'] ? ',' . $buyinfo['activity_type'] : ''; + $item_activity_type = trim($item_activity_type, ','); + + $orderItem->activity_id = $current_sku_price['activity_id'] ?? 0; // 商品当前的活动类型 + $orderItem->activity_type = $item_activity_type ?: null; // 商品当前的活动类型 + // 当前商品规格对应的 活动下对应商品规格的 id + $orderItem->item_goods_sku_price_id = isset($current_sku_price['item_goods_sku_price']) ? + $current_sku_price['item_goods_sku_price']['id'] : 0; + $orderItem->goods_sku_text = $current_sku_price['goods_sku_text']; + $orderItem->goods_title = $detail->title; + $orderItem->goods_image = empty($current_sku_price['image']) ? $detail->image : $current_sku_price['image']; + $orderItem->goods_original_price = $detail->original_price; + $orderItem->discount_fee = $buyinfo['discount_fee']; // 平均计算单件商品所享受的折扣 + $orderItem->pay_price = $buyinfo['pay_price']; // 平均计算单件商品不算运费,算折扣时候的金额 + $orderItem->goods_price = $detail->current_sku_price->price; + $orderItem->goods_num = $buyinfo['goods_num'] ?? 1; + $orderItem->goods_weight = $detail->current_sku_price->weight; + $orderItem->dispatch_status = 0; + $orderItem->dispatch_fee = $buyinfo['dispatch_amount']; + $orderItem->dispatch_type = $buyinfo['dispatch_type']; + $orderItem->dispatch_id = $buyinfo['dispatch_id'] ? $buyinfo['dispatch_id'] : 0; + $orderItem->store_id = $buyinfo['store_id'] ? $buyinfo['store_id'] : 0; + $orderItem->aftersale_status = 0; + $orderItem->comment_status = 0; + $orderItem->refund_status = 0; + + $ext = []; + if (isset($buyinfo['dispatch_date'])) { + $ext['dispatch_date'] = $buyinfo['dispatch_date']; + } + if (isset($buyinfo['dispatch_phone'])) { + $ext['dispatch_phone'] = $buyinfo['dispatch_phone']; + } + $orderItem->ext = json_encode($ext); + $orderItem->save(); + } + + // 订单创建后 + $data = [ + 'user' => $user, + 'order' => $order, + 'from' => $from, + 'groupon' => $groupon, + 'buy_type' => $buy_type, + 'activity_type' => $activity_type, + 'new_goods_list' => $new_goods_list + ]; + \think\Hook::listen('order_create_after', $data); + + // 重新获取订单 + $order = self::where('id', $order['id'])->find(); + $order['create_result'] = 200; + + saveUserMessage([ + 'user_id' => $user->id, + 'content' => "您成功创建了订单:订单号:{$order->order_sn}", + 'create_time' => time() + ]); + + return $order; + }); + + return $order; + } + + // 订单列表 + public static function getList($params) + { + $user = User::info(); + extract($params); + + $order = (new self())->where('user_id', $user->id)->with('item'); + + switch ($type) { + case 'all': + $order = $order; + break; + case 'nopay': + $order = $order->nopay(); + break; + case 'nosend': + $order = $order->payed()->nosend(); + break; + case 'noget': + $order = $order->payed()->noget(); + break; + case 'nocomment': + $order = $order->payed()->nocomment(); + break; + case 'aftersale': + $order = $order->payed()->aftersale(); // 个人中心售后单不在走这里,而是直接走的售后单列表 + break; + } + + $orders = $order->order('id', 'desc')->paginate(10); + + // 处理未支付订单 item status_code + $orders = $orders->toArray(); + if ($orders['data']) { + $data = $orders['data']; + foreach ($data as $key => $od) { + $data[$key] = self::setOrderItemStatusByOrder($od); + } + + $orders['data'] = $data; + } + + return $orders; + } + + // 订单详情 + public static function detail($params) + { + $user = User::info(); + extract($params); + + $order = (new self())->with('item')->where('user_id', $user->id); + + if (isset($order_sn)) { + $order = $order->where('order_sn', $order_sn); + } + if (isset($id)) { + $order = $order->where('id', $id); + } + + $order = $order->find(); + + if (!$order) { + new Exception('订单不存在'); + } + + // 处理未支付订单 item status_code + $order = self::setOrderItemStatusByOrder($order); + + // 用户余额 + $order['user_money'] = $user->money; + // 手机号码 + $order['user_mobile'] = hideStr($user->mobile, 3, 6); + + // 组合付款金额 + $order['group_fee'] = bcsub($order['total_fee'], $user->money, 2); + + return $order; + } + + // 订单商品详情 + public static function itemDetail($params) + { + $user = User::info(); + extract($params); + $type = $type ?? 'default'; + + $order = (new self())->with(['item' => function ($query) use ($order_item_id) { + $query->where('id', $order_item_id); + }])->where('user_id', $user->id); + + if (isset($order_sn)) { + $order = $order->where('order_sn', $order_sn); + } + if (isset($id)) { + $order = $order->where('id', $id); + } + + $order = $order->find(); + + if (!$order || !$order->item) { + new Exception('订单不存在'); + } + + // 处理未支付订单 item status_code + $order = self::setOrderItemStatusByOrder($order); + $item = $order['item'][0]; + unset($order['item']); // 移除订单表中的 item + $item['order'] = $order; // 订单信息 + + if ($type == 'dispatch') { + $store = null; + $verifies = []; + if (in_array($item['dispatch_type'], ['selfetch', 'store']) && $item['store_id']) { + // 自提,商家配送 + + if ( + $item['dispatch_type'] == 'selfetch' + && $item['dispatch_status'] == OrderItem::DISPATCH_STATUS_SENDED + && $item['refund_status'] <= 0 + ) { + // 关联核销码 + $verifies = Verify::where('order_id', $item['order_id']) + ->where('order_item_id', $item['id'])->select(); + } + + $store = Store::where('id', $item['store_id'])->find(); + } + $item['store'] = $store; // 门店信息 + $item['verify'] = $verifies; // 核销券列表 + + // $item['autosend'] + // 订单详情,自动发货内容 待补充 + } + + return $item; + } + + // 取消订单 + public static function operCancel($params) + { + $user = User::info(); + extract($params); + + $order = self::with('item')->where('user_id', $user->id)->where('id', $id)->nopay()->find(); + + if (!$order) { + new Exception('订单不存在或已取消'); + } + + // 订单取消 + $order = (new self)->doCancel($order, $user); + + return $order; + } + + public function doCancel($order, $user, $type = 'user') + { + $order = Db::transaction(function () use ($order, $user, $type) { + $data = ['order' => $order]; + \think\Hook::listen('order_cancel_before', $data); + + $order->status = Order::STATUS_CANCEL; // 取消订单 + $order->ext = json_encode($order->setExt($order, ['cancel_time' => time()])); // 取消时间 + $order->save(); + + OrderAction::operAdd($order, null, $user, $type, ($type == 'user' ? '用户' : '管理员') . '取消订单'); + + // 订单取消,退回库存,退回优惠券积分,等 + $data = ['order' => $order]; + \think\Hook::listen('order_cancel_after', $data); + + return $order; + }); + + return $order; + } + + private static function getItem($order, $order_item_id) + { + if (!$order) { + new Exception('当前订单不存在'); + } + + $order_item = null; + foreach ($order->item as $item) { + if ($item->id == $order_item_id) { + $order_item = $item; + break; + } + } + + if (!$order_item) { + new Exception('订单商品不需要操作'); + } + + return $order_item; + } + + // 确认收货订单 + public static function operConfirm($params) + { + $user = User::info(); + extract($params); + + $order = Db::transaction(function () use ($id, $order_item_id, $user) { + // 加锁查询订单,exist 里面的子查询不会加锁,但是该语句需要等待锁释放才能正常查询,所以下面的获取 item 已经是更改过状态之后的了 + $order = self::noget()->where('user_id', $user->id)->where('id', $id)->lock(true)->find(); + + // 获取要操作的 订单 item + $item = self::getItem($order, $order_item_id); + if ($item->dispatch_status == OrderItem::DISPATCH_STATUS_NOSEND) { + new Exception('当前订单未发货'); + } + if ($item->dispatch_status == OrderItem::DISPATCH_STATUS_GETED) { + new Exception('当前订单已收货'); + } + + (new self())->getedItem($order, $item, ['oper_type' => 'user']); + }); + + return $order; + } + + // 删除订单 + public static function operDelete($params) + { + $user = User::info(); + extract($params); + + $order = self::canDelete()->where('user_id', $user->id)->where('id', $id)->find(); + + if (!$order) { + new Exception('订单不存在或不可删除'); + } + + $order = Db::transaction(function () use ($order, $user) { + $order->delete(); // 删除订单 + + OrderAction::operAdd($order, null, $user, 'user', '用户删除订单'); + + return $order; + }); + + return $order; + } + + // 评价 + public static function operComment($params) + { + $user = User::info(); + + $order = Db::transaction(function () use ($user, $params) { + extract($params); + + // 加锁读取订单,直到订单评价状态改变 + $order = self::with('item')->payed()->where('user_id', $user->id)->where('id', $id)->lock(true)->find(); + + // 获取要操作的 订单 item + $item = self::getItem($order, $order_item_id); + if ($item->comment_status == 1) { + new Exception('当前商品已评价'); + } + + // 订单评价前 + $data = ['order' => $order, 'item' => $item]; + \think\Hook::listen('order_comment_before', $data); // 重新拿到更新过的订单 + + $images = (isset($images) && $images) ? $images : null; + + // 获取用户评论配置 + $config = \addons\shopro\model\Config::where('name', 'order')->value('value'); + $config = json_decode($config, true); + + GoodsComment::create([ + 'goods_id' => $item->goods_id, + 'order_id' => $order->id, + 'order_item_id' => $item->id, + 'user_id' => $user->id, + 'level' => $level, + 'content' => $content, + 'images' => $images ? implode(',', $images) : $images, + 'status' => !empty($config['user_reply']) ? 'show' : 'hidden' + ]); + + $item->comment_status = OrderItem::COMMENT_STATUS_OK; // 评价成功 + $item->save(); + + OrderAction::operAdd($order, $item, $user, 'user', '用户评价成功'); + + // 订单评价后 + $data = ['order' => $order, 'item' => $item]; + \think\Hook::listen('order_comment_after', $data); + + return $order; + }); + + return $order; + } + + // 个人中心订单数量 + public static function statusNum() + { + $user = User::info(); + + $status_num['nopay'] = self::where('user_id', $user->id)->nopay()->count(); + $status_num['nosend'] = self::where('user_id', $user->id)->payed()->nosend()->count(); + $status_num['noget'] = self::where('user_id', $user->id)->payed()->noget()->count(); + $status_num['nocomment'] = self::where('user_id', $user->id)->payed()->nocomment()->count(); + // $status_num['aftersale'] = self::where('user_id', $user->id)->payed()->aftersale()->count(); + $status_num['aftersale'] = \addons\shopro\model\OrderAftersale::where('user_id', $user->id)->count(); + + return $status_num; + } + + public function paymentProcess($order, $notify) + { + $order->status = Order::STATUS_PAYED; + $order->paytime = time(); + $order->transaction_id = $notify['transaction_id']; + $order->payment_json = $notify['payment_json']; + $order->pay_type = $notify['pay_type']; + $order->pay_fee = $notify['pay_fee']; + + // 组合支付更新付款金额 + if ($order->pay_type == 'group') { + $order->total_fee = bcsub($order->total_fee, $order->pay_money, 2); + } + + $order->save(); + + saveUserMessage([ + 'user_id' => $order->user_id, + 'content' => "付款成功,订单号:{$order->order_sn}", + 'create_time' => time() + ]); + + $user = User::where('id', $order->user_id)->find(); + OrderAction::operAdd($order, null, $user, 'user', '用户支付成功'); + + // 组合支付扣除用户余额 + if ($order->pay_type == 'group') { + User::where(['id' => $user->id])->setDec('money', $order->pay_money); + } + + // 预约抢购标记成已使用 + if ($order->activity_type === 'robbuy') { + RobOrderModel::where([ + 'user_id' => $user->id, + 'activity_id' => $order->activity_id, + 'goods_id' => OrderItem::where(['order_id' => $order->id])->value('goods_id') + ])->update(['is_use' => 1]); + } + + // 支付成功后续使用异步队列处理 + \think\Queue::push('\addons\shopro\job\OrderPayed@payed', ['order' => $order, 'user' => $user], 'shopro-high'); + return $order; + } + + // 开始退款 + public static function startRefund($order, $item, $refund_money, $user = null, $remark = '') + { + // 订单退款前 + $data = ['order' => $order, 'item' => $item]; + \think\Hook::listen('order_refund_before', $data); + + $item->refund_status = \app\admin\model\shopro\order\OrderItem::REFUND_STATUS_OK; // 同意退款 + $item->refund_fee = bcadd($item->refund_fee, $refund_money, 2);; + $item->save(); + + \addons\shopro\model\OrderAction::operAdd($order, $item, $user, ($user ? 'admin' : 'system'), $remark . ',退款金额:' . $refund_money); + + \app\admin\model\shopro\order\Order::refund($order, $item, $refund_money, $remark); + + // 订单退款后 + $data = ['order' => $order, 'item' => $item]; + \think\Hook::listen('order_refund_after', $data); + } + + + // 退款 + public static function refund($order, $item, $refund_money, $remark = '') + { + // 生成退款单 + $refundLog = new RefundLog(); + $refundLog->order_sn = $order->order_sn; + $refundLog->refund_sn = RefundLog::getSn($order->user_id); + $refundLog->order_item_id = $item->id; + $refundLog->pay_fee = $order->pay_fee; + $refundLog->refund_fee = $refund_money; + $refundLog->pay_type = $order->pay_type; + $refundLog->save(); + + if ($order->pay_type == 'wechat' || $order->pay_type == 'alipay') { + // 微信|支付宝退款 + + // 退款数据 + $order_data = [ + 'out_trade_no' => $order->order_sn + ]; + + if ($order->pay_type == 'wechat') { + $total_fee = $order->pay_fee * 100; + $refund_fee = $refund_money * 100; + + $order_data = array_merge($order_data, [ + 'out_refund_no' => $refundLog->refund_sn, + 'total_fee' => $total_fee, + 'refund_fee' => $refund_fee, + 'refund_desc' => $remark, + ]); + } else { + $order_data = array_merge($order_data, [ + 'out_request_no' => $refundLog->refund_sn, + 'refund_amount' => $refund_money, + ]); + } + + $notify_url = request()->domain() . '/addons/shopro/pay/notifyr/payment/' . $order->pay_type . '/platform/' . $order->platform; + + $pay = new \addons\shopro\library\PayService($order->pay_type, $order->platform, $notify_url); + $result = $pay->refund($order_data); + + \think\Log::write('refund-result' . json_encode($result)); + + + if ($order->pay_type == 'wechat') { + // 微信通知回调 pay->notifyr + if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { + return true; + } else { + throw new \Exception($result['return_msg']); + } + } else { + // 支付宝通知回调 pay->notifyx + if ($result['code'] == "10000") { + return true; + } else { + throw new \Exception($result['msg']); + } + } + + // { // 微信返回结果 + // "return_code":"SUCCESS", + // "return_msg":"OK", + // "appid":"wx39cd0799d4567dd0", + // "mch_id":"1481069012", + // "nonce_str":"huW9eIAb5BDPn0Ma", + // "sign":"250316740B263FE53F5DFF50AF5A8FA1", + // "result_code":"SUCCESS", + // "transaction_id":"4200000497202004072822298902", + // "out_trade_no":"202010300857029180027000", + // "out_refund_no":"1586241595", + // "refund_id":"50300603862020040700031444448", + // "refund_channel":[], + // "refund_fee":"1", + // "coupon_refund_fee":"0", + // "total_fee":"1", + // "cash_fee":"1", + // "coupon_refund_count":"0", + // "cash_refund_fee":"1 + // } + + // { // 支付宝返回结果 + // "code": "10000", + // "msg": "Success", + // "buyer_logon_id": "157***@163.com", + // "buyer_user_id": "2088902485164146", + // "fund_change": "Y", + // "gmt_refund_pay": "2020-08-15 16:11:45", + // "out_trade_no": "202002460317545607015300", + // "refund_fee": "0.01", + // "send_back_fee": "0.00", + // "trade_no": "2020081522001464141438570535" + // } + } else if ($order->pay_type == 'wallet') { + // 余额退款 + if ($refund_money != 0) { + \addons\shopro\model\User::money($refund_money, $order->user_id, 'wallet_refund', $order->id, '', [ + 'order_id' => $order->id, + 'order_sn' => $order->order_sn, + 'item_id' => $item->id, + ]); + } + + self::refundFinish($order, $item, $refundLog); + + return true; + } else if ($order->pay_type == 'score') { + // 积分退款,暂不支持积分退款 + } + } + + public static function refundFinish($order, $item, $refundLog) + { + // 退款完成 + $refundLog->status = 1; + $refundLog->save(); + + // 退款完成 + $item->refund_status = \app\admin\model\shopro\order\OrderItem::REFUND_STATUS_FINISH; // 退款完成 + $item->save(); + \addons\shopro\model\OrderAction::operAdd($order, $item, null, 'admin', '退款成功'); + } + + + public function setExt($order, $field, $origin = []) + { + $newExt = array_merge($origin, $field); + + $orderExt = $order['ext_arr']; + + return array_merge($orderExt, $newExt); + } +} diff --git a/deploy/config.example.php b/deploy/config.example.php index aef88c8..eb26a6c 100644 --- a/deploy/config.example.php +++ b/deploy/config.example.php @@ -9,7 +9,7 @@ */ return [ // Gitea Web 钩子「密钥」 - 'webhook_secret' => 'sdsl23lsdsd2323aaaq#@$kks', + 'webhook_secret' => '请改为随机长字符串', // 站点根目录(含 .git 的项目目录,非 public) 'deploy_path' => '/www/wwwroot/chufang.gynhc.com',