Order.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. <?php
  2. namespace App\Http\Controllers\WechatPay;
  3. use App\Http\Controllers\Core\Auth;
  4. use App\Http\Controllers\Fpdx\PairController;
  5. use App\Http\Controllers\Miniprogram\Auth as MiniAuth;
  6. use App\Models\OrderModel;
  7. use Illuminate\Http\Request;
  8. use App\Http\Controllers\Controller;
  9. class Order extends Controller
  10. {
  11. private $orderModel;
  12. public function __construct()
  13. {
  14. $this->orderModel = new OrderModel();
  15. }
  16. // 商品信息
  17. public const GOODS = array(
  18. 5 => [
  19. 'desc' => '抽卡',
  20. 'jsk' => 0,
  21. 'ck' => 1,
  22. 'total_fee' => 660,
  23. 'gold_flower' => 0,
  24. 'red_flower' => 0,
  25. 'body' => '卖室友充值'
  26. ],
  27. 6 => [
  28. 'desc' => '解锁卡充值',
  29. 'jsk' => 1,
  30. 'ck' => 0,
  31. 'total_fee' => 500,
  32. 'gold_flower' => 0,
  33. 'red_flower' => 1,
  34. 'body' => '卖室友充值'
  35. ],
  36. 7 => [
  37. 'desc' => '解锁卡充值',
  38. 'jsk' => 2,
  39. 'ck' => 0,
  40. 'total_fee' => 900,
  41. 'gold_flower' => 0,
  42. 'red_flower' => 2,
  43. 'body' => '卖室友充值'
  44. ],
  45. 8 => [
  46. 'desc' => '解锁卡充值',
  47. 'jsk' => 5,
  48. 'ck' => 0,
  49. 'total_fee' => 2190,
  50. 'gold_flower' => 0,
  51. 'red_flower' => 5,
  52. 'body' => '卖室友充值'
  53. ],
  54. 11 => [
  55. 'desc' => '解锁卡充值',
  56. 'jsk' => 10,
  57. 'ck' => 0,
  58. 'total_fee' => 3990,
  59. 'gold_flower' => 0,
  60. 'red_flower' => 10,
  61. 'body' => '卖室友充值'
  62. ],
  63. 1 => [
  64. 'desc' => '金fa充值',
  65. 'jsk' => 0,
  66. 'ck' => 0,
  67. 'total_fee' => 100,
  68. 'gold_flower' => 1,
  69. 'red_flower' => 0,
  70. 'body' => '卖室友充值'
  71. ],
  72. 9 => [
  73. 'desc' => '购买小fa充值',
  74. 'jsk' => 0,
  75. 'ck' => 0,
  76. 'total_fee' => 900,
  77. 'gold_flower' => 10,
  78. 'red_flower' => 0,
  79. 'body' => '卖室友充值'
  80. ],
  81. 10 => [
  82. 'desc' => '购买小fa充值',
  83. 'jsk' => 0,
  84. 'ck' => 0,
  85. 'total_fee' => 8800,
  86. 'gold_flower' => 100,
  87. 'red_flower' => 0,
  88. 'body' => '卖室友充值'
  89. ],
  90. );
  91. /**
  92. * 用户解锁卡下单
  93. * @param int $goods_type
  94. * @return array
  95. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  96. */
  97. public function unify(int $goods_type)
  98. {
  99. $uid = Auth::auth();
  100. if (!in_array($goods_type, [5, 6, 7, 8, 11, 9, 10])) {
  101. return array(
  102. 'code' => 101,
  103. 'message' => '商品类型不存在'
  104. );
  105. }
  106. $params = array(
  107. 'uid' => $uid,
  108. 'body' => self::GOODS[$goods_type]['body'],
  109. 'total_fee' => self::GOODS[$goods_type]['total_fee'],
  110. 'notify_url' => config('api.msy_url') . "/api/core/pay/notify"
  111. );
  112. $url = config('api.pay_url') . "/payments/unify";
  113. $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
  114. if (isset($result->code) && $result->code == 200) {
  115. $order = $this->orderModel->fill([
  116. 'create_at' => time(),
  117. 'flower' => self::GOODS[$goods_type]['gold_flower'],
  118. 'out_trade_no' => $result->data->order_id,
  119. 'total_fee' => self::GOODS[$goods_type]['total_fee'],
  120. 'uid' => $uid,
  121. 'type' => $goods_type
  122. ]);
  123. if ($order->save()) {
  124. return array(
  125. 'code' => 200,
  126. 'message' => 'ok',
  127. 'data' => [
  128. 'order_id' => $order->id
  129. ],
  130. );
  131. } else {
  132. return array(
  133. 'code' => 505,
  134. 'message' => '数据库异常'
  135. );
  136. }
  137. } else {
  138. return array(
  139. 'code' => $result->code ?? 505,
  140. 'message' => $result->message ?? "系统异常"
  141. );
  142. }
  143. }
  144. /**
  145. * 用户小fa下单
  146. * @param float $gold_flower
  147. * @return array
  148. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  149. */
  150. public function unifyByFlower(float $gold_flower = 1.00)
  151. {
  152. $uid = Auth::auth();
  153. $params = array(
  154. 'uid' => $uid,
  155. 'body' => self::GOODS[1]['body'],
  156. 'total_fee' => $gold_flower * 100,
  157. 'notify_url' => config('api.msy_url') . "/api/core/pay/notify"
  158. );
  159. $url = config('api.pay_url') . "/payments/unify";
  160. $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
  161. if (isset($result->code) && $result->code == 200) {
  162. $order = $this->orderModel->fill([
  163. 'create_at' => time(),
  164. 'flower' => $gold_flower,
  165. 'out_trade_no' => $result->data->order_id,
  166. 'total_fee' => $gold_flower * 100,
  167. 'uid' => $uid,
  168. 'type' => 1
  169. ]);
  170. if ($order->save()) {
  171. return array(
  172. 'code' => 200,
  173. 'message' => 'ok',
  174. 'data' => [
  175. 'order_id' => $order->id
  176. ],
  177. );
  178. } else {
  179. return array(
  180. 'code' => 505,
  181. 'message' => '数据库异常'
  182. );
  183. }
  184. } else {
  185. return array(
  186. 'code' => $result->code ?? 505,
  187. 'message' => $result->message ?? "系统异常"
  188. );
  189. }
  190. }
  191. /**
  192. * 分配对象下单
  193. * @param int $total_fee 费用
  194. * @param array $attach 附加数据包
  195. * @return array
  196. * @throws \ApiException
  197. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  198. */
  199. public function unifyByFpdx(int $total_fee, array $attach)
  200. {
  201. $uid = Auth::auth();
  202. $params = array(
  203. 'uid' => $uid,
  204. 'body' => "72小时恋爱体验报名",
  205. 'total_fee' => $total_fee,
  206. 'notify_url' => config('api.msy_url') . "/api/core/pay/notify/fpdx"
  207. );
  208. $order = $this->orderModel->where([
  209. ['uid', $uid],
  210. ['type', 3],
  211. 'type_id' => $attach['stage_id'],
  212. ['create_at', '>', time() - 600]
  213. ])->first();
  214. if (!collect($order)->isEmpty()) {
  215. return $order->id;
  216. }
  217. $url = config('api.pay_url') . "/payments/unify";
  218. $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
  219. if (isset($result->code) && $result->code == 200) {
  220. $order = $this->orderModel->fill([
  221. 'create_at' => time(),
  222. 'flower' => 0,
  223. 'out_trade_no' => $result->data->order_id,
  224. 'total_fee' => $total_fee,
  225. 'uid' => $uid,
  226. 'type' => 3,
  227. 'type_id' => $attach['stage_id'] ?? 0,
  228. 'attach_data' => json_encode($attach)
  229. ]);
  230. if ($order->save()) {
  231. return $order->id;
  232. } else {
  233. throw new \ApiException("数据库异常", 505);
  234. }
  235. } else {
  236. throw new \ApiException($result->message ?? "系统异常", $result->code ?? 505);
  237. }
  238. }
  239. /**
  240. * 表白下单
  241. * @param int $total_fee 表白费用
  242. * @param int $confess_id 表白记录id
  243. * @return mixed
  244. * @throws \ApiException
  245. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  246. */
  247. public function unifyByConfess(int $total_fee, int $confess_id)
  248. {
  249. $uid = Auth::auth();
  250. $params = array(
  251. 'uid' => $uid,
  252. 'body' => '卖室友表白',
  253. 'total_fee' => $total_fee,
  254. 'notify_url' => config('api.msy_url') . "/api/core/pay/notify/confess"
  255. );
  256. $url = config('api.pay_url') . "/payments/unify";
  257. $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->withData($params)->asJsonResponse()->post();
  258. if (isset($result->code) && $result->code == 200) {
  259. $order = $this->orderModel->fill([
  260. 'create_at' => time(),
  261. 'flower' => 0,
  262. 'out_trade_no' => $result->data->order_id,
  263. 'total_fee' => $total_fee,
  264. 'uid' => $uid,
  265. 'type' => 2,
  266. 'type_id' => $confess_id
  267. ]);
  268. if ($order->save()) {
  269. return $order->id;
  270. } else {
  271. throw new \ApiException("数据库异常", 505);
  272. }
  273. } else {
  274. throw new \ApiException($result->message ?? "系统异常", $result->code ?? 505);
  275. }
  276. }
  277. /**
  278. * 小程序支付jssdk
  279. * @param int $order_id
  280. * @return array
  281. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  282. */
  283. public function miniProgram(int $order_id)
  284. {
  285. $uid = MiniAuth::auth();
  286. $order = $this->orderModel->find($order_id);
  287. if (collect($order)->isEmpty()) {
  288. return array(
  289. 'code' => 101,
  290. 'message' => '订单号错误'
  291. );
  292. }
  293. if ($order->trade_state != 0) {
  294. return array(
  295. 'code' => 102,
  296. 'message' => '订单失效' . json_encode($order->toArray())
  297. );
  298. }
  299. if ($uid != $order->uid) {
  300. return array(
  301. 'code' => 103,
  302. 'message' => '用户标识不一致'
  303. );
  304. }
  305. $public_id = config('miniprogram.public_id');
  306. $url = config('api.pay_url') . "/payments/miniProgram/{$order->out_trade_no}";
  307. $result = \Curl::to($url)->withHeader("app:{$public_id}")->asJsonResponse()->get();
  308. if (isset($result->code) && $result->code == 200) {
  309. return array(
  310. 'code' => 200,
  311. 'message' => 'ok',
  312. 'data' => $result->data,
  313. );
  314. } else {
  315. return array(
  316. 'code' => $result->code ?? 505,
  317. 'message' => $result->message ?? "系统异常"
  318. );
  319. }
  320. }
  321. /**
  322. * 公众号支付jssdk
  323. * @param int $order_id
  324. * @return array
  325. * @throws \Tymon\JWTAuth\Exceptions\JWTException
  326. */
  327. public function jssdk(int $order_id)
  328. {
  329. $uid = Auth::auth();
  330. $order = $this->orderModel->find($order_id);
  331. if (collect($order)->isEmpty()) {
  332. return array(
  333. 'code' => 101,
  334. 'message' => '订单号错误'
  335. );
  336. }
  337. if ($order->trade_state != 0) {
  338. return array(
  339. 'code' => 102,
  340. 'message' => '订单失效'
  341. );
  342. }
  343. if ($uid != $order->uid) {
  344. return array(
  345. 'code' => 103,
  346. 'message' => '用户标识不一致'
  347. );
  348. }
  349. $url = config('api.pay_url') . "/payments/jssdk/{$order->out_trade_no}";
  350. $result = \Curl::to($url)->asJsonResponse()->get();
  351. if (isset($result->code) && $result->code == 200) {
  352. return array(
  353. 'code' => 200,
  354. 'message' => 'ok',
  355. 'data' => $result->data,
  356. );
  357. } else {
  358. return array(
  359. 'code' => $result->code ?? 505,
  360. 'message' => $result->message ?? "系统异常"
  361. );
  362. }
  363. }
  364. /**
  365. * 订单退款
  366. * @param int $order_id
  367. * @param int $refund_fee 退款金额:分
  368. * @param string $refund_desc
  369. * @param bool $all
  370. * @return array|bool
  371. * @throws \ApiException
  372. */
  373. public function refund(int $order_id, int $refund_fee, $refund_desc = "", $all = false)
  374. {
  375. $order = $this->orderModel->find($order_id);
  376. if (collect($order)->isEmpty()) {
  377. throw new \ApiException('订单号错误', 101);
  378. }
  379. if (0 == $order->order_state) {
  380. throw new \ApiException('订单失效', 102);
  381. }
  382. if ($all && $order->create_at < 1533114000) {
  383. throw new \ApiException("过期订单,请联系小向导微信:fpdxkf", 103);
  384. $url = config('api.pay_url') . "/payments/transfer";
  385. $data = array(
  386. 'uid' => $order->uid,
  387. 'amount' => $refund_fee,
  388. 'app_order_id' => "fpdx_refund_" . uniqid(),
  389. 'desc' => $refund_desc
  390. );
  391. } else {
  392. $url = config('api.pay_url') . "/payments/order/{$order->out_trade_no}/refund";
  393. $data = array(
  394. 'refund_fee' => $refund_fee,
  395. 'refund_desc' => $refund_desc
  396. );
  397. }
  398. $result = \Curl::to($url)->withContentType("application/x-www-form-urlencoded")->asJsonResponse()->withData($data)->post();
  399. if (isset($result->code) && $result->code == 200) {
  400. return true;
  401. } else {
  402. throw new \ApiException($result->message, $result->code);
  403. }
  404. }
  405. /**
  406. * 支付结果核销处理
  407. * @param Request $request
  408. * @param array $callback
  409. * @return string
  410. */
  411. private function handlePaidNotify(Request $request, array $callback)
  412. {
  413. $orderModel = new OrderModel();
  414. $order = $orderModel->where('out_trade_no', $request->input('order_id'))->first();
  415. if (collect($order)->isEmpty()) {
  416. return "fail";
  417. }
  418. if ($order->order_state != 0) {
  419. return "success";
  420. } else {
  421. $order->cash_fee = $request->input('cash_fee');
  422. if ($request->input('trade_state') == 'SUCCESS') {
  423. $order->order_state = 1;
  424. }
  425. if ($order->save()) {
  426. call_user_func($callback, $order);
  427. return "success";
  428. } else {
  429. return "fail";
  430. }
  431. }
  432. }
  433. /**
  434. * 普通支付成功业务处理
  435. * @param OrderModel $order
  436. * @return bool
  437. * @throws \Exception
  438. */
  439. protected function payment(OrderModel $order)
  440. {
  441. \DB::beginTransaction();
  442. try {
  443. // 增加抽卡次数
  444. \DB::table('kdgx_partner_charge_user')->where('uid', $order->uid)->increment(
  445. 'ck_count',
  446. self::GOODS[$order->type]['ck']
  447. );
  448. // 增加解锁卡
  449. $ticketController = new Ticket();
  450. for ($i = 0; $i < self::GOODS[$order->type]['jsk']; $i++) {
  451. $ticketController->create(5, $order->uid);
  452. }
  453. // 增加花
  454. \DB::table('kdgx_partner_charge_user')->where('uid', $order->uid)->increment(
  455. 'red_flower',
  456. self::GOODS[$order->type]['red_flower']
  457. );
  458. \DB::table('kdgx_partner_charge_user')->where('uid', $order->uid)->increment('gold_flower', $order->flower);
  459. // 日志
  460. \DB::table('kdgx_partner_charge_pay_logs')->insert([
  461. 'uid' => $order->uid,
  462. 'create_at' => time(),
  463. 'type' => 3,
  464. 'gold_flower' => $order->flower,
  465. 'red_flower' => self::GOODS[$order->type]['red_flower'],
  466. 'jsk' => self::GOODS[$order->type]['jsk'],
  467. 'type_id' => $order->total_fee,
  468. 'remark' => "微信充值 {$order->total_fee}"
  469. ]);
  470. \DB::commit();
  471. return true;
  472. } catch (\Exception $e) {
  473. \DB::rollBack();
  474. return false;
  475. }
  476. }
  477. /**
  478. * 普通支付结果通知
  479. * @param Request $request
  480. * @return string
  481. * @throws \Exception
  482. */
  483. public function notify(Request $request)
  484. {
  485. return $this->handlePaidNotify($request, [$this, 'payment']);
  486. }
  487. /**
  488. * 表白支付结果通知
  489. * @param Request $request
  490. * @return string
  491. */
  492. public function notifyByconfess(Request $request)
  493. {
  494. $confess = new Confess();
  495. return $this->handlePaidNotify($request, [$confess, 'payment']);
  496. }
  497. /**
  498. * 分配对象报名支付结果通知
  499. * @param Request $request
  500. * @return string
  501. */
  502. public function notifyByfpdx(Request $request)
  503. {
  504. $pairObj = new PairController();
  505. return $this->handlePaidNotify($request, [$pairObj, 'payment']);
  506. }
  507. public function requestRefund(int $order_id)
  508. {
  509. $order = $this->orderModel->find($order_id);
  510. $this->refund($order_id, $order->cash_fee, '测试退款');
  511. }
  512. }