| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- <?php
- namespace addons\Alitopay\common\services;
- use addons\Alitopay\common\jdk\alipay\request\AlipayDataBillEreceiptApplyRequest;
- use addons\Alitopay\common\jdk\alipay\request\AlipayDataBillEreceiptQueryRequest;
- use addons\Alitopay\common\jdk\alipay\request\AlipayFundTransCommonQueryRequest;
- use addons\Alitopay\common\logic\MiddleApi;
- use addons\Alitopay\common\models\Apply;
- use addons\Alitopay\common\models\Order;
- use common\components\export\CsvTool;
- use common\helpers\CurlHelper;
- use common\helpers\LockHelper;
- use common\helpers\UploadHelper;
- use common\models\common\Attachment;
- use common\models\common\MiddleMch;
- use common\models\user\UserWithdrawLog;
- use common\models\user\UserWithdrawLog as Withdraw;
- use Omnipay\Omnipay;
- use yii\base\BaseObject;
- use yii\helpers\Json;
- class OrderService extends BaseObject
- {
- public $error;
- public function error($msg)
- {
- $this->error = $msg;
- return false;
- }
- /**
- * 提现打款
- *
- * @param array $params
- * @return array [boolean, string]
- */
- public function withdrawToPay($params)
- {
- $mall_id = $params['mall_id'] ?? '';
- $order_ids = $params['ids'] ?? '';
- /**
- * @var Apply
- */
- $apply = Apply::find()->where(['mall_id' => $mall_id])->one();
- if (empty($apply)) {
- return [false, "支付宝代付配置未设置"];
- }
- if ($apply->auth_status != 2) {
- return [false, "支付宝代付未授权"];
- }
- $list = Withdraw::find()
- ->where([
- 'id' => $order_ids,
- 'mall_id' => $mall_id,
- 'status' => Withdraw::STATUS_AGREE,
- 'type' => "alipay",
- ])
- ->asArray()
- ->all();
- if (empty($list)) {
- return [false, "没有符合条件的提现记录"];
- }
- $uniqid = uniqid();
- $lock_key = "alitopay_order_lock_" . $mall_id;
- if (!LockHelper::lock($lock_key, $uniqid)) {
- return [false, "操作频繁请稍后重试"];
- };
- try {
- $order_insert = $trans_list = [];
- foreach ($list as $cash) {
- // 收款对象
- $ali_user = Json::decode($cash['extra']);
- if (empty($ali_user['name']) || empty($ali_user['mobile'])) {
- return [false, "订单{$cash['order_no']},支付宝名称或者支付宝账号为空"];
- }
- if ($cash['actual_num'] < 1) {
- return [false, "订单{$ali_user['name']},打款金额必须大于1元"];
- }
- // $ali_user['name'] = '陆福佳';
- // $ali_user['mobile'] = '15820232749';
- $one['mall_id'] = $apply->mall_id;
- $one['order_sn'] = time() . rand(1000, 9999);
- $one['type'] = Order::TYPE_WITHDRAWAL;
- $one['money'] = $cash['actual_num'];
- $one['name'] = $ali_user['name'];
- $one['account'] = $ali_user['mobile'];
- $one['source_id'] = $cash['id'];
- $one['source_sn'] = $cash['order_no'];
- $one['created_at'] = time();
- $one['updated_at'] = time();
- $order_insert[] = $one;
- }
- $db = \Yii::$app->db->beginTransaction();
- $res = \Yii::$app->db
- ->createCommand()
- ->batchInsert(Order::tableName(), array_keys($order_insert[0]), $order_insert)
- ->execute();
- if (!$res) {
- LockHelper::uLock($lock_key, $uniqid);
- $db->rollBack();
- return [false, "创建代付订单失败"];
- }
- // 修改提现记录,打款中
- $res = UserWithdrawLog::updateAll(['status' => 5, 'updated_at' => time()], ['id' => $order_ids]);
- if (!$res) {
- LockHelper::uLock($lock_key, $uniqid);
- $db->rollBack();
- return [false, "修改提现记录失败"];
- }
- // 发起代付请求
- try {
- $res = $this->ali_to_pay($apply, $order_insert);
- if ($res == false) {
- LockHelper::uLock($lock_key, $uniqid);
- $db->rollBack();
- return [false, $this->error];
- } else {
- LockHelper::uLock($lock_key, $uniqid);
- $db->commit();
- }
- return [true, $res];
- } catch (\Exception$e) {
- \Yii::error($e);
- LockHelper::uLock($lock_key, $uniqid);
- $db->rollBack();
- return [false, $this->error($e->getMessage())];
- }
- } catch (\Exception$e) {
- \Yii::error($e);
- isset($db) && $db->rollBack();
- LockHelper::uLock($lock_key, $uniqid);
- return [false, $e->getMessage()];
- }
- }
- public function orderToPay($mall_id, $ids)
- {
- }
- public function withdrawChannel($param)
- {
- $mall_id = $param['mall_id'] ?? 0;
- $data = Apply::findOne(['mall_id' => $mall_id]);
- $is_install = 0;
- if (!empty($data) && $data['auth_status'] == 2) {
- $is_install = 1;
- }
- return [
- "alitopay" => [
- 'is_install' => $is_install,
- ],
- ];
- }
- public function orderQuery($id)
- {
- $order = Order::findOne($id);
- if ($order->status != 2) {
- return $this->error("订单状态不是打款中...");
- }
- $mch = MiddleMch::getMch($order->mall_id);
- try {
- $api = new MiddleApi($mch);
- $res = $api->query($order->batch_sn);
- if (isset($res['order_list'])) {
- $this->orderNotifyHandle($res['order_list']);
- return true;
- }
- return $this->error("查询失败");
- } catch (\Exception$e) {
- return $this->error($e->getMessage());
- }
- }
- /**
- * 支付宝代付
- *
- * @param Apply $apply
- * @param array $orders
- * @return string|false
- */
- private function ali_to_pay(Apply $apply, $orders)
- {
- $order_sn = [];
- foreach ($orders as $order) {
- /** 创建支付宝数据 start **/
- $data['out_biz_no'] = $order['order_sn'];
- $data['trans_amount'] = $order['money'];
- $data['order_title'] = '收益';
- $data['payee_info'] = [
- 'identity' => $order['account'],
- 'identity_type' => 'ALIPAY_LOGON_ID',
- 'name' => $order['name'],
- ];
- $trans_list[] = $data;
- $order_sn[] = $order['order_sn'];
- /** 创建支付宝数据 end **/
- }
- $out_batch_no = 'TX' . date("Ymd") . $apply->mall_id . rand(1000, 9999);
- Order::updateAll(["batch_sn" => $out_batch_no], ['mall_id' => $apply->mall_id, 'order_sn' => $order_sn]);
- $title = '收益提现';
- $api_data = [
- 'alipay_app_id' => $apply->alipay_app_id,
- 'out_batch_no' => $out_batch_no,
- 'order_title' => $title,
- 'trans_order_list' => Json::encode($trans_list),
- ];
- // 发起代付请求
- try {
- $mch = MiddleMch::getMch($apply->mall_id);
- $api = new MiddleApi($mch);
- $res = $api->pay($api_data);
- if (!isset($res['form_html'])) {
- return $this->error("代付订单 form_html 未定义");
- }
- Order::updateAll(["status" => 2, 'updated_at' => time()], ['mall_id' => $apply->mall_id, 'order_sn' => $order_sn]);
- return $res['form_html'];
- } catch (\Exception$e) {
- \Yii::error($e);
- return $this->error($e->getMessage());
- }
- }
- public function orderNotifyHandle($order_list)
- {
- foreach ($order_list as $item) {
- $order = Order::find()->where(['order_sn' => $item['out_biz_no'], 'status' => 2])->one();
- if (empty($order)) {
- continue;
- }
- switch ($item['status']) {
- case "success":
- // 成功
- $res = $this->_success($order, $item);
- break;
- case "wait":
- // 打款中,不做处理
- break;
- case "fail":
- $res = $this->_fail($order, $item);
- // 失败
- break;
- case "disuse":
- // 取消,也作为失败
- break;
- }
- }
- return true;
- }
- private function _success(Order $order, $response)
- {
- $res = Order::updateAll(['status' => 3, 'msg' => '成功', 'updated_at' => time()], ['id' => $order->id]);
- if (!$res) {
- return $this->error("修改订单状态success失败");
- }
- if ($order->type == 2) {
- // 手动打款的,直接返回成功
- return true;
- }
- // 提现打款,要修改提现记录
- $cash = UserWithdrawLog::findOne($order->source_id);
- UserWithdrawLog::remit_success($cash);
- // 提现成功...
- return true;
- }
- private function _fail(Order $order, $response)
- {
- $msg = $response['error_msg'] ?? "未知错误";
- $res = Order::updateAll(['status' => 4, 'msg' => $msg, 'updated_at' => time()], ['id' => $order->id]);
- if (!$res) {
- return $this->error("修改订单状态success失败");
- }
- if ($order->type == 2) {
- // 手动打款的,直接返回成功
- return true;
- }
- // 提现打款,要修改提现记录
- $cash = UserWithdrawLog::findOne($order->source_id);
- UserWithdrawLog::remit_fail($cash, $msg);
- // 失败...
- return true;
- }
- public function list($mall_id, $param)
- {
- $name = $param['name'] ?? '';
- $batch_sn = $param['batch_sn'] ?? '';
- $account = $param['account'] ?? '';
- $source_sn = $param['source_sn'] ?? '';
- $limit = $param['limit'] ?? 10;
- $page = $param['page'] ?? 1;
- $type = $param['type'] ?? '';
- $status = $param['status'] ?? '';
- $where[] = ["=", "mall_id", $mall_id];
- $name && $where[] = ["=", "name", $name];
- $batch_sn && $where[] = ["=", "batch_sn", $batch_sn];
- $account && $where[] = ["=", "account", $account];
- $source_sn && $where[] = ["=", "source_sn", $source_sn];
- $type && $where[] = ["=", "type", $type];
- $status && $where[] = ["=", "status", $status];
- $params = array('where' => $where, 'order' => 'created_at desc', 'limit' => $limit);
- $list = Order::listPage($params, false, true);
- return $list;
- // $pagination = new Pagination(['totalCount' => $model->count(), 'pageSize' => $limit]);
- // $model->limit($pagination->limit)->offset($pagination->offset);
- // $list = $model->asArray()
- // ->orderBy('created_at desc')
- // ->all();
- // $data['list'] = $list;
- // $data['page_count'] = $pagination->pageCount;
- // $data['current_page'] = $page + 1;
- // return $data;
- }
- /**
- * 返回前端提现方式
- *
- * @param array $params
- * @return array
- */
- public static function getWithdrawWay($params)
- {
- $mall_id = $params['mall_id'];
- // mall_id为空 后台显示提现方式
- if (empty($mall_id)) return ['alipay' => '支付宝代付'];
- $apply = (new ApplyService())->getApply($mall_id);
- if ($apply && $apply['auth_status'] == 2) {
- return ['alipay' => '支付宝代付'];
- }
- return [];
- }
- public function ereceiptApply($mall_id, Order $order)
- {
- if (empty($order)) throw new \Exception('订单不存在');
- $alipay = new AlipayService($mall_id);
- $request = new AlipayDataBillEreceiptApplyRequest();
- $params = [
- 'type' => 'FUND_DETAIL',
- 'key' => $order->order_id
- ];
- $request->setBizContent(json_encode($params));
- $result = $alipay->getAopClientMall()->execute($request);
- $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
- $resultCode = $result->$responseNode->code;
- if (!empty($resultCode) && $resultCode == 10000) {
- $order->file_id = $result->$responseNode->file_id;
- $order->save();
- return $order->file_id;
- } else {
- throw new \Exception($result->$responseNode->msg);
- }
- }
- public function ereceiptQuery($mall_id, Order $order)
- {
- if (empty($order)) throw new \Exception('订单不存在');
- $alipay = new AlipayService($mall_id);
- $request = new AlipayDataBillEreceiptQueryRequest();
- $params = [
- 'file_id' => $order->file_id,
- ];
- $request->setBizContent(json_encode($params));
- $result = $alipay->getAopClientMall()->execute($request);
- $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
- $resultCode = $result->$responseNode->code;
- $relative_filename = 'alipay/' . $mall_id;
- if (!empty($resultCode) && $resultCode == 10000) {
- $file_name = $order->order_id . '_' . time();
- $absolute_dir = \Yii::getAlias('@attachment') . '/alipay/' . $mall_id . '/';
- $res = CurlHelper::downImgRar($result->$responseNode->download_url, $file_name, 'pdf', $absolute_dir);
- $obj = new CsvTool();
- $url = $obj->upload($mall_id, $relative_filename . '/' . $file_name . '.pdf');
- $order->download_url = $url;
- $order->save();
- unlink($res);
- return $url;
- } else {
- throw new \Exception($result->$responseNode->msg);
- }
- }
- public function fundTransCommonQuery($mall_id, $id)
- {
- try {
- $order = Order::findOne(['mall_id' => $mall_id, 'id' => $id]);
- if (empty($order)) throw new \Exception('订单不存在');
- $alipay = new AlipayService($mall_id);
- $request = new AlipayFundTransCommonQueryRequest();
- $params = [
- 'out_biz_no' => $order->order_sn,
- 'biz_scene' => 'DIRECT_TRANSFER',
- 'product_code' => 'TRANS_ACCOUNT_NO_PWD',
- ];
- $request->setBizContent(json_encode($params));
- $result = $alipay->getAopClientMall()->execute($request);
- $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
- $resultCode = $result->$responseNode->code;
- if (!empty($resultCode) && $resultCode == 10000) {
- $order->order_id = $result->$responseNode->pay_fund_order_id;
- $order->save();
- $this->ereceiptApply($mall_id, $order);
- sleep(1);
- $this->ereceiptQuery($mall_id, $order);
- return $result->$responseNode->pay_fund_order_id;
- } else {
- return $this->error($result->$responseNode->msg);
- }
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- }
- }
|