123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- <?php
- namespace App\Http\Controllers;
- use App\Exceptions\AlertException;
- use App\Jobs\GrowingIO\ActivateSvipReportJob;
- use App\Jobs\OrderCloseJob;
- use App\Services\Pay\CouponService;
- use App\Services\Pay\OrderService;
- use App\Services\User\VipService;
- use Illuminate\Support\Facades\DB;
- use App\Http\Controllers\Core\Auth;
- use App\Http\Controllers\Fpdx\PairController;
- use App\Http\Controllers\Miniprogram\Auth as MiniAuth;
- use App\Models\OrderModel;
- use Illuminate\Http\Request;
- use Ixudra\Curl\Facades\Curl;
- /**
- * 订单及微信支付
- * Class Order
- * @package App\Http\Controllers
- */
- class Order extends Controller
- {
- private $orderModel;
- public function __construct()
- {
- $this->orderModel = new OrderModel();
- }
- // 商品信息
- public const GOODS = [
- 1 => [
- 'goods_id' => 1,
- 'desc' => '金fa充值',
- 'total_fee' => 100,
- 'gold_flower' => 1,
- 'red_flower' => 0,
- 'body' => '卖室友充值',
- 'notify_url' => "/api/core/pay/notify"
- ],
- 2 => [
- 'goods_id' => 2,
- 'desc' => '卖室友表白',
- 'total_fee' => 100,
- 'gold_flower' => 0,
- 'red_flower' => 0,
- 'body' => '卖室友表白',
- 'notify_url' => "/api/core/pay/notify"
- ],
- 3 => [
- 'goods_id' => 3,
- 'desc' => '72小时恋爱体验入场券',
- 'total_fee' => 990,
- 'gold_flower' => 0,
- 'red_flower' => 0,
- 'body' => '72小时入场券',
- 'notify_url' => "/api/core/pay/notify"
- ],
- 9 => [
- 'goods_id' => 9,
- 'desc' => '购买小fa充值',
- 'total_fee' => 900,
- 'gold_flower' => 10,
- 'red_flower' => 0,
- 'body' => '卖室友充值',
- 'notify_url' => "/api/core/pay/notify"
- ],
- 10 => [
- 'goods_id' => 10,
- 'desc' => '购买小fa充值',
- 'total_fee' => 8800,
- 'gold_flower' => 100,
- 'red_flower' => 0,
- 'body' => '卖室友充值',
- 'notify_url' => "/api/core/pay/notify"
- ],
- 12 => [
- 'goods_id' => 12,
- 'desc' => "「1个月」超级会员充值",
- 'total_fee' => 2990,
- 'gold_flower' => 0,
- 'red_flower' => 0,
- 'body' => '分配对象「1个月」超级会员充值',
- 'notify_url' => "/api/pay/notify/supervip"
- ],
- 13 => [
- 'goods_id' => 13,
- 'desc' => "「3个月」超级会员充值",
- 'total_fee' => 7200,
- 'gold_flower' => 0,
- 'red_flower' => 0,
- 'body' => '分配对象「3个月」超级会员充值',
- 'notify_url' => "/api/pay/notify/supervip"
- ],
- 14 => [
- 'goods_id' => 14,
- 'desc' => "「12个月」超级会员充值",
- 'total_fee' => 25200,
- 'gold_flower' => 0,
- 'red_flower' => 0,
- 'body' => '分配对象「12个月」超级会员充值',
- 'notify_url' => "/api/pay/notify/supervip"
- ],
- ];
- /**
- * 超级会员充值
- * @param Request $request
- * @param int $goods_type
- * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
- * @throws AlertException
- * @throws \App\Exceptions\ApiException
- */
- public function unifyBySuperVip(Request $request, int $goods_type)
- {
- $uid = Auth::auth();
- if (!in_array($goods_type, [1, 3, 9, 10, 12, 13, 14])) {
- throw new AlertException("商品类型不存在", 404001);
- }
- $agent = $request->header('user-agent');
- $os = 'other';
- if (
- strpos($agent, 'macintosh')
- || strpos($agent, 'iPod')
- || strpos($agent, 'iPhone')
- || strpos($agent, 'iPad')
- ) {
- $os = "ios";
- }
- if (strpos($agent, 'Android')) {
- $os = 'android';
- }
- $goods = self::GOODS[$goods_type];
- $total_fee = $goods['total_fee'];
- $coupon_id = $request->input('coupon_id', 0);
- if ($coupon_id) {
- $couponService = new CouponService();
- $total_fee = $couponService->setUid($uid)
- ->setCouponId($coupon_id)
- ->setGoodsId($goods['goods_id'])
- ->use();
- }
- $params = [
- 'uid' => $uid,
- 'body' => $goods['body'],
- 'total_fee' => $total_fee,
- 'notify_url' => config('api.msy_url') . $goods['notify_url']
- ];
- $url = config('api.pay_url') . "/payments/unify";
- $result = Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
- if (isset($result->code) && $result->code == 200) {
- $fill = [
- 'flower' => $goods['gold_flower'],
- 'out_trade_no' => $result->data->order_id,
- 'total_amount' => $goods['total_fee'],
- 'total_fee' => $total_fee,
- 'uid' => $uid,
- 'type' => $goods['goods_id'],
- 'coupon_id' => $coupon_id,
- 'device' => $os,
- 'create_at' => time(),
- ];
- $media_id = $request->get('media_id', null);
- if (!is_null($media_id)) {
- $fill['attach_data'] = json_encode(['media_id' => $media_id]);
- }
- $order = $this->orderModel->fill($fill);
- if ($order->save()) {
- OrderCloseJob::dispatch($order->id)->onQueue('{order:close}')->delay(now()->addMinute(5));
- return response([
- 'code' => 200,
- 'message' => 'OK',
- 'data' => [
- 'order_id' => $order->id
- ],
- ]);
- } else {
- throw new AlertException("系统异常", 505);
- }
- } else {
- throw new AlertException("系统异常", 505);
- }
- }
- /**
- * 用户充值任意小fa下单
- * @param Request $request
- * @param float $gold_flower
- * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
- */
- public function unifyByFlower(Request $request, $gold_flower = 1.00)
- {
- $uid = Auth::auth();
- // 支付设备
- $agent = $request->header('user-agent');
- $os = 'other';
- if (
- strpos($agent, 'macintosh')
- || strpos($agent, 'iPod')
- || strpos($agent, 'iPhone')
- || strpos($agent, 'iPad')
- ) {
- $os = "ios";
- }
- if (strpos($agent, 'Android')) {
- $os = 'android';
- }
- $goods = self::GOODS[1];
- $params = [
- 'uid' => $uid,
- 'body' => $goods['body'],
- 'total_fee' => $gold_flower * 100,
- 'notify_url' => config('api.msy_url') . "/api/core/pay/notify"
- ];
- $url = config('api.pay_url') . "/payments/unify";
- $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
- if (isset($result->code) && $result->code == 200) {
- $order = $this->orderModel->fill([
- 'flower' => $gold_flower,
- 'out_trade_no' => $result->data->order_id,
- 'total_amount' => $gold_flower * 100,
- 'total_fee' => $gold_flower * 100,
- 'uid' => $uid,
- 'type' => $goods['goods_id'],
- 'device' => $os,
- 'create_at' => time(),
- ]);
- if ($order->save()) {
- return response([
- 'code' => 200,
- 'message' => 'OK',
- 'data' => [
- 'order_id' => $order->id
- ],
- ]);
- } else {
- return response([
- 'code' => 505,
- 'message' => '数据库异常'
- ]);
- }
- } else {
- return response([
- 'code' => $result->code ?? 505,
- 'message' => $result->message ?? "系统异常"
- ]);
- }
- }
- /**
- * 分配对象下单
- * @param int $total_fee 费用
- * @param array $attach 附加数据包
- * @param Request $request
- * @return int
- * @throws AlertException
- */
- public function unifyByFpdx(int $total_fee, array $attach, Request $request)
- {
- $uid = Auth::auth();
- // 支付设备
- $agent = $request->header('user-agent');
- $os = 'other';
- if (
- strpos($agent, 'macintosh')
- || strpos($agent, 'iPod')
- || strpos($agent, 'iPhone')
- || strpos($agent, 'iPad')
- ) {
- $os = "ios";
- }
- if (strpos($agent, 'Android')) {
- $os = 'android';
- }
- $goods = self::GOODS[3];
- // 使用优惠券
- $coupon_id = $request->input('coupon_id', 0);
- if ($coupon_id) {
- $couponService = new CouponService();
- $total_fee = $couponService->setUid($uid)
- ->setCouponId($coupon_id)
- ->setGoodsId($goods['goods_id'])
- ->use();
- }
- $params = [
- 'uid' => $uid,
- 'body' => "72小时恋爱体验报名",
- 'total_fee' => $total_fee,
- 'notify_url' => config('api.msy_url') . "/api/core/pay/notify/fpdx",
- 'attach' => json_encode($attach)
- ];
- $url = config('api.pay_url') . "/payments/unify";
- $result = \Curl::to($url)->withData($params)->asJsonResponse()->post();
- if (isset($result->code) && $result->code == 200) {
- $order = $this->orderModel->fill([
- 'out_trade_no' => $result->data->order_id,
- 'total_amount' => $goods['total_fee'],
- 'total_fee' => $total_fee,
- 'uid' => $uid,
- 'type' => $goods['goods_id'],
- 'type_id' => $attach['stage_id'] ?? 0,
- 'coupon_id' => $coupon_id,
- 'attach_data' => json_encode($attach),
- 'device' => $os,
- 'create_at' => time(),
- ]);
- if ($order->save()) {
- OrderCloseJob::dispatch($order->id)->onQueue('{order:close}')->delay(now()->addMinute(5));
- if ($total_fee == 0) {
- $params = [
- 'out_trade_no' => $result->data->order_id,
- ];
- $url = config('api.pay_url') . "/payments/notify/koudai";
- \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->post();
- return 0;
- }
- return $order->id;
- } else {
- throw new AlertException("数据库异常", 505);
- }
- } else {
- throw new AlertException(isset($result->message) ? $result->message : "发起支付失败", $result->code ?? 505);
- }
- }
- /**
- * 表白下单
- * @param int $total_fee 表白费用
- * @param int $confess_id 表白记录id
- * @param Request $request
- * @return mixed
- * @throws AlertException
- */
- public function unifyByConfess(int $total_fee, int $confess_id, Request $request)
- {
- $uid = Auth::auth();
- // 支付设备
- $agent = $request->header('user-agent');
- $os = 'other';
- if (
- strpos($agent, 'macintosh')
- || strpos($agent, 'iPod')
- || strpos($agent, 'iPhone')
- || strpos($agent, 'iPad')
- ) {
- $os = "ios";
- }
- if (strpos($agent, 'Android')) {
- $os = 'android';
- }
- $goods = self::GOODS[2];
- $params = [
- 'uid' => $uid,
- 'body' => '卖室友表白',
- 'total_fee' => $total_fee,
- 'notify_url' => config('api.msy_url') . "/api/core/pay/notify/confess"
- ];
- $pay_url = config('api.pay_url') . "/payments/unify";
- $result = \Curl::to($pay_url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
- if (isset($result->code) && $result->code == 200) {
- $order = $this->orderModel->fill([
- 'out_trade_no' => $result->data->order_id,
- 'total_amount' => $total_fee,
- 'total_fee' => $total_fee,
- 'uid' => $uid,
- 'type' => $goods['goods_id'],
- 'type_id' => $confess_id,
- 'device' => $os,
- 'create_at' => time(),
- ]);
- if ($order->save()) {
- OrderCloseJob::dispatch($order->id)->onQueue('{order:close}')->delay(now()->addMinute(5));
- return $order->id;
- } else {
- throw new AlertException("数据库异常", 505);
- }
- } else {
- throw new AlertException($result->message ?? "系统异常", $result->code ?? 505);
- }
- }
- /**
- * 小程序支付jssdk
- * @param int $order_id
- * @return array
- * @throws \Tymon\JWTAuth\Exceptions\JWTException
- */
- public function miniProgram(int $order_id)
- {
- $uid = MiniAuth::auth();
- $order = $this->orderModel->find($order_id);
- if (collect($order)->isEmpty()) {
- return response([
- 'code' => 404,
- 'message' => '订单号错误或者不存在'
- ]);
- }
- if ($order->trade_state != 0) {
- return response([
- 'code' => 102,
- 'message' => '订单失效' . json_encode($order->toArray())
- ]);
- }
- if ($uid != $order->uid) {
- return response([
- 'code' => 403,
- 'message' => '用户标识不一致'
- ]);
- }
- $public_id = config('miniprogram.public_id');
- $pay_url = config('api.pay_url') . "/payments/miniProgram/{$order->out_trade_no}";
- $result = \Curl::to($pay_url)->withHeader("app:{$public_id}")->asJsonResponse()->get();
- if (isset($result->code) && $result->code == 200) {
- return response([
- 'code' => 200,
- 'message' => 'Success',
- 'data' => $result->data,
- ]);
- } else {
- return response([
- 'code' => $result->code ?? 505,
- 'message' => $result->message ?? "系统异常",
- 'data' => $result
- ]);
- }
- }
- /**
- * 公众号支付jssdk
- * @param int $order_id
- * @return array
- */
- public function jssdk(int $order_id)
- {
- $uid = Auth::auth();
- $order = $this->orderModel->find($order_id);
- if (collect($order)->isEmpty()) {
- return response([
- 'code' => 404,
- 'message' => '订单号错误或不存在'
- ]);
- }
- if ($order->trade_state != 0) {
- return response([
- 'code' => 102,
- 'message' => '订单失效'
- ]);
- }
- if ($uid != $order->uid) {
- return response([
- 'code' => 403,
- 'message' => '用户标识不一致'
- ]);
- }
- $url = config('api.pay_url') . "/payments/jssdk/{$order->out_trade_no}";
- $result = \Curl::to($url)->asJsonResponse()->get();
- if (isset($result->code) && $result->code == 200) {
- return response([
- 'code' => 200,
- 'message' => 'Success',
- 'data' => $result->data,
- ]);
- } else {
- return response([
- 'code' => $result->code ?? 505,
- 'message' => $result->message ?? "系统异常"
- ]);
- }
- }
- /**
- * app支付jssdk
- * @param int $order_id
- * @return array
- */
- public function app(int $order_id)
- {
- $uid = Auth::auth();
- $order = $this->orderModel->find($order_id);
- if (collect($order)->isEmpty()) {
- return response([
- 'code' => 404,
- 'message' => '订单号错误或者不存在'
- ]);
- }
- if ($order->trade_state != 0) {
- return response([
- 'code' => 102,
- 'message' => '订单失效' . json_encode($order->toArray())
- ]);
- }
- if ($uid != $order->uid) {
- return response([
- 'code' => 403,
- 'message' => '用户标识不一致'
- ]);
- }
- $pay_url = config('api.pay_url') . "/payments/app/{$order->out_trade_no}";
- $result = \Curl::to($pay_url)->asJsonResponse()->get();
- if (isset($result->code) && $result->code == 200) {
- return response([
- 'code' => 200,
- 'message' => 'Success',
- 'data' => $result->data,
- ]);
- } else {
- return response([
- 'code' => $result->code ?? 505,
- 'message' => $result->message ?? "系统异常",
- 'data' => $result
- ]);
- }
- }
- /**
- * 订单退款
- * @param int $order_id
- * @param int $refund_fee 退款金额:分
- * @param string $refund_desc
- * @param bool $all
- * @return array|bool
- * @throws AlertException
- */
- public function refund(int $order_id, int $refund_fee, $refund_desc = "", $all = false)
- {
- $order = $this->orderModel->find($order_id);
- if (collect($order)->isEmpty()) {
- throw new AlertException('订单错误或不存在', 101);
- }
- if (0 == $order->order_state) {
- throw new AlertException('订单未支付不可退款', 102);
- }
- if ($all && $order->create_at < 1533114000) {
- throw new AlertException("过期订单,请联系小向导微信:fpdxkf", 103);
- $pay_url = config('api.pay_url') . '/payments/transfer';
- $data = [
- 'uid' => $order->uid,
- 'amount' => $refund_fee,
- 'app_order_id' => "fpdx_refund_" . uniqid(),
- 'desc' => $refund_desc
- ];
- } else {
- $pay_url = config('api.pay_url') . "/payments/order/{$order->out_trade_no}/refund";
- $data = [
- 'refund_fee' => $refund_fee,
- 'refund_desc' => $refund_desc
- ];
- }
- $result = \Curl::to($pay_url)->withContentType("application/x-www-form-urlencoded")->asJsonResponse()->withData($data)->post();
- if (isset($result->code) && $result->code == 200) {
- // 使用优惠券逻辑
- if ($order->coupon_id) {
- $couponService = new CouponService();
- $couponService->setUid($order->uid)
- ->setCouponId($order->coupon_id)
- ->unUse();
- }
- return true;
- } else {
- throw new AlertException("退款失败", 500);
- }
- }
- /**
- * 支付结果核销处理
- * @param Request $request
- * @param array $callback
- * @return string
- */
- private function handlePaidNotify(Request $request, array $callback)
- {
- $orderModel = new OrderModel();
- /** @var OrderModel|null $order */
- $order = $orderModel->where('out_trade_no', $request->input('order_id'))->first();
- if (!$order) {
- return "fail";
- }
- if ($order->order_state != 0) {
- return "success";
- } else {
- $order->cash_fee = $request->input('cash_fee', 0);
- if ($request->input('trade_state') == 'SUCCESS') {
- $order->order_state = 1;
- }
- if ($order->save()) {
- dispatch_now(new ActivateSvipReportJob($order));
- call_user_func($callback, $order);
- return "success";
- } else {
- return "fail";
- }
- }
- }
- /**
- * 普通支付成功业务处理
- * @param OrderModel $order
- * @return bool
- * @throws \Exception
- */
- protected function payment(OrderModel $order)
- {
- DB::beginTransaction();
- try {
- // 增加花
- DB::table('kdgx_partner_charge_user')->where('uid', $order->uid)->increment(
- 'red_flower',
- self::GOODS[$order->type]['red_flower']
- );
- DB::table('kdgx_partner_charge_user')->where('uid', $order->uid)->increment('gold_flower', $order->flower);
- // 日志
- DB::table('kdgx_partner_charge_pay_logs')->insert([
- 'uid' => $order->uid,
- 'create_at' => time(),
- 'type' => 3,
- 'gold_flower' => $order->flower,
- 'red_flower' => self::GOODS[$order->type]['red_flower'],
- 'type_id' => $order->total_fee,
- 'remark' => "微信充值 {$order->total_fee}"
- ]);
- DB::commit();
- return true;
- } catch (\Exception $e) {
- DB::rollBack();
- return false;
- }
- }
- /**
- * 普通支付结果通知
- * @param Request $request
- * @return string
- * @throws \Exception
- */
- public function notify(Request $request)
- {
- return $this->handlePaidNotify($request, [$this, 'payment']);
- }
- // 超级VIP支付结果通知
- public function notifyBySuperVip(Request $request)
- {
- $vs = new VipService();
- return $this->handlePaidNotify($request, [$vs, 'payment']);
- }
- /**
- * 表白支付结果通知
- * @param Request $request
- * @return string
- */
- public function notifyByconfess(Request $request)
- {
- $confess = new Confess();
- return $this->handlePaidNotify($request, [$confess, 'payment']);
- }
- /**
- * 分配对象报名支付结果通知
- * @param Request $request
- * @return string
- */
- public function notifyByfpdx(Request $request)
- {
- $pairObj = new PairController();
- return $this->handlePaidNotify($request, [$pairObj, 'payment']);
- }
- /**
- * 后台退款接口
- * @param int $order_id
- * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
- * @throws AlertException
- * @throws \App\Exceptions\ApiException
- */
- public function requestRefund(int $order_id)
- {
- $order = $this->orderModel->find($order_id);
- $orderService = new OrderService();
- $result = $orderService->refund($order_id, $order->cash_fee, '测试退款');
- return response([
- 'code' => 200,
- 'message' => 'OK',
- 'data' => $result
- ]);
- }
- /**
- * 订单关闭
- * @param $id
- * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
- * @throws \App\Exceptions\ApiException
- */
- public function closeOrder($id)
- {
- $orderService = new OrderService();
- $orderService->closeOrder($id);
- return response([
- 'code' => 200,
- 'message' => 'OK'
- ]);
- }
- }
|