db->beginTransaction(); try { $app = WechatMini::getWechatConfig($this->store_id, $this->mini_id); if (!$app) { throw new \Exception('小程序信息未找到'); } $this->baseClient = $baseClient = new BaseClient($app); $mini = StoreMini::findOne($this->mini_id); if (!$mini) { throw new \Exception('小程序信息查询失败'); } $store = Store::findOne($this->store_id); if (!$store) { throw new \Exception('商城信息查询失败'); } $data = $this->auth_data ?: [ 'customer_type' => 1, 'taskid' => '', 'contact_info' => [ 'name' => '', 'email' =>'' ], 'invoice_info' => [ 'invoice_type' => 2, 'electronic' => [ 'id' => '', 'desc' => '' ], 'vat' => [ 'enterprise_phone' => '', 'id' => '', 'enterprise_address' => '', 'bank_name' => '', 'bank_account' => '', 'mailing_address' => '', 'address' => '', 'name' => '', 'phone' => '', 'province' => '', 'city' => '', 'district' => '', 'desc' => '', ], 'invoice_title' => '', ], 'qualification' => [ 'media_id' => '', 'url' => '' ], 'qualification_other' => [ [ 'media_id' => '', 'url' => '' ] ], 'account_name' => $mini->mini_nickname, 'account_name_type' => 1, 'account_supplemental' => [ [ 'media_id' => '', 'url' => '' ] ], 'pay_type' => StoreMiniAuth::PAY_TYPE_SELF, 'third_party_phone' => Option::get("platform_phone", 0, 'saas')['value'], 'service_appid' => Option::get("platform_wechat_fuwu_appid", 0, 'saas')['value'] ]; if (isset($data['third_party_phone']) && empty($data['third_party_phone'])) { $data['third_party_phone'] = Option::get("platform_phone", 0, 'saas')['value']; } else { $data = array_merge($data, ['third_party_phone' => Option::get("platform_phone", 0, 'saas')['value']]); } if (intval($data['pay_type']) === StoreMiniAuth::PAY_TYPE_SERVICE) { if ($store->mini_auth_num <= 0) { throw new \Exception('当前商城认证代缴次数不足,请联系平台管理员'); } if (isset($data['service_appid']) && empty($data['service_appid'])) { $data['service_appid'] = Option::get('platform_wechat_fuwu_appid', 0, 'saas', '')['value']; } else { $data = array_merge($data, ['service_appid' => Option::get('platform_wechat_fuwu_appid', 0, 'saas', '')['value']]); } } $mini_auth = StoreMiniAuth::findOne(['store_id' => $this->store_id, 'mini_id' => $this->mini_id]) ?: new StoreMiniAuth(); $mini_auth->store_id = $this->store_id; $mini_auth->mini_id = $this->mini_id; if ($mini_auth->task_id) { $apply_status = intval($mini_auth->apply_status); if ($apply_status === 5) {//猜测如果已经认证最终失败,则不能重新调用重新提审接口,只能重新开始认证 if (isset($data['taskid'])) { unset($data['taskid']); } } else { $data['taskid'] = $mini_auth->task_id; } } else { unset($data['taskid']); } if (isset($data['task_id'])) { unset($data['task_id']); } $mini_auth->auth_form = json_encode($data, JSON_UNESCAPED_UNICODE); if (!$mini_auth->save()) { throw new \Exception(json_encode($mini_auth->errors, JSON_UNESCAPED_UNICODE)); } if (!in_array($data['customer_type'], [1, 12])) { throw new \Exception('身份类型枚举值错误'); } // 支付方式 if (!in_array($data['pay_type'], [StoreMiniAuth::PAY_TYPE_SERVICE, StoreMiniAuth::PAY_TYPE_SELF])) { throw new \Exception('支付方式枚举值错误'); } if (intval($data['pay_type']) === StoreMiniAuth::PAY_TYPE_SERVICE) {//支付方式 1:消耗服务商预购包 //发票信息,如果是服务商代缴模式,不需要改参数 // unset($data['invoice_info']); $data['invoice_info']['invoice_type'] = 1; if (empty($data['service_appid'])) { throw new \Exception('请选择服务市场appid'); } } else { // 发票类型 if (!in_array($data['invoice_info']['invoice_type'], [1, 2, 3])) { throw new \Exception('发票类型枚举值错误'); } } //不开发票 if (intval($data['invoice_info']['invoice_type']) === 1) { unset($data['invoice_info']['vat'], $data['invoice_info']['electronic']); } // 电子发票 if (intval($data['invoice_info']['invoice_type']) === 2) { // 未填写电子发票开票信息 if (empty($data['invoice_info']['electronic'])) { throw new \Exception('未填写电子发票开票信息'); } // 未填写电子发票纳税识别号 if (empty($data['invoice_info']['electronic']['id'])) { throw new \Exception('未填写电子发票纳税识别号'); } unset($data['invoice_info']['vat']); } // 增值税专票 if (intval($data['invoice_info']['invoice_type']) === 3) { $data['invoice_info']['invoice_type'] = 4; // 未填写电子发票开票信息 if (empty($data['invoice_info']['vat'])) { throw new \Exception('未填写增值税专票开票信息'); } // 未填写企业电话 if (empty($data['invoice_info']['vat']['enterprise_phone'])) { throw new \Exception('未填写企业电话'); } // 未填写电子发票纳税识别号 if (empty($data['invoice_info']['vat']['id'])) { throw new \Exception('未填写增值税专票纳税识别号'); } // 未填写企业注册地址 if (empty($data['invoice_info']['vat']['enterprise_address'])) { throw new \Exception('未填写企业注册地址'); } // 未填写企业开户银行 if (empty($data['invoice_info']['vat']['bank_name'])) { throw new \Exception('未填写企业开户银行'); } // 未填写企业银行账号 if (empty($data['invoice_info']['vat']['bank_account'])) { throw new \Exception('未填写企业银行账号'); } // 未填写发票邮寄地址邮编 if (empty($data['invoice_info']['vat']['mailing_address'])) { throw new \Exception('未填写发票邮寄地址邮编'); } // 未填写街道地址 if (empty($data['invoice_info']['vat']['address'])) { throw new \Exception('未填写街道地址'); } // 未填写联系人 if (empty($data['invoice_info']['vat']['name'])) { throw new \Exception('未填写联系人'); } // 未填写联系电话 if (empty($data['invoice_info']['vat']['phone'])) { throw new \Exception('未填写联系电话'); } // 未填写省份 if (empty($data['invoice_info']['vat']['province'])) { throw new \Exception('未填写省份'); } // 未填写城市 if (empty($data['invoice_info']['vat']['city'])) { throw new \Exception('未填写城市'); } // 未填写县区 if (empty($data['invoice_info']['vat']['district'])) { throw new \Exception('未填写县区市'); } unset($data['invoice_info']['electronic']); } // 主体资质材料 if (!empty($data['qualification'])) { if (!empty($data['qualification']['url'])) { $media_result = $this->updateMedia($data['qualification']['url']); if (empty($media_result['media_id'])) { throw new \Exception($media_result['msg']); } $data['qualification'] = $media_result['media_id']; } else { throw new \Exception('未填写主体资质材料'); } } else { throw new \Exception('未填写主体资质材料'); } // 主体资质其他证明材料 if (!empty($data['qualification_other'])) { $qualification_other = []; foreach ($data['qualification_other'] as $media_item) { if (!empty($media_item['url'])) { $media_result = $this->updateMedia($media_item['url']); if (empty($media_result['media_id'])) { throw new \Exception($media_result['msg']); } array_push($qualification_other, $media_result['media_id']); } else { array_push($qualification_other, ''); } } if (!empty($qualification_other)) { $data['qualification_other'] = $qualification_other; } } // 小程序账号名称 if (empty($data['account_name'])) { throw new \Exception('需要填写小程序账号名称'); } // 小程序账号名称命名类型 if (!in_array($data['account_name_type'], [1, 2])) { throw new \Exception('小程序账号名称命名类型枚举值错误'); } // 名称命中关键词-补充材料 if (!empty($data['account_supplemental'])) { $account_supplemental = []; foreach ($data['account_supplemental'] as $media_item) { if (!empty($media_item['url'])) { $media_result = $this->updateMedia($media_item['url']); if (empty($media_result['media_id'])) { throw new \Exception($media_result['msg']); } array_push($account_supplemental, $media_result['media_id']); } else { array_push($account_supplemental, ''); } } if (!empty($account_supplemental)) { $data['account_supplemental'] = $account_supplemental; } } // 第三方联系电话 if (empty($data['third_party_phone'])) { throw new \Exception('需要填写第三方联系电话'); } $url = 'wxa/sec/wxaauth'; if (isset($data['taskid'])) { $url = 'wxa/sec/reauth'; } $result = $baseClient->httpPostJson($url, ['auth_data' => $data]); if (empty($result['errcode']) && !empty($result)) { debug_log(['old_task_id' => $mini_auth->task_id, 'task_id' => $result['taskid'], 'result' => $result], 'wxaaut.log'); if ($result['taskid']) { $mini_auth->task_id = $result['taskid']; } $mini_auth->auth_url = $result['auth_url']; $url = $result['auth_url']; if ($url) { $pic_url = $this->setPicUrl($url, $mini_auth->id); debug_log(['pic_url' => $pic_url], 'wxaaut.log'); $mini_auth->pic_url = $pic_url; } if (intval($data['pay_type']) === StoreMiniAuth::PAY_TYPE_SERVICE) { $store->mini_auth_num -= 1; if (!$store->save()) { debug_log(['errors' => $store->errors], 'wechatAuth.log'); } $mini_auth->is_use_service = 1; } if (!$mini_auth->save()) { throw new \Exception(json_encode($mini_auth->errors, JSON_UNESCAPED_UNICODE)); } // $t->commit(); return [ 'code' => 0, 'msg' => "成功", 'data' => [ 'auth_url' => $result['auth_url'] ] ]; } else { throw new \Exception($result['errmsg'], $result['errcode']); } } catch (\Exception $e) { // $t->rollBack(); return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } public function setPicUrl($auth_url, $id) { $filename = md5(date('Ym') . 'mini_auth' . $id); $path = \Yii::$app->runtimePath . '/image/' . $filename . '.jpg'; $pic_url = str_replace('http://', 'https://', \Yii::$app->request->hostInfo . '/runtime/image/' . $filename . '.jpg'); QrCode::image($auth_url, 500, false, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, false, $path); return $pic_url; } // 获取信息 public function getApplyData() { try { $mini = StoreMini::findOne($this->mini_id); if (!$mini) { throw new \Exception('小程序信息查询失败'); } $data = [ 'customer_type' => 1, 'taskid' => '', 'contact_info' => [ 'name' => '', 'email' =>'' ], 'pay_type' => 2, 'invoice_info' => [ 'invoice_type' => 2, 'electronic' => [ 'id' => '', 'desc' => '' ], 'vat' => [ 'enterprise_phone' => '', 'id' => '', 'enterprise_address' => '', 'bank_name' => '', 'bank_account' => '', 'mailing_address' => '', 'address' => '', 'name' => '', 'phone' => '', 'province' => '', 'city' => '', 'district' => '', 'desc' => '', ], 'invoice_title' => '', ], 'qualification' => [ 'media_id' => '', 'url' => '' ], 'qualification_other' => [ [ 'media_id' => '', 'url' => '' ] ], 'account_name' => $mini->mini_nickname, 'account_name_type' => 1, 'account_supplemental' => [ [ 'media_id' => '', 'url' => '' ] ], 'third_party_phone' => Option::get("platform_phone", 0, 'saas')['value'], 'service_appid' => Option::get("platform_third_appid", 0, 'saas')['value'] ]; $mini_auth = StoreMiniAuth::findOne(['store_id' => $this->store_id, 'mini_id' => $this->mini_id]); $is_edit = 1; $pic_url = ''; if ($mini_auth) { $is_edit = 0; $this->getTaskStatus($mini_auth); $auth_form = json_decode($mini_auth->auth_form, JSON_UNESCAPED_UNICODE); if ($auth_form) { $data = json_decode($mini_auth->auth_form, true); } $task_status = $mini_auth->task_status; if (in_array($task_status, [-1, 1, 2, 5, 8, 11, 14])) { $is_edit = 1; } $apply_status = intval($mini_auth->apply_status); if (in_array($apply_status, [3, 5])) { $is_edit = 1; } if (!$mini_auth->pic_url && !empty($mini_auth->auth_url)) { $pic_url = $this->setPicUrl($mini_auth->auth_url, $mini_auth->id); $mini_auth->pic_url = $pic_url; $mini_auth->save(); } else { $pic_url = $mini_auth->pic_url; // if (!file_exists($pic_url)) { // QrCode::image($pic_url, 500, false, 'L', 'JPEG', 0, ['255,255,255', '0,0,0'], 1, false, $path); // } } } return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'auth_data' => $data, 'message' => $mini_auth->task_message ?: '', 'auth_url' => $pic_url ?: '', 'apply_status' => intval($mini_auth->apply_status) ?: 0, 'task_status' => intval($mini_auth->task_status) ?: -1, 'is_edit' => $is_edit ] ]; } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } // 认证进度查询 private function getTaskStatus(&$mini_auth) { try { $app = WechatMini::getWechatConfig($this->store_id, $this->mini_id); $baseClient = new BaseClient($app); if (!$mini_auth || empty($mini_auth->task_id)) { $mini_auth->auth_url = ''; $mini_auth->pic_url = ''; $mini_auth->save(); throw new \Exception('未找到申请认证信息'); } $result = $baseClient->httpPostJson('wxa/sec/queryauth', ['taskid' => $mini_auth->task_id]); if (empty($result['errcode']) && !empty($result)) { $mini_auth->task_status = (int)$result['task_status']; $mini_auth->apply_status = (int)$result['apply_status']; $task_message = ''; if ($result['apply_status'] < 2) { switch ($result['task_status']) { case 1: $task_message = "任务超时,24小时内有效"; break; case 2: $task_message = "用户授权拒绝"; break; case 3: $task_message = "用户授权同意"; break; case 4: $task_message = "发起人脸流程"; break; case 5: $task_message = "人脸认证失败"; break; case 6: $task_message = "人脸认证成功"; break; case 7: $task_message = "人脸认证后,已经提交手机号码下发验证码"; break; case 8: $task_message = "手机验证失败"; break; case 9: $task_message = "手机验证成功"; break; case 11: $task_message = "创建认证审核单失败"; break; case 12: $task_message = "创建认证审核单成功"; break; case 14: $task_message = "验证失败"; break; case 15: $task_message = "等待支付"; break; } } else { switch ($result['apply_status']) { case 2: $task_message = "审核中"; break; case 3: $task_message = "打回重填:" . $result['refill_reason']; break; case 4: $task_message = "认证通过"; break; case 5: $task_message = "认证最终失败:" . $result['fail_reason']; break; } } if (in_array($result['task_status'], [1, 2, 5, 8, 11, 14]) || in_array($result['apply_status'], [3, 5])) { if ($mini_auth->is_use_service) { $mini_auth->is_use_service = 0; $store = Store::findOne($this->store_id); if (!$store) { throw new \Exception('店铺不存在'); } $store->mini_auth_num += 1; if (!$store->save()) { throw new \Exception(json_encode($store->errors, JSON_UNESCAPED_UNICODE)); } } } $mini_auth->task_message = $task_message; if (!$mini_auth->save()) { throw new \Exception(json_encode($mini_auth->errors, JSON_UNESCAPED_UNICODE)); } return [ 'code' => 0, 'msg' => "更新成功" ]; } else { return [ 'code' => $result['errcode'], 'msg' => $result['errmsg'] ]; } } catch (\Exception $e) { return [ 'code' => 0, 'msg' => $e->getMessage() ]; } } /** * @param $local_media_url * @return array * 获取media_id */ public function updateMedia($local_media_url) { try { $baseClient = $this->baseClient; $result = $baseClient->httpUpload('wxa/sec/uploadauthmaterial', [ 'media' => $this->saveTempImage($local_media_url) ]); if (empty($result['errcode']) && !empty($result)) { return [ 'code' => 0, 'msg' => "成功", 'media_id' => $result['mediaid'] ]; } else { return [ 'code' => $result['errcode'], 'msg' => $result['errmsg'] ]; } } catch (\Exception $e) { return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } //获取网络图片到临时目录 private function saveTempImage($url) { if (strpos($url, 'http') === false) { $url = 'http:' . trim($url); } if (!is_dir(\Yii::$app->runtimePath . '/image')) { mkdir(\Yii::$app->runtimePath . '/image'); } $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg'; CurlHelper::download($url, $save_path); return $save_path; } }