| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\modules\admin\models;
- use app\models\Option;
- use app\models\Store;
- use app\models\StoreMini;
- use app\models\StoreMiniAuth;
- use app\utils\CurlHelper;
- use app\utils\QrCode;
- use app\utils\Wechat\WechatMini;
- use EasyWeChat\BasicService\Media\Client;
- use EasyWeChat\Kernel\BaseClient;
- use yii\base\Model;
- use yii\helpers\ArrayHelper;
- class WechatThirdAuthForm extends Model
- {
- public $auth_data;
- public $baseClient;
- // public $customer_type; //身份类型企业为1,个体工商户 为12,个人是15
- //
- // public $taskid; //认证任务id,打回重审调用reauth时为必填
- //
- // public $name; //认证联系人姓名
- //
- // public $email; //认证联系人邮箱
- //
- // public $invoice_type; //发票类型 1: 不开发票 2: 电子发票 3: 增值税专票
- //
- // public $invoice_id; //纳税识别号(15位、17、18或20位)
- //
- // public $desc; //发票备注(选填)
- //
- // public $enterprise_phone; //企业电话
- //
- // public $enterprise_address; //企业注册地址
- //
- // public $bank_name; //企业开户银行
- //
- // public $bank_account; //企业银行账号
- //
- // public $mailing_address; //发票邮寄地址邮编
- //
- // public $address; //街道地址
- //
- // public $phone; //联系电话
- //
- // public $province; //省份
- //
- // public $city; //城市
- //
- // public $district; //县区
- //
- // public $invoice_title; //发票抬头,需要和认证主体名称一样
- //
- // public $qualification; //非个人类型必填。主体资质材料 media_id 支持jpg,jpeg .bmp.gif .png格式,仅支持一张图片
- //
- // public $qualification_other; //主体资质其他证明材料 media_id 支持jpg,jpeg .bmp.gif .png格式,最多上传10张图片
- //
- // public $account_name; //小程序账号名称
- //
- // public $account_name_type; //小程序账号名称命名类型 1:基于自选词汇命名 2:基于商标命名
- //
- // public $account_supplemental; //名称命中关键词-补充材料 media_id 支持jpg,jpeg .bmp.gif .png格式,支持上传多张图片
- //
- // public $pay_type; //支付方式 1:消耗服务商预购包 2:小程序开发者自行支付
- //
- // public $third_party_phone; //第三方联系电话
- //
- // public $service_appid; //选择服务商代缴模式时必填。服务市场appid,该服务市场账号主体必须与服务商账号主体一致
- public $mini_id; //小程序id
- public $store_id;
- public function rules()
- {
- return [
- [['customer_type', 'invoice_type', 'account_name_type', 'pay_type', 'mini_id', 'store_id'], 'integer'],
- [['taskid', 'name', 'email', 'invoice_id', 'desc', 'enterprise_phone', 'enterprise_address', 'bank_name',
- 'bank_account', 'mailing_address', 'address', 'phone', 'province', 'city', 'district', 'invoice_title',
- 'qualification', 'qualification_other', 'account_name', 'account_supplemental', 'third_party_phone', 'service_appid'
- ], 'string'],
- [['auth_data'], 'safe']
- ];
- }
- // 提交申请
- public function applyWxaauth() {
- // $t = \Yii::$app->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;
- }
- }
|