PayServer.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <?php
  2. namespace App\Servers;
  3. use App\Events\OrderSubAccountEvent;
  4. use App\Jobs\OrderSubAccountJob;
  5. use App\Models\ErrorRecord;
  6. use App\Models\Order;
  7. use App\Models\OrderItem;
  8. use App\Models\PayItem;
  9. use App\Models\PayOrder;
  10. use Illuminate\Support\Facades\DB;
  11. /**
  12. * 订单管理
  13. * Class OrderServer
  14. * @package App\Servers
  15. */
  16. class PayServer
  17. {
  18. private $pay_arr = [
  19. 0 => '余额支付',
  20. 1 => '微信支付',
  21. 2 => '支付宝支付',
  22. 3 => '混合支付',
  23. 4 => '公益豆支付',
  24. ];
  25. private $order_type = [
  26. 1 => '线上订单',
  27. 2 => '闲置订单',
  28. ];
  29. static private $server = null;
  30. private function __construct()
  31. {
  32. }
  33. /**
  34. * 创建对象
  35. * @return PayServer
  36. */
  37. static function creatServer()
  38. {
  39. if (empty(self::$server)) self::$server = new PayServer();
  40. return self::$server;
  41. }
  42. /**
  43. * 获取支付类型
  44. * @param $pay_type
  45. * @param $balance_money
  46. * @return string
  47. */
  48. public function getPayArr($pay_type, $balance_money = 0)
  49. {
  50. $pay_name = empty($this->pay_arr[$pay_type]) ? '' : $this->pay_arr[$pay_type];
  51. if ($pay_type != 0 && $pay_type != 4 && $balance_money > 0) {
  52. $pay_name .= '+余额支付';
  53. }
  54. return $pay_name;
  55. }
  56. /**
  57. * 创建支付信息
  58. * @param $order
  59. * @param $balance_money
  60. * @param $pay_type
  61. * @param $money_type
  62. * @param $order_type
  63. * @return PayOrder|\Illuminate\Database\Eloquent\Model
  64. * @throws \Exception
  65. */
  66. function createPayInfo($order, $balance_money, $pay_type, $money_type = 1, $order_type = 1)
  67. {
  68. if (empty($balance_money) || $balance_money <= 0) $balance_money = 0;
  69. $mobile_money = $order->{'total_money'} - $balance_money;
  70. if ($mobile_money <= 0) $mobile_money = 0;
  71. $pay_info = PayOrder::where('order_id', $order->{'id'})->where('m_id', $order->{'m_id'})->where('pay_type', $pay_type)->where('balance_money', $balance_money)->where('mobile_money', $mobile_money)->where('status', 0)->first();
  72. if (!empty($pay_info)) {
  73. return $pay_info;
  74. }
  75. if ($order_type == 1) {
  76. $pay_info = [
  77. 'order_id' => $order->{'id'},
  78. 'm_id' => $order->{'m_id'},
  79. 'balance_money' => $balance_money,
  80. 'mobile_money' => $mobile_money,
  81. 'pay_type' => $pay_type,
  82. 'money_type' => $money_type,
  83. 'order_type' => $order_type,
  84. 'status' => 0,
  85. 'water_id' => 0,
  86. 'pay_time' => date('Y-m-d H:i:s'),
  87. 'pay_sn' => '',
  88. 'pay_info' => '',
  89. // 'pay_code' => $order->{'order_sn'},
  90. 'pay_code' => IndentNumServer::creatServer()->getIndentNum(4),
  91. ];
  92. } else {
  93. $pay_info = [
  94. 'order_id' => $order->{'id'},
  95. 'm_id' => $order->{'buy_id'},
  96. 'balance_money' => $balance_money ?: 0,
  97. 'mobile_money' => $order->{'total_money'} - $balance_money,
  98. 'pay_type' => $pay_type,
  99. 'money_type' => $money_type,
  100. 'order_type' => $order_type,
  101. 'status' => 0,
  102. 'water_id' => 0,
  103. 'pay_time' => date('Y-m-d H:i:s'),
  104. 'pay_sn' => '',
  105. 'pay_info' => '',
  106. 'pay_code' => $order->{'used_sn'},
  107. ];
  108. }
  109. DB::beginTransaction();
  110. PayOrder::where('order_id', $order->{'id'})->where('m_id', $order->{'m_id'})->update(['status' => 2]);
  111. $pay_info = PayOrder::create($pay_info);
  112. if ($order_type == 1) OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, '订单创建支付信息');
  113. DB::commit();
  114. return $pay_info;
  115. }
  116. /**
  117. * 余额支付
  118. * @param PayOrder $pay_info
  119. * @return bool
  120. * @throws \Exception
  121. */
  122. function balancePay(PayOrder $pay_info)
  123. {
  124. DB::beginTransaction();
  125. if ($pay_info->{'balance_money'} > 0) {
  126. $pay_info = $this->deductionBalance($pay_info);
  127. if (empty($pay_info)) {
  128. DB::rollBack();
  129. return false;
  130. }
  131. }
  132. $pay_info->update(['status' => 1, 'pay_sn' => IndentNumServer::creatServer()->getIndentNum(4)]);
  133. if ($pay_info->{'order_type'} == 1) {
  134. //线上加入队列处理
  135. OrderSubAccountJob::dispatch($pay_info)->onConnection('redis')->onQueue('order_sub');
  136. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, '余额支付完成');
  137. } elseif ($pay_info->{'order_type'} == 2) {
  138. //闲置订单支付流程
  139. UsedServer::creatServer()->payOrder($pay_info);
  140. }
  141. DB::commit();
  142. return $pay_info;
  143. }
  144. /**
  145. * 公益豆支付
  146. * @param PayOrder $pay_info
  147. * @param PayOrder $claim_shop_id 扣款店铺
  148. * @return \App\Models\MoneyDetail|PayOrder|false|\Illuminate\Database\Eloquent\Model
  149. * @throws \Exception
  150. */
  151. function benefitPay(PayOrder $pay_info, $claim_shop_id)
  152. {
  153. DB::beginTransaction();
  154. $pay_info = $this->benefitBalance($pay_info, $claim_shop_id);
  155. if (empty($pay_info)) {
  156. DB::rollBack();
  157. return false;
  158. }
  159. $pay_info->update(['status' => 1]);
  160. //加入队列处理
  161. OrderSubAccountJob::dispatch($pay_info)->onConnection('redis')->onQueue('order_sub');
  162. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, '公益豆支付完成');
  163. DB::commit();
  164. return $pay_info;
  165. }
  166. /**
  167. * 回调信息
  168. * @param $pay_code
  169. * @param $pay_sn
  170. * @param $pay_money
  171. * @param $notify_info
  172. * @return bool
  173. * @throws \Exception
  174. */
  175. function NotifyPay($pay_code, $pay_sn, $pay_money, $notify_info)
  176. {
  177. $pay_info = PayOrder::where('pay_code', $pay_code)->where('status', 0)->first();
  178. if (empty($pay_info)) {
  179. $pay_info->update(['pay_sn' => $pay_sn, 'pay_info' => serialize($notify_info)]);
  180. ErrorRecord::create(['msg' => '订单支付状态错误', 'data' => serialize($notify_info)]);
  181. return false;
  182. }
  183. $is_test = env('TEST_SERVE', false);
  184. if ($pay_info->{'mobile_money'} != $pay_money && !$is_test) {
  185. $pay_info->update(['pay_sn' => $pay_sn, 'pay_info' => serialize($notify_info)]);
  186. ErrorRecord::create(['msg' => '支付金额不匹配', 'data' => serialize($notify_info)]);
  187. return false;
  188. }
  189. DB::beginTransaction();
  190. if ($pay_info->{'balance_money'} > 0) {
  191. $pay_info = $this->deductionBalance($pay_info);
  192. if (empty($pay_info)) {
  193. ErrorRecord::create(['msg' => '订单余额支付错误', 'data' => serialize($notify_info)]);
  194. DB::rollBack();
  195. return false;
  196. }
  197. }
  198. $pay_info->update(['pay_sn' => $pay_sn, 'pay_info' => serialize($notify_info), 'status' => 1]);
  199. // event(new OrderSubAccountEvent($pay_info));
  200. if ($pay_info->{'order_type'} == 1) {
  201. //线上加入队列处理
  202. OrderSubAccountJob::dispatch($pay_info)->onConnection('redis')->onQueue('order_sub');
  203. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, '在线支付回调完成');
  204. } elseif ($pay_info->{'order_type'} == 2) {
  205. //闲置订单支付流程
  206. UsedServer::creatServer()->payOrder($pay_info);
  207. }
  208. DB::commit();
  209. return true;
  210. }
  211. /**
  212. * 余额支付
  213. * @param PayOrder $pay_info
  214. * @return \App\Models\MoneyDetail|false|\Illuminate\Database\Eloquent\Model
  215. */
  216. function deductionBalance(PayOrder $pay_info)
  217. {
  218. $water_id = MoneyDetailServer::creatServer()->write(1, 2, $pay_info->{'balance_money'}, 0, $pay_info->{'m_id'}, $pay_info->{'pay_code'} . '流水支付完成', $pay_info->{'id'});
  219. if (empty($water_id)) return false;
  220. $pay_info->update(['water_id' => $pay_info->{'id'}]);
  221. return $pay_info;
  222. }
  223. /**
  224. * 公益豆
  225. * @param PayOrder $pay_info
  226. * @param PayOrder $claim_shop_id 扣款店铺ID(公益豆支付)
  227. * @return \App\Models\MoneyDetail|false|\Illuminate\Database\Eloquent\Model
  228. */
  229. function benefitBalance(PayOrder $pay_info, $claim_shop_id = 0)
  230. {
  231. $water_id = MoneyDetailServer::creatServer()->write(3, 4, $pay_info->{'balance_money'}, 0, $pay_info->{'m_id'}, $pay_info->{'pay_code'} . '流水支付完成', $pay_info->{'id'}, $claim_shop_id);
  232. if (empty($water_id)) return false;
  233. $pay_info->update(['water_id' => $pay_info->{'id'}]);
  234. return $pay_info;
  235. }
  236. /**
  237. * 订单商家分账
  238. * @param PayOrder $pay_info
  239. * @return false
  240. */
  241. function OrderSubAccount(PayOrder $pay_info)
  242. {
  243. $item_num = PayItem::where('pay_id', $pay_info->{'id'})->count();
  244. if ($item_num > 0) {
  245. return false;
  246. }
  247. $order = Order::where('id', $pay_info->{'order_id'})->select(['id', 'parent_id', 'child_num', 'total_money', 'shop_id', 'order_sn'])->first();
  248. DB::beginTransaction();
  249. //更新订单支付信息
  250. $pay_name = $this->getPayArr($pay_info->{'pay_type'}, $pay_info->{'balance_money'});
  251. Order::where('id', '=', $pay_info->{'order_id'}, 'or')->where('parent_id', '=', $pay_info->{'order_id'}, 'or')->update(['pay_time' => date('Y-m-d H:i:s'), 'pay_code' => $pay_info->{'pay_sn'}, 'pay_id' => $pay_info->{'id'}, 'pay_type' => $pay_info->{'pay_type'}, 'pay_name' => $pay_name]);
  252. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, $order->{'order_sn'} . '订单进行分账');
  253. //订单分账
  254. if ($order->{'shop_id'}) {
  255. if ($pay_info->{'balance_money'} > 0) {
  256. $this->balanceSubAccount($pay_info, 0, $pay_info->{'balance_money'}, $order->{'shop_id'}, $order->{'id'}, 1, $pay_info->{'money_type'});
  257. }
  258. if ($pay_info->{'mobile_money'} > 0) {
  259. $this->balanceSubAccount($pay_info, $pay_info->{'pay_type'}, $pay_info->{'mobile_money'}, $order->{'shop_id'}, $order->{'id'}, $pay_info->{'pay_type'}, $pay_info->{'money_type'});
  260. }
  261. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, $order->{'order_sn'} . '订单分账完成');
  262. } else {
  263. $order_list = Order::where('parent_id', $pay_info->{'order_id'})->where('id', '<>', $pay_info->{'order_id'})->select(['id', 'parent_id', 'child_num', 'total_money', 'shop_id', 'order_sn'])->get();
  264. foreach ($order_list as $item) {
  265. $proportion = round($item->{'total_money'} / $order->{'total_money'}, 6);
  266. if ($pay_info->{'balance_money'} > 0) {
  267. $sub_money = $proportion * $pay_info->{'balance_money'};
  268. $this->balanceSubAccount($pay_info, 0, $sub_money, $item->{'shop_id'}, $item->{'id'}, 1, $pay_info->{'money_type'});
  269. }
  270. if ($pay_info->{'mobile_money'} > 0) {
  271. $sub_money = $proportion * $pay_info->{'mobile_money'};
  272. $this->balanceSubAccount($pay_info, $pay_info->{'pay_type'}, $sub_money, $item->{'shop_id'}, $item->{'id'}, $pay_info->{'pay_type'}, $pay_info->{'money_type'});
  273. }
  274. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, $order->{'order_sn'} . '订单分账至' . $item->{'order_sn'});
  275. }
  276. OrderServer::creatServer()->OrderLog($pay_info->{'order_id'}, $order->{'order_sn'} . '订单分账完成');
  277. }
  278. DB::commit();
  279. }
  280. /**
  281. * 生成分账明细
  282. * @param PayOrder $pay_info
  283. * @param $pay_type
  284. * @param $money
  285. * @param $shop_id
  286. * @param $order_id
  287. * @param int $type
  288. * @param int $money_type
  289. */
  290. function balanceSubAccount(PayOrder $pay_info, $pay_type, $money, $shop_id, $order_id, $type = 1, $money_type = 1)
  291. {
  292. $item = [
  293. 'm_id' => $pay_info->{'m_id'},
  294. 'pay_id' => $pay_info->{'id'},
  295. 'pay_sn' => $pay_info->{'pay_sn'},
  296. 'pay_type' => $pay_type,
  297. 'money' => $money,
  298. 'type' => $type,
  299. 'shop_id' => $shop_id,
  300. 'money_type' => $money_type,
  301. 'order_id' => $order_id,
  302. ];
  303. PayItem::create($item);
  304. }
  305. }