getClassesByNamespace('\\App\\Services\\Gateway\\'); foreach ($class_list as $class) { if (get_parent_class($class) === 'App\\Services\\Gateway\\Base') { $payments[] = $class; } } return $payments; } public static function getPaymentsEnabled(): array { return array_values(array_filter(Payment::getAllPaymentMap(), static function ($payment) { return $payment::_enable(); })); } public static function getPaymentMap(): array { $result = []; foreach (self::getPaymentsEnabled() as $payment) { $result[$payment::_name()] = $payment; } return $result; } public static function getPaymentByName($name) { $all = self::getPaymentMap(); return $all[$name]; } public static function notify($request, $response, $args) { $payment = self::getPaymentByName($args['type']); if ($payment !== null) { $instance = new $payment(); return $instance->notify($request, $response, $args); } return $response->withStatus(404); } public static function returnHTML($request, $response, $args): string|ResponseInterface { $payment = self::getPaymentByName($args['type']); if ($payment !== null) { $instance = new $payment(); return $instance->getReturnHTML($request, $response, $args); } return ''; } public static function getStatus($request, $response, $args) { $payment = self::getPaymentByName($args['type']); if ($payment !== null) { $instance = new $payment(); return $instance->getStatus($request, $response, $args); } return $response->withStatus(404); } public static function payBalance($oThisUser, $oThisInvoice) { if ($oThisInvoice === null) { return [ 'ret' => 0, 'msg' => '账单不存在', ]; } if ($oThisUser->is_shadow_banned) { return [ 'ret' => 0, 'msg' => '支付失败,请稍后再试', ]; } if ($oThisUser->money < $oThisInvoice->price) { return [ 'ret' => 0, 'msg' => '余额不足', ]; } $money_before = $oThisUser->money; $oThisUser->money -= $oThisInvoice->price; $oThisUser->save(); (new UserMoneyLog())->add( $oThisUser->id, $money_before, (float) $oThisUser->money, -$oThisInvoice->price, '购买套餐 #' . $oThisInvoice->id ); $oThisInvoice->status = 'paid_balance'; $oThisInvoice->update_time = time(); $oThisInvoice->pay_time = time(); $oThisInvoice->money_use = $oThisInvoice->price; $oThisInvoice->save(); return [ 'ret' => 1, 'msg' => '支付成功', ]; } public static function code($request, $response, $args) { $oAntiXss = new AntiXSS(); $type_pay = "epay"; // epay, balance=本地钱包 $redir = $oAntiXss->xss_clean($request->getParam('redir')); $type_onlinePay = $oAntiXss->xss_clean($request->getParam('payType')); $iAmount = $oAntiXss->xss_clean($request->getParam('amount') ?? 0); $iAmount = (int) $iAmount; if ($iAmount < 1) { return $response->withJson([ 'ret' => 0, 'msg' => '金额不能小于1', ]); } $user = Auth::getUser(); $order = new Order(); $order->user_id = $user->id; $order->product_code = "code"; $order->user_product_name = "钱包充值"; $order->user_price = $iAmount; // $order->user_coupon = ""; $order->status = 'payment_pending'; $order->create_time = time(); $order->update_time = time(); $order->save(); $invoice = new Invoice(); $invoice->user_id = $user->id; $invoice->order_id = $order->id; // $invoice->content = json_encode($invoice_content); $invoice->price = $iAmount; $invoice->status = 'unpaid'; $invoice->create_time = time(); $invoice->update_time = time(); $invoice->pay_time = 0; // $invoice->set = $iSet; // 新增 // $invoice->money_use = $iYuezhifu; $invoice->save(); $args["true_price"] = $iAmount; $args["true_invoice_id"] = $invoice->id; $args["type"] = $type_onlinePay; $args["redir"] = $redir; $payment = self::getPaymentByName($type_pay); $instance = new $payment(); return $instance->purchase($request, $response, $args); // return $response->withJson([ // 'ret' => 1, // 'msg' => $iAmount, // ]); } public static function purchase($request, $response, $args) { $antiXss = new AntiXSS(); $type_pay = $args["type"]; // epay, balance=本地钱包 $coupon_raw = $antiXss->xss_clean($request->getParam('coupon')); $product_id = $antiXss->xss_clean($request->getParam('shopid')); // 暂时EPay用 $type_onlinePay = $antiXss->xss_clean($request->getParam('type')); $redir = $antiXss->xss_clean($request->getParam('redir')); $user = Auth::getUser(); //test // tomd("type_pay:".$type_pay); // tomd("coupon_raw:".$coupon_raw); // tomd("product_id:".$product_id); // tomd("autorenew:".$autorenew); // tomd("type_onlinePay:".$type_onlinePay); // tomd("redir:".$redir); // exit; ////// 先创建订单 $product = (new Product())->find($product_id); if ($product === null || $product->stock === 0) { return $response->withJson([ 'ret' => 0, 'msg' => '商品不存在或库存不足', ]); } if ($product->end_time != 0 && $product->end_time < time()) { return $response->withJson([ 'ret' => 0, 'msg' => '商品已过期', ]); } // 此时,商品原价 $true_price = $product->price; // 用户等级折扣最先算 $iUserVipRate = $user->getVipRate(); $true_price = $true_price * ((100 - $iUserVipRate) / 100); if ($user->is_shadow_banned) { return $response->withJson([ 'ret' => 0, 'msg' => '商品不存在或库存不足', ]); } if ($coupon_raw !== '') { $aPayOrderStatus = ["activated", "pending", "expired"]; $coupon = (new UserCoupon())->where('code', $coupon_raw)->first(); if ($coupon === null || ($coupon->expire_time !== 0 && $coupon->expire_time < time())) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码不存在或已过期', ]); } $coupon_limit = json_decode($coupon->limit); if ($coupon_limit->disabled) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码已被禁用', ]); } if ($product->coupon_disable == 1) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码不适用于此商品', ]); } if ($coupon_limit->product_id !== '' && ! in_array($product_id, explode(',', $coupon_limit->product_id))) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码不适用于此商品', ]); } $coupon_use_limit = $coupon_limit->use_time; if ($coupon_use_limit > 0) { $user_use_count = (new Order())->where('user_id', $user->id)->where('user_coupon', $coupon->code)->whereIn("status", $aPayOrderStatus)->count(); if ($user_use_count >= $coupon_use_limit) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码使用次数已达上限', ]); } } if (property_exists($coupon_limit, 'total_use_time')) { $coupon_total_use_limit = $coupon_limit->total_use_time; } else { $coupon_total_use_limit = -1; } if ($coupon_total_use_limit > 0 && $coupon->use_count >= $coupon_total_use_limit) { return $response->withJson([ 'ret' => 0, 'msg' => '优惠码使用次数已达上限', ]); } $content = json_decode($coupon->content); if ($content->type === 'percentage') { $discount = $true_price * $content->value / 100; } else { $discount = $content->value; } $true_price = $true_price - $discount; } $product_limit = json_decode($product->limit); if ($product_limit->class_required !== '' && $user->class < (int) $product_limit->class_required) { return $response->withJson([ 'ret' => 0, 'msg' => '您的账户等级不足,无法购买此商品', ]); } if ($product_limit->node_group_required !== '' && $user->node_group !== (int) $product_limit->node_group_required) { return $response->withJson([ 'ret' => 0, 'msg' => '您所在的用户组无法购买此商品', ]); } if ($product_limit->new_user_required !== 0) { $order_count = (new Order())->where('user_id', $user->id)->whereIn("status", $aPayOrderStatus)->count(); if ($order_count > 0) { return $response->withJson([ 'ret' => 0, 'msg' => '此商品仅限新用户购买', ]); } } // 最后余额抵扣 $iYuezhifu = 0; if ($user->money > 0) { // 如果有余额 $iRengxuzhifu = $true_price - $user->money; // 仍需支付 if ($iRengxuzhifu <= 0) { // 余额能覆盖支付额,强制走钱包 $type_pay = "balance"; } else { // 余额抵付 $iYuezhifu = $user->money; } } $iSet = $user->havePayClass() ? 2 : 1; if ($product->name_sub) { $sProductName = $product->name." - ".$product->name_sub; } else { $sProductName = $product->name; } $order = new Order(); $order->user_id = $user->id; $order->product_code = $product->code; $order->user_product_name = $sProductName; $order->user_price = $true_price; $order->user_coupon = $coupon_raw; $order->status = 'payment_pending'; $order->create_time = time(); $order->update_time = time(); $order->save(); // $invoice_content = []; // $invoice_content[] = [ // 'content_id' => 0, // 'name' => $product->name, // 'price' => $product->price, // ]; // // if ($coupon_raw !== '') { // $invoice_content[] = [ // 'content_id' => 1, // 'name' => '优惠码 ' . $coupon_raw, // 'price' => '-' . $discount, // ]; // } $invoice = new Invoice(); $invoice->user_id = $user->id; $invoice->order_id = $order->id; // $invoice->content = json_encode($invoice_content); $invoice->price = $true_price; $invoice->status = 'unpaid'; $invoice->create_time = time(); $invoice->update_time = time(); $invoice->pay_time = 0; // $invoice->set = $iSet; // 新增 $invoice->money_use = $iYuezhifu; $invoice->save(); if ($type_pay !== "balance" && $iYuezhifu > 0) { $user->money = 0; $user->save(); (new UserMoneyLog())->add( $user->id, $iYuezhifu, (float) $user->money, -$iYuezhifu, '余额抵付 #账单号:'.$invoice->id ); } // if ($product->stock > 0) { // $product->stock -= 1; // } // $product->sale_count += 1; // $product->save(); if ($coupon_raw !== '') { $coupon->use_count += 1; $coupon->save(); } ////// end ////////// // 如果是钱包支付,拦截 if ($type_pay == "balance") { $result = self::payBalance($user, $invoice); return $response->withJson($result); } $payment = self::getPaymentByName($type_pay); if ($payment !== null) { // if ($type_pay == "epay") { $args["true_price"] = $true_price; $args["true_invoice_id"] = $invoice->id; $args["type"] = $type_onlinePay; $args["redir"] = $redir; // } $instance = new $payment(); return $instance->purchase($request, $response, $args); } return $response->withStatus(404); } }