UserExtractController.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. namespace app\api\controller\user;
  3. use app\models\user\UserBill;
  4. use app\models\user\UserExtract;
  5. use app\Request;
  6. use crmeb\services\payment\PaymentService;
  7. use crmeb\services\UtilService;
  8. use think\facade\Log;
  9. use tw\redis\UserRds;
  10. /**
  11. * 提现类
  12. * Class UserExtractController
  13. * @package app\api\controller\user
  14. */
  15. class UserExtractController
  16. {
  17. /**
  18. * @api {get} /extract/bank 提现银行
  19. * @apiName ExtractBank
  20. * @apiGroup Brokerage
  21. *
  22. * @apiSuccess {float} broken_commission 冻结佣金
  23. * @apiSuccess {float} brokerage_price 总佣金
  24. * @apiSuccess {float} commissionCount 可提现佣金
  25. * @apiSuccess {string[]} extractBank 银行列表
  26. * @apiSuccess {float} minPrice 最小提现金额
  27. */
  28. public function bank(Request $request)
  29. {
  30. $user = $request->user();
  31. // 佣金冻结时间
  32. $frozen_days = intval(sys_config('extract_time'));
  33. $frozen_from = time() - 86400 * $frozen_days;
  34. //可提现佣金
  35. $brokerage_commission = UserBill::where(['uid' => $user['uid'], 'category' => 'now_money', 'type' => 'brokerage'])
  36. ->where('add_time', '>', $frozen_from)
  37. ->where('pm', 1)
  38. ->sum('number');
  39. $refund_commission = UserBill::where(['uid' => $user['uid'], 'category' => 'now_money', 'type' => 'brokerage'])
  40. ->where('add_time', '>', $frozen_from)
  41. ->where('pm', 0)
  42. ->sum('number');
  43. $data['broken_commission'] = floatval(bcsub($brokerage_commission, $refund_commission, 2));
  44. if ($data['broken_commission'] < 0) {
  45. $data['broken_commission'] = 0;
  46. }
  47. $data['brokerage_price'] = $user['brokerage_price'];
  48. //可提现佣金
  49. $data['commissionCount'] = floatval(bcsub($data['brokerage_price'], $data['broken_commission'], 2));
  50. $extractBank = sys_config('user_extract_bank') ?? []; //提现银行
  51. $extractBank = str_replace("\r\n", "\n", $extractBank); //防止不兼容
  52. $data['extractBank'] = explode("\n", is_array($extractBank) ? (isset($extractBank[0]) ? $extractBank[0] : $extractBank) : $extractBank);
  53. $data['minPrice'] = sys_config('user_extract_min_price'); //提现最低金额
  54. // 输入记忆
  55. $ur = new UserRds();
  56. $cach = $ur->gets($user['uid'], ['wxpayName', 'bankCardNo', 'bankUser', 'bankName']);
  57. $data['wxpayName'] = $cach['wxpayName'] ? $cach['wxpayName'] : '';
  58. $data['bankCardNo'] = $cach['bankCardNo'] ? $cach['bankCardNo'] : '';
  59. $data['bankUser'] = $cach['bankUser'] ? $cach['bankUser'] : '';
  60. $data['bankName'] = $cach['bankName'] ? $cach['bankName'] : '';
  61. return app('json')->successful($data);
  62. }
  63. /**
  64. * @api {post} /extract/bank_fee 查询银行提现手续费
  65. * @apiName PostExtractBankFee
  66. * @apiGroup Brokerage
  67. *
  68. * @apiBody {int} extract_type 提现类型/通道
  69. * @apiBody {float} money 提现金额
  70. *
  71. * @apiSuccess {float} rate 手续费率
  72. * @apiSuccess {float} min 最少收取
  73. * @apiSuccess {float} max 最多收取
  74. * @apiSuccess {float} fee 当前收取
  75. * @apiSuccess {float} valid 实际到帐金额
  76. */
  77. public function bank_fee(Request $request)
  78. {
  79. $rate = 0.01; // 1%
  80. $min = 1; //
  81. $max = 25; //
  82. $extractInfo = UtilService::postMore([
  83. ['alipay_code', ''],
  84. ['extract_type', ''],
  85. ['money', 0],
  86. ['name', ''],
  87. ['bankname', ''],
  88. ['cardnum', ''],
  89. ['weixin', ''],
  90. ], $request);
  91. $user = $request->user();
  92. if ($extractInfo['extract_type'] != 'bank') {
  93. return app('json')->fail('不是银行卡提现');
  94. }
  95. if ($extractInfo['money'] < sys_config('user_extract_min_price')) {
  96. return app('json')->fail('金额小于最低提现金额');
  97. }
  98. // 手续费
  99. $fee = floatval(bcmul($extractInfo['money'], 0.01, 2));
  100. if ($fee < $min) {
  101. $fee = $min;
  102. }
  103. if ($fee > $max) {
  104. $fee = $max;
  105. }
  106. // 实际到帐金额
  107. $valid = floatval(bcsub($extractInfo['money'], $fee, 2));
  108. return app('json')->successful([
  109. 'rate' => $rate, // 费率
  110. 'min' => $min, // 最少收费
  111. 'max' => $max, // 最大收费
  112. 'fee' => $fee, // 当前收费
  113. 'valid' => $valid, // 实际到帐
  114. ]);
  115. }
  116. /**
  117. * @api {post} /extract/cash 提现申请
  118. * @apiName ExtractCash
  119. * @apiGroup Brokerage
  120. *
  121. * @apiBody {string} alipay_code 支付宝号码
  122. * @apiBody {string="alipay","bank","weixin"} extract_type 提现类型
  123. * @apiBody {float} money 提现金额
  124. * @apiBody {string} bankName 开户行
  125. * @apiBody {string} cardnum 卡号
  126. * @apiBody {string} name 微信实名/银行户名/支付宝帐号
  127. * @apiBody {string} weixin 微信实名
  128. *
  129. * @apiSuccessExample:
  130. * {
  131. *
  132. * }
  133. * @apiErrorExample:
  134. * {
  135. *
  136. * }
  137. *
  138. */
  139. public function cash(Request $request)
  140. {
  141. $extractInfo = UtilService::postMore([
  142. ['alipay_code', ''],
  143. ['extract_type', ''],
  144. ['money', 0],
  145. ['name', ''],
  146. ['bankname', ''],
  147. ['cardnum', ''],
  148. ['weixin', ''],
  149. ], $request);
  150. $user = $request->user();
  151. list($suc, $msg) = PaymentService::user_request_extract($user, $extractInfo);
  152. if ($suc) {
  153. return app('json')->successful('申请提现成功!');
  154. } else {
  155. return app('json')->fail($msg);
  156. }
  157. }
  158. /**
  159. * 即时提現,參數返回值同 cash
  160. * 本接口支持即時到帐,调用三方支付提现 API
  161. *
  162. * 用户账户必须满足以下规则。
  163. * 1. 满足对应提现通道要求,微信支付:每个用户1天限1次,每次限200, 平台每日限额 200,000
  164. * 2. 15 日内必须有退款订单。且30日内退款订单金额 > 提现金额
  165. * 3. 其他基本需求(最低提现限额等等)
  166. *
  167. * 不满足体现条件,则交给人工处理
  168. * API 执行失败,则必须重新提交提现请求,因为人工操作也是失败。
  169. * 如果API 返回 SYSTEMERROR, 则按照原订单参数重新提交。
  170. */
  171. public function flash_cash(Request $request)
  172. {
  173. // 提交申请
  174. $extractInfo = UtilService::postMore([
  175. ['alipay_code', ''],
  176. ['extract_type', ''],
  177. ['money', 0],
  178. ['name', ''],
  179. ['bankname', ''],
  180. ['cardnum', ''],
  181. ['weixin', ''],
  182. ], $request);
  183. $user = $request->user();
  184. list($suc, $msg) = PaymentService::user_request_extract($user, $extractInfo);
  185. if (!$suc) {
  186. return app('json')->fail($msg);
  187. }
  188. $row = $msg;
  189. $extractRow = UserExtract::getUserExtractInfo($user['uid'], $row['extract_type'], $row['add_time']);
  190. if (!$extractRow) {
  191. Log::error('Unbelievable error getUserExtractInfo(' . $user['uid'] . ' ' . $row['add_time'] . ')');
  192. return app('json')->fail('提交申请失败');
  193. }
  194. // 检查条件
  195. list($suc, $msg) = PaymentService::user_extract_auto_conditions($user);
  196. if (!$suc) {
  197. // 条件不满足,不进一步处理,相当与交给人工处理
  198. return app('json')->fail($msg);
  199. }
  200. // API
  201. list($suc, $ec, $es) = PaymentService::extract_by_api($extractRow);
  202. if (!$suc) {
  203. // API 失败 直接拒绝,因为重试也会大概率失败
  204. list($ok, $msg) = PaymentService::user_extract_reject($extractRow['id'], $es);
  205. if (!$ok) {
  206. errlog('user_extract_reject()' . $extractRow['id']);
  207. }
  208. return app('json')->fail($es);
  209. } else {
  210. list($ok, $msg) = PaymentService::user_extract_passed($extractRow);
  211. if (!$ok) {
  212. errlog('user_extract_passed()' . $extractRow['id']);
  213. }
  214. return app('json')->successful('提现成功');
  215. }
  216. }
  217. }