AliPayServices.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. /**
  3. * 支付宝支付
  4. */
  5. namespace app\api\services;
  6. use think\console\command\optimize\Schema;
  7. use think\Exception;
  8. use think\facade\Db;
  9. use utils\AliPay;
  10. /**
  11. * Class AliPayServices
  12. * @package app\services
  13. * @method $this data($data)
  14. * @method $this type(int $type)
  15. * @method $this trade_type(string $trade_type)
  16. * @method $this uid(int $uid)
  17. */
  18. class AliPayServices extends BasePayServices
  19. {
  20. /**
  21. * 用户id
  22. * @var
  23. */
  24. protected $uid;
  25. /**
  26. * 数据体
  27. * @var
  28. */
  29. protected $data;
  30. /**
  31. * 支付类型 app jsapi
  32. * @var string
  33. */
  34. protected $trade_type;
  35. protected static $instance = null;
  36. public static function instance ()
  37. {
  38. if (is_null(self::$instance)) {
  39. self::$instance = new static();
  40. }
  41. return self::$instance;
  42. }
  43. /**
  44. * 统一下单
  45. * @return mixed
  46. */
  47. public function getUnifiedOrder ()
  48. {
  49. $uid = $this->uid;
  50. if (!$uid || !$this->data)
  51. return api_error_return('下单失败');
  52. list($body, $total_amount, $order_type, $remarks, $trade_type, $pay_way, $voucher_img) = $this->_payConf($uid, $this->data);
  53. // 如果是会员订单
  54. // ["开通会员","38","3","开通会员time2022-01-17 22:14:15","app","1",""]
  55. // 如果是商品订单
  56. // ["购买商品",40,"4","20220117224549208049091","app","1",""]
  57. $out_trade_no = rand(1000000000, 9999999999) . (string)date('ymdhis', time()) . (int)microtime(true); // 订单号
  58. /** @var AliPay $pay */
  59. $pay = app()->make(AliPay::class);
  60. if ($pay->pay_v == 1) {
  61. $rpm = $pay->unifiedOrder(compact('uid', 'body', 'out_trade_no', 'total_amount'));
  62. // {
  63. // "flag": true,
  64. // "msg": "调用成功",
  65. // "data": {
  66. // "result": "alipay_root_cert_sn=687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6&alipay_sdk=alipay-sdk-php-2020-04-15&app_cert_sn=01ddde3e4d64f1a43931e5dff9576eed&app_id=2021003113660354&biz_content=%7B%22total_amount%22%3A%2238%22%2C%22subject%22%3A%22%E5%BC%80%E9%80%9A%E4%BC%9A%E5%91%98%22%2C%22out_trade_no%22%3A%2291485501262201171015001642428900%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fhjw.suncorex.com%3A2080%2FaliResult&sign_type=RSA2&timestamp=2022-01-17+22%3A15%3A00&version=1.0&sign=kiqVqlWdOhZbbTXv1q4zaCSB3vrYSrJ2%2F9%2FqP7t9KEMrEX%2Fm5XtXYUzaLcVGCFgIL41MzvN9%2FMUdsAA6H0FwwW76diMQMz47yk0E4m2NMo0u9uQ09EAF83jPBwBhMEPTySTIR5aU1SbY%2BW2h1%2B%2BOErUgHiqdUMTeTKh8JrXE9ZsWAbHpQ47OIkke9F136C%2FKvmBmzacfsdlPwu7ikCPV0hLgVphoAp00O1BpQS%2FzwPR5gYkpiVic5HcWy2qZSqEgRTSeS%2FL4WtqzbkN3GT0L%2FmmqI7wGUZNhlacu53djiBCok1Y0TWvj%2BxhqshljuOA5IvtzIljUAFWlvUj8G1znsg%3D%3D"
  67. // }
  68. //}
  69. } else {
  70. $rpm = $pay->easyUnifiedOrder(compact('uid', 'body', 'out_trade_no', 'total_amount'));
  71. }
  72. if (!$rpm['flag']) {
  73. return api_error_return($rpm['msg']);
  74. }
  75. $this->setPaymentOrder(compact('body', 'out_trade_no', 'total_amount', 'remarks', 'uid', 'trade_type', 'order_type', 'pay_way', 'voucher_img'), 2);
  76. if (in_array($uid,[7523024,7523024])){
  77. sr_log('shimctest '.$uid. json_encode($rpm));
  78. }
  79. sleep('5');
  80. return api_succ_return(['msg'=>'请求成功', 'data'=>['alipay'=>$rpm['data']['result']]]);
  81. }
  82. /**
  83. * 支付回调
  84. * @return $this
  85. */
  86. public function getNotifyInfo ()
  87. {
  88. $pay = new AliPay();
  89. if ($pay->checkSign($this->data)) {
  90. if ($this->data['trade_status'] == 'TRADE_SUCCESS') {
  91. $this->notify_info = $this->data;
  92. $this->pay_status = true;
  93. $this->pay_way = 2;
  94. }
  95. }
  96. sr_log('签名错误');
  97. return $this;
  98. }
  99. /**
  100. * 提现
  101. * @return mixed
  102. * @throws \think\db\exception\DataNotFoundException
  103. * @throws \think\db\exception\DbException
  104. * @throws \think\db\exception\ModelNotFoundException
  105. */
  106. public function withdrawal ()
  107. {
  108. if (empty($this->data['money'])){
  109. throw new Exception('参数错误');
  110. }
  111. if (!preg_match("/^[1-9][0-9]*$/" ,$this->data['money'])){
  112. throw new Exception('提现金额不能有小数点,不能是负数');
  113. }
  114. $uid = $this->uid;
  115. if (!$uid || !$this->data)
  116. throw new Exception('提现失败');
  117. $money = $this->data['money'];
  118. $user = Db::name('user')->alias('a')->join('user_data b', 'a.id=b.uid')->field('money,status,alipay,real_name,is_auth,level')->where('a.id', $uid)->find();
  119. if ($user['status'] != 1)
  120. throw new Exception('账号已被禁用');
  121. if ($user['is_auth'] != 1)
  122. throw new Exception('你还未实名认证');
  123. if (empty($user['alipay']) || empty($user['real_name']))
  124. throw new Exception('你还未绑定支付宝');
  125. if ($money <= env('WITHDRAW.ONE_COUNT_MONEY'))
  126. throw new Exception('单次提现金额要大于'.env('WITHDRAW.ONE_COUNT_MONEY'));
  127. if ($money > $user['money'])
  128. throw new Exception('余额不足');
  129. // $pay_configs = get_config(2); // 获取支付设置
  130. // if (empty($pay_configs))
  131. // return api_error_return('后台配置错误');
  132. //$service = $pay_configs['TRANSFERSERVICE'] ?? 0;
  133. // $service = $user['vip'] ? 0 : ($user['level'] ? 1 : 3); // vip手续费0,星级达人手续费1%,普通用户3%
  134. $service_money = $money * (env('WITHDRAW.APP_WITHDRAW_SCALE')) / 100 + env('WITHDRAW.APP_WITHDRAW_BEGIN');
  135. $practical_money = $money - $service_money; // 最终金额
  136. // if ($money < $pay_configs['AGENT_REFLECT_MONEY'])
  137. // return api_error_return('单笔提现金额小于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
  138. // if ($money > $pay_configs['TRANSFERMAX'])
  139. // return api_error_return('单笔提现金额大于' . $pay_configs['TRANSFERMAX'] . '元');
  140. $today = Db::name('withdraw_log')
  141. ->field("
  142. CASE WHEN id>0 THEN count(id) ELSE 0 END count,
  143. CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
  144. ")
  145. ->where('uid', $uid)
  146. ->where('status', 1)
  147. ->whereTime('create_at', 'today')
  148. ->find();
  149. if ($today['count'] >= env('WITHDRAW.ONE_DAY_MAX_COUNT'))
  150. throw new Exception('超出今日提现次数');
  151. if ($today['money'] + $money > env('WITHDRAW.ONE_DAY_MAX_MONEY'))
  152. throw new Exception('超过今日最大转账金额' . env('WITHDRAW.ONE_DAY_MAX_MONEY') . '元');
  153. $moth = Db::name('withdraw_log')
  154. ->field("
  155. CASE WHEN id>0 THEN count(id) ELSE 0 END count,
  156. CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
  157. ")
  158. ->where('uid', $uid)
  159. ->where('status', 1)
  160. ->whereTime('create_at', 'moth')
  161. ->find();
  162. if ($moth['count'] >= env('WITHDRAW.ONE_MONTH_MAX_COUNT'))
  163. throw new Exception('超出本月提现次数');
  164. if ($moth['money'] + $money > env('WITHDRAW.ONE_MONTH_MAX_MONEY'))
  165. throw new Exception('超过本月最大提现金额' . env('WITHDRAW.ONE_MONTH_MAX_MONEY') . '元');
  166. $insert_log = [ // 提现流水
  167. 'uid' => $this->uid,
  168. 'apply_money' => $money,
  169. 'status' => 0,
  170. 'zfb_number' => $user['alipay'],
  171. 'zfb_name' => $user['real_name'],
  172. 'channel' => 1,
  173. 'service_money' => $service_money,
  174. 'transfer_type' => 1,
  175. 'practical_money' => $practical_money,
  176. 'ip' => app('request')->ip(),
  177. 'mchid' => Db::name('pay_config')->where('channel', 1)->where('status', 1)->value('mchid'), // 商户号
  178. ];
  179. edit_user_money(2, $uid, $money);
  180. $log_id = Db::name('withdraw_log')->insertGetId($insert_log);
  181. }
  182. /**
  183. * 后台提现
  184. * @return mixed
  185. * @throws \think\db\exception\DataNotFoundException
  186. * @throws \think\db\exception\DbException
  187. * @throws \think\db\exception\ModelNotFoundException
  188. */
  189. public function adminWithdrawal ()
  190. {
  191. $uid = $this->uid;
  192. if (!$uid || !$this->data)
  193. return api_error_return('提现失败');
  194. $money = $this->data['apply_money']; // 申请的金额
  195. $practical_money = $this->data['practical_money']; // 最终金额
  196. if ($practical_money <= 0)
  197. return api_error_return('提现金额必须大于0');
  198. $user = Db::name('user')->field('money,status,is_auth')->where('id', $uid)->find();
  199. if ($user['status'] != 1)
  200. return api_error_return('账号已被禁用');
  201. // if ($user['is_auth'] != 1)
  202. // api_error_return->json_error('你还未实名认证');
  203. if ($money <= 0)
  204. return api_error_return('提现金额要大于0');
  205. // if ($money > $user['money'])
  206. // return api_error_return('余额不足');
  207. // $pay_configs = get_config(2); // 获取支付设置
  208. // if (empty($pay_configs))
  209. // return api_error_return('后台配置错误');
  210. // if ($money < $pay_configs['AGENT_REFLECT_MONEY'])
  211. // return api_error_return('单笔提现金额小于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
  212. // if ($money > $pay_configs['TRANSFERMAX'])
  213. // return api_error_return('单笔提现金额大于' . $pay_configs['AGENT_REFLECT_MONEY'] . '元');
  214. // $today = Db::name('withdraw_log')
  215. // ->field("
  216. // CASE WHEN id>0 THEN count(id) ELSE 0 END count,
  217. // CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
  218. // ")
  219. // ->where('uid', $uid)
  220. // ->where('status', 1)
  221. // ->whereTime('create_at', 'today')
  222. // ->find();
  223. // if ($today['count'] >= $pay_configs['TRANSFERMAXDAYNUM'])
  224. // return api_error_return('超出今日提现次数');
  225. // if ($today['money'] + $money > $pay_configs['TRANSFERMAXTODAY'])
  226. // return api_error_return('超过今日最大转账金额' . $pay_configs['TRANSFERMAXTODAY'] . '元');
  227. // $moth = Db::name('withdraw_log')
  228. // ->field("
  229. // CASE WHEN id>0 THEN count(id) ELSE 0 END count,
  230. // CASE WHEN id>0 THEN sum(apply_money) ELSE 0 END money
  231. // ")
  232. // ->where('uid', $uid)
  233. // ->where('status', 1)
  234. // ->whereTime('create_at', 'moth')
  235. // ->find();
  236. // if ($moth['count'] >= $pay_configs['PERFORMANCE_UPPER'])
  237. // return api_error_return('超出本月提现次数');
  238. // if ($moth['money'] + $money > $pay_configs['TRANSFERMAXMONTH'])
  239. // return api_error_return('超过本月最大转账金额' . $pay_configs['TRANSFERMAXMONTH'] . '元');
  240. try {
  241. /** @var AliPay $pay */
  242. $pay = app()->make(AliPay::class);
  243. // $pay = new AliPay();
  244. $para = ['practical_money'=>$this->data['practical_money'],
  245. 'zfb_name'=>$this->data['zfb_name'],
  246. 'zfb_number'=>$this->data['zfb_number'],
  247. 'uid'=>$this->data['uid'],
  248. 'type'=>'pay'
  249. ];
  250. // $para {"practical_money":"7.50","real_name":"王红力","alipay":"18280066008","uid":"7493314"}
  251. $rpm = $pay->withdrawal($para);
  252. sr_log('rpm'.json_encode($rpm));
  253. if ($rpm['flag']) {
  254. Db::name('withdraw_log')->where('id', $this->data['id'])->update(['status' => 1, 'out_biz_no' => $rpm['data']['out_biz_no'], 'update_at' => date('Y-m-d H:i:s', time()), 'final_transfer_type' => 1]);
  255. return api_succ_return('提现成功');
  256. } else {
  257. Db::name('withdraw_log')->where('id', $this->data['id'])->update(['fail_log' => $rpm['msg'], 'status' => 2]);
  258. return api_error_return('提现失败');
  259. }
  260. } catch (\Exception $e) {
  261. sr_log('eeee'.$e->getMessage());
  262. return api_error_return($e->getMessage());
  263. return api_error_return('提现失败');
  264. }
  265. }
  266. /**
  267. * 魔术方法
  268. * @param $name
  269. * @param $arguments
  270. * @return $this
  271. */
  272. public function __call ($name, $arguments)
  273. {
  274. // TODO: Implement __call() method.
  275. if ($name == 'data') {
  276. $this->{$name} = $arguments[0];
  277. } else {
  278. $this->{$name} = $arguments[0];
  279. }
  280. return $this;
  281. }
  282. }