PayedService.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. *
  5. * User: king/QQ:995265288
  6. * Date: 2018/6/19 下午1:51
  7. * Email: livsyitian@163.com
  8. */
  9. namespace app\common\services\withdraw;
  10. use app\common\events\withdraw\WithdrawFailedEvent;
  11. use app\common\events\withdraw\WithdrawPayedEvent;
  12. use app\common\events\withdraw\WithdrawPayEvent;
  13. use app\common\events\withdraw\WithdrawPayingEvent;
  14. use app\common\exceptions\ShopException;
  15. use app\common\models\Income;
  16. use app\common\models\Member;
  17. use app\common\models\Withdraw;
  18. use app\common\services\credit\ConstService;
  19. use app\common\services\finance\BalanceChange;
  20. use app\common\services\income\WithdrawIncomeService;
  21. use app\common\services\PayFactory;
  22. use Illuminate\Support\Facades\DB;
  23. use app\common\services\finance\BalanceNoticeService;
  24. use app\common\services\finance\MessageService;
  25. class PayedService
  26. {
  27. /**
  28. * @var Withdraw
  29. */
  30. private $withdrawModel;
  31. private $msg;
  32. public function __construct(Withdraw $withdrawModel)
  33. {
  34. $this->setWithdrawModel($withdrawModel);
  35. }
  36. public function withdrawPay()
  37. {
  38. if ($this->withdrawModel->status == Withdraw::STATUS_AUDIT) {
  39. $this->_withdrawPay();
  40. return true;
  41. }
  42. throw new ShopException("提现打款:ID{$this->withdrawModel->id},不符合打款规则");
  43. }
  44. /**
  45. * 确认打款接口
  46. *
  47. * @return bool
  48. * @throws ShopException
  49. */
  50. public function confirmPay()
  51. {
  52. if ($this->withdrawModel->status == Withdraw::STATUS_PAYING || $this->withdrawModel->status == Withdraw::STATUS_AUDIT) {
  53. $this->withdrawModel->pay_at = time();
  54. try {
  55. DB::transaction(function () {
  56. $this->_payed();
  57. });
  58. return true;
  59. } catch (\Exception $e) {
  60. if ($this->withdraw_set['free_audit'] == 1) {
  61. event(new WithdrawFailedEvent($this->withdrawModel));
  62. $this->sendMessage();
  63. }
  64. }
  65. }
  66. throw new ShopException('提现记录不符合确认打款规则');
  67. }
  68. /**
  69. * 提现打款
  70. *
  71. * @return bool
  72. * @throws ShopException
  73. */
  74. private function _withdrawPay()
  75. {
  76. try {
  77. DB::transaction(function () {
  78. $this->pay();
  79. });
  80. return $this->payed();
  81. } catch (\Exception $e) {
  82. if (\Setting::get('withdraw.income.free_audit') == 1) {
  83. event(new WithdrawFailedEvent($this->withdrawModel));
  84. $this->sendMessage();
  85. }
  86. }
  87. throw new ShopException($this->msg ?: '提现失败');
  88. }
  89. private function pay()
  90. {
  91. event(new WithdrawPayEvent($this->withdrawModel));
  92. //提现收入表
  93. if (!\YunShop::request()->again_pay) {
  94. WithdrawIncomeService::insert($this->withdrawModel);
  95. }
  96. $this->paying();
  97. }
  98. private function paying()
  99. {
  100. $this->withdrawModel->status = Withdraw::STATUS_PAYING;
  101. $this->withdrawModel->pay_at = time();
  102. event(new WithdrawPayingEvent($this->withdrawModel));
  103. \Log::debug('++++app_common_services_withdraw_PayService----paying---');
  104. $this->updateWithdrawModel();
  105. }
  106. private function payed()
  107. {
  108. $result = $this->tryPayed();
  109. if ($result === true) {
  110. DB::transaction(function () {
  111. $this->_payed();
  112. });
  113. }
  114. return true;
  115. }
  116. private function _payed()
  117. {
  118. $this->withdrawModel->status = Withdraw::STATUS_PAY;
  119. $this->withdrawModel->arrival_at = time();
  120. \Log::debug('---------eventmodel+++++++++-----------------');
  121. $this->updateWithdrawModel();
  122. event(new WithdrawPayedEvent($this->withdrawModel));
  123. }
  124. /**
  125. * 尝试打款
  126. *
  127. * @return bool
  128. * @throws ShopException
  129. */
  130. private function tryPayed()
  131. {
  132. try {
  133. $result = $this->_tryPayed();
  134. //dd($result);
  135. if ($result !== true) {
  136. //处理中 返回 false , 提现记录打款中
  137. return false;
  138. }
  139. return true;
  140. } catch (\Exception $exception) {
  141. $this->withdrawModel->status = Withdraw::STATUS_AUDIT;
  142. $this->withdrawModel->pay_at = null;
  143. WithdrawIncomeService::delete($this->withdrawModel);
  144. \Log::debug('++++app_common_services_withdraw_PayService----tryPayed---');
  145. $this->updateWithdrawModel();
  146. $this->msg = $exception->getMessage();
  147. throw new ShopException($this->msg);
  148. } finally {
  149. // todo 增加验证队列
  150. }
  151. }
  152. /**
  153. * 尝试打款
  154. *
  155. * @return bool
  156. * @throws ShopException
  157. */
  158. private function _tryPayed()
  159. {
  160. switch ($this->withdrawModel->pay_way) {
  161. case Withdraw::WITHDRAW_WITH_BALANCE:
  162. $result = $this->balanceWithdrawPay();
  163. break;
  164. case Withdraw::WITHDRAW_WITH_WECHAT:
  165. $result = $this->wechatWithdrawPay();
  166. break;
  167. case Withdraw::WITHDRAW_WITH_ALIPAY:
  168. $result = $this->alipayWithdrawPay();
  169. break;
  170. case Withdraw::WITHDRAW_WITH_MANUAL:
  171. $result = $this->manualWithdrawPay();
  172. break;
  173. case Withdraw::WITHDRAW_WITH_HUANXUN:
  174. $result = $this->huanxunWithdrawPay();
  175. break;
  176. case Withdraw::WITHDRAW_WITH_EUP_PAY:
  177. $result = $this->eupWithdrawPay();
  178. break;
  179. case Withdraw::WITHDRAW_WITH_SEPARATE_UNION_PAY:
  180. $result = $this->separateUnionPay();
  181. break;
  182. case Withdraw::WITHDRAW_WITH_YOP:
  183. $result = $this->yopWithdrawPay();
  184. break;
  185. case Withdraw::WITHDRAW_WITH_CONVERGE_PAY:
  186. $result = $this->convergePayWithdrawPay();
  187. break;
  188. case Withdraw::WITHDRAW_WITH_YEE_PAY:
  189. $result = $this->yeePayWithdrawPay();
  190. break;
  191. case Withdraw::WITHDRAW_WITH_HIGH_LIGHT_WECHAT:
  192. $result = $this->highLightWithdrawPay(Withdraw::WITHDRAW_WITH_HIGH_LIGHT_WECHAT);
  193. break;
  194. case Withdraw::WITHDRAW_WITH_HIGH_LIGHT_ALIPAY:
  195. $result = $this->highLightWithdrawPay(Withdraw::WITHDRAW_WITH_HIGH_LIGHT_ALIPAY);
  196. break;
  197. case Withdraw::WITHDRAW_WITH_HIGH_LIGHT_BANK:
  198. $result = $this->highLightWithdrawPay(Withdraw::WITHDRAW_WITH_HIGH_LIGHT_BANK);
  199. break;
  200. case Withdraw::WITHDRAW_WITH_WORK_WITHDRAW_ALIPAY:
  201. case Withdraw::WITHDRAW_WITH_WORK_WITHDRAW_BANK:
  202. case Withdraw::WITHDRAW_WITH_WORK_WITHDRAW_WECHAT:
  203. $result = $this->workerWithdrawPay($this->withdrawModel->pay_way);
  204. break;
  205. case Withdraw::WITHDRAW_WITH_EPLUS_WITHDRAW_BANK:
  206. $result = $this->eplusWithdrawPay($this->withdrawModel->pay_way);
  207. break;
  208. case Withdraw::WITHDRAW_WITH_SILVER_POINT:
  209. $result = $this->silverPointWithdrawPay();
  210. break;
  211. default:
  212. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:未知打款类型";
  213. throw new ShopException($this->msg);
  214. }
  215. return $result;
  216. }
  217. /**
  218. * 提现打款:余额打款
  219. *
  220. * @return bool
  221. * @throws ShopException
  222. */
  223. private function balanceWithdrawPay()
  224. {
  225. $remark = "提现打款-{$this->withdrawModel->type_name}-金额:{$this->withdrawModel->actual_amounts}";
  226. $data = array(
  227. 'member_id' => $this->withdrawModel->member_id,
  228. 'remark' => $remark,
  229. 'source' => ConstService::SOURCE_INCOME,
  230. 'relation' => '',
  231. 'operator' => ConstService::OPERATOR_MEMBER,
  232. 'operator_id' => $this->withdrawModel->id,
  233. 'change_value' => $this->withdrawModel->actual_amounts
  234. );
  235. $result = (new BalanceChange())->income($data);
  236. if ($result !== true) {
  237. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result}";
  238. throw new ShopException($this->msg);
  239. }
  240. return true;
  241. }
  242. /**
  243. * 提现打款:微信打款
  244. *
  245. * @return bool
  246. * @throws ShopException
  247. */
  248. private function wechatWithdrawPay()
  249. {
  250. $memberId = $this->withdrawModel->member_id;
  251. $sn = $this->withdrawModel->withdraw_sn;
  252. $amount = $this->withdrawModel->actual_amounts;
  253. $remark = '';
  254. $memberModel = Member::uniacid()->where('uid', $memberId)->with(['hasOneFans', 'hasOneMiniApp', 'hasOneWechat']
  255. )->first();
  256. //优先使用微信会员打款
  257. if ($memberModel->hasOneFans->openid) {
  258. $result = PayFactory::create(PayFactory::PAY_WEACHAT)->doWithdraw($memberId, $sn, $amount, $remark, 1);
  259. //微信会员openid不存在时,假设使用小程序会员openid
  260. } elseif (app('plugins')->isEnabled('min-app') && $memberModel->hasOneMiniApp->openid) {
  261. $result = PayFactory::create(PayFactory::PAY_WE_CHAT_APPLET)->doWithdraw(
  262. $memberId,
  263. $sn,
  264. $amount,
  265. $remark,
  266. 1
  267. );
  268. } elseif (app('plugins')->isEnabled('app-set') && $memberModel->hasOneWechat->openid) {
  269. $result = PayFactory::create(PayFactory::PAY_WE_CHAT_APP)->doWithdraw($memberId, $sn, $amount, $remark, 1);
  270. } else {
  271. event(new WithdrawFailedEvent($this->withdrawModel));
  272. $this->sendMessage('提现会员openid错误');
  273. throw new ShopException("收入提现ID:{$this->withdrawModel->id},提现失败:提现会员openid错误");
  274. }
  275. if ($result['errno'] == 1) {
  276. event(new WithdrawFailedEvent($this->withdrawModel));
  277. $this->sendMessage();
  278. throw new ShopException("收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}");
  279. }
  280. $v3_switch = false;
  281. if ($memberModel->hasOneFans->openid) {
  282. $income_set = \Setting::get('shop.pay');
  283. $v3_switch = (bool)$income_set['weixin_apiv3'];
  284. } elseif (app('plugins')->isEnabled('min-app') && $memberModel->hasOneMiniApp->openid) {
  285. $appletSet = \Setting::get('plugin.min_app');
  286. $v3_switch = (bool)$appletSet['v3_switch'];
  287. } elseif (app('plugins')->isEnabled('app-set') && $memberModel->hasOneWechat->openid) {
  288. $appSet = \Setting::get('shop_app.pay');
  289. $v3_switch = (bool)$appSet['weixin_v3'];
  290. }
  291. if ($v3_switch) {
  292. return false;//使用新版V3接口,保持打款中
  293. }
  294. return true;
  295. }
  296. private function alipayWithdrawPay()
  297. {
  298. $member_id = $this->withdrawModel->member_id;
  299. $sn = $this->withdrawModel->withdraw_sn;
  300. $amount = $this->withdrawModel->actual_amounts;
  301. $remark = '';
  302. $result = PayFactory::create(PayFactory::PAY_ALIPAY)->doWithdraw($member_id, $sn, $amount, $remark);
  303. \Log::debug('app_common_services_withdraw_PayService_in_alipay----result+++++', $result);
  304. if (is_array($result)) {
  305. if ($result['errno'] == 1) {
  306. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  307. throw new ShopException($this->msg);
  308. }
  309. return true;
  310. }
  311. redirect($result)->send();
  312. }
  313. private function huanxunWithdrawPay()
  314. {
  315. $member_id = $this->withdrawModel->member_id;
  316. $sn = $this->withdrawModel->withdraw_sn;
  317. $amount = $this->withdrawModel->actual_amounts;
  318. $remark = '';
  319. $result = PayFactory::create(PayFactory::PAY_Huanxun_Quick)->doWithdraw($member_id, $sn, $amount, $remark);
  320. \Log::debug('app_common_services_withdraw_PayService_in_huanxun----result+++++', $result);
  321. if ($result['result'] == 10) {
  322. return true;
  323. }
  324. if ($result['result'] == 8) {
  325. return false;
  326. }
  327. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['msg']}";
  328. throw new ShopException($this->msg);
  329. }
  330. private function eupWithdrawPay()
  331. {
  332. $member_id = $this->withdrawModel->member_id;
  333. $sn = $this->withdrawModel->withdraw_sn;
  334. $amount = $this->withdrawModel->actual_amounts;
  335. $remark = '';
  336. $result = PayFactory::create(PayFactory::PAY_EUP)->doWithdraw($member_id, $sn, $amount, $remark);
  337. \Log::debug('app_common_services_withdraw_PayService_in_eup----result+++++', $result);
  338. if ($result['errno'] === 0) {
  339. return true;
  340. }
  341. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  342. throw new ShopException($this->msg);
  343. }
  344. private function yopWithdrawPay()
  345. {
  346. $member_id = $this->withdrawModel->member_id;
  347. $sn = $this->withdrawModel->withdraw_sn;
  348. $amount = $this->withdrawModel->actual_amounts;
  349. $remark = 'withdraw';
  350. $result = PayFactory::create(PayFactory::YOP)->doWithdraw($member_id, $sn, $amount, $remark);
  351. \Log::debug('app_common_services_withdraw_PayService_in_yop----result+++++', $result);
  352. if ($result['errno'] == 200) {
  353. return false;
  354. }
  355. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  356. throw new ShopException($this->msg);
  357. }
  358. private function yeePayWithdrawPay()
  359. {
  360. $member_id = $this->withdrawModel->member_id;
  361. $sn = $this->withdrawModel->withdraw_sn;
  362. $amount = $this->withdrawModel->actual_amounts;
  363. $remark = 'withdraw';
  364. $result = PayFactory::create(PayFactory::YEE_PAY)->doWithdraw($member_id, $sn, $amount, $remark);
  365. \Log::debug('app_common_services_withdraw_PayService_in_yee_pay----result+++++', $result);
  366. if ($result['errno'] == 200) {
  367. return false;
  368. }
  369. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  370. throw new ShopException($this->msg);
  371. }
  372. private function eplusWithdrawPay($type)
  373. {
  374. $member_id = $this->withdrawModel->member_id;
  375. $sn = $this->withdrawModel->withdraw_sn;
  376. $amount = bcadd($this->withdrawModel->actual_amounts, 0, 2);
  377. $remark = 'withdraw';
  378. $result = PayFactory::create(PayFactory::EPLUS_WECHAT_PAY)->doWithdraw(
  379. $member_id,
  380. $sn,
  381. $amount,
  382. $remark,
  383. $type
  384. );
  385. \Log::debug('app_common_services_withdraw_PayService_in_' . $type . '----result+++++', $result);
  386. if ($result['errno'] == 200) {
  387. return false;
  388. }
  389. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  390. throw new ShopException($this->msg);
  391. }
  392. private function silverPointWithdrawPay()
  393. {
  394. $result = PayFactory::create(PayFactory::SILVER_POINT_PAYMENT)->doWithdraw(
  395. $this->withdrawModel->member_id,
  396. $this->withdrawModel->withdraw_sn,
  397. bcadd($this->withdrawModel->actual_amounts, 0, 2),
  398. 'withdraw',
  399. $this->withdrawModel->pay_way
  400. );
  401. if ($result['errno'] == 200) {
  402. return false;
  403. }
  404. //银典支付要根据回调地址验证打款是否成功
  405. }
  406. private function workerWithdrawPay($type)
  407. {
  408. $member_id = $this->withdrawModel->member_id;
  409. $sn = $this->withdrawModel->withdraw_sn;
  410. $amount = bcadd($this->withdrawModel->actual_amounts, 0, 2);
  411. $remark = 'withdraw';
  412. $result = PayFactory::create(PayFactory::WORK_WITHDRAW_PAY)->doWithdraw(
  413. $member_id,
  414. $sn,
  415. $amount,
  416. $remark,
  417. $type
  418. );
  419. \Log::debug('app_common_services_withdraw_PayService_in_' . $type . '----result+++++', $result);
  420. if ($result['errno'] == 200) {
  421. return false;
  422. }
  423. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  424. throw new ShopException($this->msg);
  425. }
  426. private function highLightWithdrawPay($type)
  427. {
  428. $member_id = $this->withdrawModel->member_id;
  429. $sn = $this->withdrawModel->withdraw_sn;
  430. $amount = $this->withdrawModel->actual_amounts;
  431. $remark = 'withdraw';
  432. $result = PayFactory::create(PayFactory::HIGH_LIGHT)->doWithdraw($member_id, $sn, $amount, $remark, $type);
  433. \Log::debug('app_common_services_withdraw_PayService_in_' . $type . '----result+++++', $result);
  434. if ($result['errno'] == 200) {
  435. return false;
  436. }
  437. $this->msg = "收入提现ID:{$this->withdrawModel->id},提现失败:{$result['message']}";
  438. throw new ShopException($this->msg);
  439. }
  440. private function convergePayWithdrawPay()
  441. {
  442. $member_id = $this->withdrawModel->member_id;
  443. $sn = $this->withdrawModel->withdraw_sn;
  444. $amount = $this->withdrawModel->actual_amounts;
  445. $remark = 'withdraw';
  446. $result = PayFactory::create(PayFactory::PAY_WECHAT_HJ)->doWithdraw($member_id, $sn, $amount, $remark);
  447. if ($result['verify']) {
  448. return false;
  449. }
  450. $this->msg = "收入提现ID:{$this->withdrawModel->id},汇聚提现失败:{$result['msg']}";
  451. throw new ShopException($this->msg);
  452. }
  453. private function separateUnionPay()
  454. {
  455. \Log::debug('--------尝试打款withdrawPay---------');
  456. $member_id = $this->withdrawModel->member_id;
  457. $withdraw_id = $this->withdrawModel->id;
  458. $amount = $this->withdrawModel->amounts;
  459. $sn = $this->withdrawModel->separate['order_sn'];
  460. $trade_no = $this->withdrawModel->separate['trade_no'];
  461. //如果订单号不存在或支付单号不存在 重新获取 服务重新打款功能
  462. if (app('plugins')->isEnabled('separate') && (!$sn || !$trade_no)) {
  463. $incomeId = $this->withdrawModel->type_id;
  464. $incomeRelationModel = \Yunshop\Separate\Common\Models\IncomeRelationModel::whereIncomeId($incomeId)->first(
  465. );
  466. $sn = $incomeRelationModel->order_sn;
  467. $trade_no = $incomeRelationModel->pay_order_sn;
  468. }
  469. \Log::debug('--------withdrawPay1---------$member_id', print_r($member_id, 1));
  470. //\Log::debug('--------withdrawPay2---------$sn', print_r($sn,1));
  471. //\Log::debug('--------withdrawPay3---------$withdraw_id', print_r($withdraw_id,1));
  472. \Log::debug('--------withdrawPay4---------$amount', print_r($amount, 1));
  473. //\Log::debug('--------withdrawPay5---------$trade_no', print_r($trade_no,1));
  474. //调用分帐接口
  475. $result = PayFactory::create(PayFactory::PAY_SEPARATE)->doWithdraw(
  476. $member_id,
  477. $sn,
  478. $amount,
  479. $withdraw_id,
  480. $trade_no
  481. );
  482. \Log::debug(
  483. '-------app_common_services_withdraw_PayService_in_separateUnionPay
  484. --withdrawPay---------$result',
  485. print_r($result, 1)
  486. );
  487. if ($result) {
  488. return true;
  489. }
  490. return false;
  491. //TODO 对接结果进行判断1
  492. //throw new ShopException("分账失败");
  493. }
  494. /**
  495. * 手动打款
  496. *
  497. * @return bool
  498. */
  499. private function manualWithdrawPay()
  500. {
  501. return true;
  502. }
  503. /**
  504. * @return bool
  505. * @throws ShopException
  506. */
  507. private function updateWithdrawModel()
  508. {
  509. \Log::debug('--------进入更新打款体现记录---------');
  510. $validator = $this->withdrawModel->validator();
  511. if ($validator->fails()) {
  512. \Log::debug('--------更新打款提现验证失败---------');
  513. $this->msg = $validator->messages();
  514. throw new ShopException($this->msg);
  515. }
  516. if (!$this->withdrawModel->save()) {
  517. $this->msg = "提现打款-打款记录更新状态失败";
  518. throw new ShopException($this->msg);
  519. }
  520. return true;
  521. }
  522. /**
  523. * @param $withdrawModel
  524. * @throws ShopException
  525. */
  526. private function setWithdrawModel($withdrawModel)
  527. {
  528. $this->withdrawModel = $withdrawModel;
  529. }
  530. private function sendMessage()
  531. {
  532. if ($this->withdrawModel->type == 'balance') {
  533. //余额提现失败通知
  534. BalanceNoticeService::withdrawFailureNotice($this->withdrawModel);
  535. } else {
  536. $ids = \Setting::get('withdraw.notice.withdraw_user');
  537. foreach ($ids as $k => $v) {
  538. (new MessageService($this->withdrawModel))->failureNotice($v['uid']);
  539. }
  540. }
  541. }
  542. }