int, // 商城Id * ids => array, // 提现Ids * ] * @return array [boolean, string] */ public function globalWithdrawToPay($params) { // 设置商城ID $this->setMallId($params['mall_id'] ?? 0); // 支付 $count = $this->withdrawToPay($params['ids'] ?? []); if ($count === false) { return [false, $this->getErrorMsg()]; } return [true, sprintf('打款成功%s笔', $count)]; } /** * 进行提现支付 * * @param array $ids * @return boolean|int */ public function withdrawToPay(array $ids) { // 获取设置 $setting = (new SettingService($this->mall_id))->getSetting(); if (empty($setting)) return $this->error('未进行代付配置'); // 查询代付提现订单 $list = WithdrawLog::getAlitopayLogByIds($this->mall_id, $ids); if (empty($list)) return $this->error('没有符合条件的提现订单'); // 加锁 $uniqid = uniqid(); $lock_key = 'alitopay_order_lock_' . $this->mall_id; if (!LockHelper::lock($lock_key, $uniqid)) return $this->error('操作频繁请稍后重试'); // 拼接数据入表 $insert_data = []; $time = time(); foreach ($list as $cash) { // 收款对象 $ali_user = Json::decode($cash['extra']); // 是否设置名称和账号 if (empty($ali_user['name']) || empty($ali_user['mobile'])) { return $this->error("订单{$cash['order_no']},支付宝名称或者支付宝账号为空"); } // 是否达到最低打款金额 if ($cash['actual_num'] < AlitoapyEnum::MIX_WITHDRAW) { return $this->error("订单{$ali_user['name']},打款金额必须大于1元"); } // 数据 $data['mall_id'] = $this->mall_id; $data['order_sn'] = $time . rand(1000, 9999); $data['type'] = Order::TYPE_WITHDRAWAL; $data['money'] = $cash['actual_num']; $data['name'] = $ali_user['name']; $data['account'] = $ali_user['mobile']; $data['source_id'] = $cash['id']; $data['source_sn'] = $cash['order_no']; $data['created_at'] = $data['updated_at'] = $time; $insert_data[] = $data; } // 开启事务 $db = Yii::$app->db->beginTransaction(); try { // 批量插入 Order::batchInsert($insert_data); // 批量修改打款中 $order_ids = array_column($list, 'id'); WithdrawLog::changeStatusToPayingByIds($order_ids); $db->commit(); } catch (\Exception $e) { $db->rollBack(); LockHelper::uLock($lock_key, $uniqid); return $this->error($e->getMessage()); } // 批量进行打款 $count = $this->aliPay($insert_data); LockHelper::uLock($lock_key, $uniqid); return $count; } /** * 支付宝进行支付 * * @param array $list * @return int */ private function aliPay(array $list) { $aliapy = new AlipayService($this->mall_id); // 创建一个批次号 $out_batch_no = 'TX' . date('Ymd') . $this->mall_id . rand(1000, 9999); $count = 0; foreach ($list as $v) { // 打款 $res = $aliapy->transfer( $v['money'], $v['name'], $v['account'], $v['order_sn'] ); if ($res['code'] == '10000') { // 打款成功 Order::paySuccessBySourceIdAndOrderSn( $v['source_id'], $v['order_sn'],$res['order_id'] ); $count++; } else { // 打款失败 Order::payFialBySourceIdAndOrderSn( $v['source_id'], $v['order_sn'], $res['sub_msg'] ); } } // 设置批次号 Order::setOutBatchNoByOrderSn($out_batch_no, array_column($list, 'order_sn')); //支付宝代付-打款成功事件 $event = new WithdrawToPayEvent($this->mall_id); $data = [ 'mall_id'=>$this->mall_id, 'out_batch_no'=>$out_batch_no, ]; \Yii::$app->services->events->dispatch($event,$data , $event->listeners); return $count; } /** * 全局调用使用 提现通道 * * @param array $params * @return array */ public function withdrawChannel(array $params) { $mall_id = $params['mall_id'] ?? 0; $setting = (new SettingService($mall_id))->getSetting(); $is_install = !empty($setting) ? 1 : 0; return [ 'alitopay' => [ 'is_install' => $is_install, ], ]; } /** * 全局调用使用 获取支付方式 * * @param array $params * [ * mall_id => int * ] * @return array */ public function getWithdrawWay(array $params) { // 提现方式 $way = [ AlitoapyEnum::ALITOPAY => AlitoapyEnum::ALITOPAY_NAME ]; $mall_id = $params['mall_id'] ?? 0; // mall_id为空 后台显示提现方式 if (empty($mall_id)) return $way; $setting = (new SettingService($params['mall_id']))->getSetting(); // 配置密钥后显示 if (!empty($setting)) return $way; return []; } }