thinkphp快速对接e签宝平台

<?php
namespace app\home\controller; 
use app\common\logic\UserAddressLogic;
use app\common\logic\GoodsActivityLogic;
use app\common\logic\CouponLogic;
use app\common\logic\IntegralLogic;
use app\common\logic\CartLogic;
use app\common\logic\OrderLogic;
use app\common\logic\PickupLogic;
use app\common\model\SpecGoodsPrice;
use app\common\model\Goods;
use think\Db;

header("Content-type:text/html;charset=utf-8");

//e签宝
class Eqb extends Base {
    
    private $redirectUrl =''; //签属结束后跳转页
    private $notifyUrl =''; //签属回调页
    private $eSignAppId =''; //app id
    private $eSignAppSecret=''; // app key
    private $eSignHost ='https://smlopenapi.esign.cn'; //模拟环境
    private $eSignUpload ='https://esignoss.esign.cn'; //文件流
    // private $eSignUpload ='https://oss.esign.cn'; //模拟环境
    // private $eSignHost ='https://openapi.esign.cn'; //正式环境
    /**
     * 初始化函数
     */
    public function _initialize()
    {
        
    }

    
    //消息回调通知
    public function notifyurl(){
        $data = file_get_contents('php://input');
        file_put_contents('eqb.txt',$data,FILE_APPEND);//追加写入消息日志
        $json = json_decode($data,true);
        if($json['action']=='SIGN_MISSON_COMPLETE' && $json['signResult']==2){
            //签署完成
            $mobile = $json['operator']['psnAccount']['accountMobile'];
            $user = M('users')->where(['mobile'=>$mobile])->save(['eqb_status'=>1]);
        }
        // $json = [
        //   "action" => "SIGN_MISSON_COMPLETE",
        //   "timestamp" => 1718267179875,
        //   "signFlowId" => "46b0609529ad458e8a3eec361e3f87f7",
        //   "customBizNum" => "1718267148",
        //   "signOrder" => 1,
        //   "operateTime" => 1718267179000,
        //   "signResult" => 2,
        //   "resultDescription" => "签署完成",
        //   "operator" => [
        //     "psnId" => "030abcd9221f478e8446600054ed1772",
        //     "psnAccount" => [
        //       "accountMobile" => "15241508811"
        //     ]
        //   ]
        // ];

        // echo 12;die;
    }
    //印章回调通知
    public function notifyyinzhang(){
        $data = file_get_contents('php://input');
        file_put_contents('eqbyinzhang.txt',$data,FILE_APPEND);//追加写入消息日志
        // echo 12;die;
    }
    //展示页面测试
    public function show(){
        return $this->fetch('index/eqb');
    }

    //上传本地文件
    public function upload($filePath='',$fileName=''){
        $url = '/v3/files/file-upload-url';
        $host = $this->eSignHost.'/v3/files/file-upload-url';
        // $filePath = "./esign/平台用户合作协议(青抖云).pdf";
        // 文件Content-MD5值 4wobwYcP/xHBzdaIx4hiuQ==
        $fileContentMD5 = $this->getFileContentMD5($filePath);
        // echo $fileContentMD5;die;
        $content_type = "application/pdf";
        $data = [
            'contentMd5'=>$fileContentMD5,
            'contentType'=>$content_type,
            'convertToPDF'=>false,
            'fileName'=>$fileName,
            'fileSize'=>filesize($filePath)
        ];
        $json = json_encode($data,JSON_UNESCAPED_UNICODE);
        $headers = $this->buildSignedHeaders($this->eSignAppId,$this->eSignAppSecret,'POST', $json, 'application/json; charset=UTF-8', $url);
        $res = $this->sendPost($host,$json,$headers);
        $result = json_decode($res,true);
        if($result['code']==0){
            $fileUploadUrl = $result['data']['fileUploadUrl'];//文件上传地址,链接有效期60分钟
            $fileId = $result['data']['fileId'];//文件id 3d2c5d7691fc4c8081d0e63cbba8adb9
            $headers_put = [
                'Content-MD5:'.$fileContentMD5,
                'Content-Type:'.$content_type,
            ];
            $content_put = file_get_contents($filePath);//文件字节流
            $put = $this->sendPut($fileUploadUrl,$content_put,$headers_put);
            $result_put = json_decode($put,true);
            if($result_put['errCode']==0){
                // echo $fileId.'成功';
                $chom = $this->file_status($fileId);
                if($chom['code'] == 0){
                    return ['code'=>0,'msg'=>'文件ok','data'=>$fileId];
                }else{
                    return ['code'=>1,'msg'=>'文件状态不满足'];
                }
                // ll($chom);
                // return $chom;
            }else{
                // echo 'GG';
                return ['code'=>1,'msg'=>'文件流上传E签宝失败'];
            }
            // ll($headers_put);
            // ll($fileId);
            // ll($put);
        }else{
            return ['code'=>1,'msg'=>'本地文件上传E签宝失败'];
            // echo '文件上传error';
        }
        // ll($result);
    }
    //查询文件状态
    public function file_status($fileId){
        // $fileId = 'a7753f49de694528af12d391fee1c59f';
        $url = '/v3/files/'.$fileId;
        $host = $this->eSignHost.'/v3/files/'.$fileId;
        $content_type = "application/json; charset=UTF-8";
        // $data = [
        //     'fileId'=>$fileId,
        // ];
        // $json = json_encode($data,JSON_UNESCAPED_UNICODE);
        $headers = $this->buildSignedHeaders($this->eSignAppId,$this->eSignAppSecret,'GET', $fileId, 'application/json; charset=UTF-8', $url);
        // ll($headers);die;
        $get = $this->sendGet($host,$headers);
        if($get['code'] == 0){
            if($get['data']['fileStatus'] == 2 || $get['data']['fileStatus']==5){
                return ['code'=>0,'msg'=>'可以使用'];
            }else{
                return ['code'=>1,'msg'=>'查询文件状态错误'];
            }
        }else{
            return ['code'=>1,'msg'=>'查询状态请求失败'];
        }
        // ll($get);
    }
    //创建签属
    public function create(){
        $arr = I('post.');
        // $signFlowExpireTime = round(microtime(true) * 1000 + 86400);//流程过期时间
        $user_id = input('user_id',6085);
        $user = M('users')->field('username,mobile,eqb_link,eqb_status')->where(['user_id'=>$user_id])->find();
        if(empty($user)){
            $this->ajaxReturn(['code'=>1,'msg'=>'登录失效']);
        }
        //判断是否有链接
        if(!empty($user['eqb_link']) && $user['eqb_status']==0){
            //未签约用户中途退出 重新拉起签署链接
            $this->ajaxReturn(['code'=>0,'msg'=>'可以使用','data'=>['url'=>$user['eqb_link']]]);
        }
        $mobile = $user['mobile'];
        $username =  $user['username'];
        //查询模板页码数
        $fileId = M('config')->where(['name'=>'eqb_fileid','inc_type'=>'eqb'])->getField('value');
        $fileName = M('config')->where(['name'=>'eqb_filename','inc_type'=>'eqb'])->getField('value');
        
        if(empty($fileId) || empty($fileName)){
            $this->ajaxReturn(['code'=>1,'msg'=>'模板合同不存在,请联系管理员']);
        }
        $page = M('config')->where(['name'=>'eqb_page','inc_type'=>'eqb'])->getField('value');
        $positionx = M('config')->where(['name'=>'eqb_positionx','inc_type'=>'eqb'])->getField('value');
        $positiony = M('config')->where(['name'=>'eqb_positiony','inc_type'=>'eqb'])->getField('value');
        // ll($fileName);
        // ll($fileId);die;
        $url = '/v3/sign-flow/create-by-file';
        $host = $this->eSignHost.$url;
        $content_type = "application/json; charset=UTF-8";
        $data = [
          "docs" => [
            "0" => [
              "fileId" => $fileId,
              "fileName" => $fileName
            ]
          ],
          "signFlowConfig" => [
            "signFlowTitle" => "平台用户合作协议",
            "autoFinish" => true,
            "notifyUrl" => $this->notifyUrl,
            "redirectConfig" => [
              "redirectUrl" => $this->redirectUrl,
            ]
          ],
          "signers" => [
            "0" => [
              "signConfig" => [
                "signOrder" => 1
              ],
              "noticeConfig" => [
                "noticeTypes" => ""
              ],
              "signerType" => 0,
              "psnSignerInfo" => [
                "psnAccount" => $mobile,
                "psnInfo" => [
                  "psnName" => $username
                ]
              ],
              "signFields" => [
                "0" => [
                  "customBizNum" => time(),
                  "fileId" => $fileId,//20240612截至123
                  "normalSignFieldConfig" => [
                    "signFieldStyle" => 1,
                    "signFieldPosition" => [
                      "positionPage" =>$page,
                      "positionX" => $positionx,
                      "positionY" => $positiony
                    ]
                  ]
                ]
              ]
            ],
            // "1" => [
            //   "signConfig" => [
            //     "signOrder" => 2
            //   ],
            //   "signerType" => 1,
            //   "signFields" => [
            //     "0" => [
            //       "customBizNum" => time(),
            //       "fileId" => $fileId,
            //       "normalSignFieldConfig" => [
            //         "autoSign" =>false ,
            //         "signFieldStyle" => 1,
            //         "signFieldPosition" => [
            //           "positionPage" => "1",
            //           "positionX" => 458,
            //           "positionY" => 200
            //         ]
            //       ]
            //     ]
            //   ]
            // ]
          ]
        ];
        $json = json_encode($data,JSON_UNESCAPED_UNICODE);
        // ll($data);die;
        $headers = $this->buildSignedHeaders($this->eSignAppId,$this->eSignAppSecret,'POST', $json, 'application/json; charset=UTF-8', $url);
        // ll($json);
        // ll($headers);
        $post = $this->sendPost($host,$json,$headers);
        $res = json_decode($post,true);
        if($res['code'] == 0){
            $signFlowId = $res['data']['signFlowId'];//签属id
            
            //调用获取签署链接
            $geturl = $this->get_url($signFlowId,$mobile);
            if($geturl['code']==0){
                //客户存储
                $eqb_link = $geturl['data']['url'];//签署跳转链接
                $user_change = M('users')->where(['user_id'=>$user_id])->save(['eqb_flowid'=>$signFlowId,'eqb_link'=>$eqb_link]);
                if(!$user_change){
                     $this->ajaxReturn(['code'=>1,'msg'=>'用户签约流程ID存储失败']);
                }
                $this->ajaxReturn(['code'=>0,'msg'=>'可以使用','data'=>$geturl['data']]);
            }else{
                $this->ajaxReturn(['code'=>1,'msg'=>$geturl['msg']]);
            }
        }else{
            $this->ajaxReturn(['code'=>1,'msg'=>'创建签署请求失败']);
        }
        //res['data'] =  {"signFlowId":"83d4e4ae063046a08b3ba5950a224560"}}"
    }
    //获取签签署页链接
    public function get_url($signFlowId='',$mobile=''){
        $url = '/v3/sign-flow/'.$signFlowId.'/sign-url';
        $host = $this->eSignHost.$url;
        $data = [
            "clientType" => "ALL",
            "needLogin" => false,
            "operator" => [
                "psnAccount" => $mobile
            ],
            "redirectConfig"=>[
                "redirectUrl"=>$this->redirectUrl,
                "redirectDelayTime"=>0,
            ],
            "urlType" => 2
        ];

        $json = json_encode($data,JSON_UNESCAPED_UNICODE);
        // ll($data);die;
        $headers = $this->buildSignedHeaders($this->eSignAppId,$this->eSignAppSecret,'POST', $json, 'application/json; charset=UTF-8', $url);
        // ll($json);
        // ll($headers);
        $post = $this->sendPost($host,$json,$headers);
        $res = json_decode($post,true);
        // ll($res);
        if($res['code'] == 0){
            return ['code'=>0,'data'=>$res['data']];
        }else{
            return ['code'=>1,'msg'=>'签署连接请求失败'];
        }
    }





    

    public function getFileContentMD5($filePath){
        //获取文件MD5的128位二进制数组
        $md5Bytes = md5_file($filePath,true);
        //计算文件的Content-MD5
        $contentMD5 = base64_encode($md5Bytes);
        return $contentMD5;
    }


    public function getContentMd5($bodyData){
        //计算Body体的Content-MD5
        $md5Bytes = md5($bodyData,true);
        $contentMD5 = base64_encode($md5Bytes);
        return $contentMD5;
    }
    //创建签名
    public function getSignature( $method, $content_md5,  $content_type,  $uri,  $app_secret){
        $string = "$method\n*/*\n$content_md5\n$content_type\n\n$uri";
        return base64_encode(hash_hmac('sha256', $string, $app_secret, true));
    }
    //创建请求头
    public function buildSignedHeaders($app_id, $app_secret, $method,  $body,  $content_type,  $uri){
        $contentMd5 = '';
        if (in_array($method, ['GET', 'DELETE'])) {
            $content_type = '';
        } else {
            $contentMd5 = $this->getContentMd5($body);
        }
        $header = [
            'Accept' => '*/*',
            'Content-MD5' => $contentMd5,
            'Content-Type' => $content_type,
            'X-Tsign-Open-App-Id' => $app_id,
            'X-Tsign-Open-Auth-Mode' => 'Signature',
            'X-Tsign-Open-Ca-Signature' => $this->getSignature($method, $contentMd5, $content_type, $uri, $app_secret),
            'X-Tsign-Open-Ca-Timestamp' => round(microtime(true) * 1000),
        ];
        $headers = [];
        foreach ($header as $k => $v) {
            array_push($headers,$k.':'.$v);
        }
        return $headers;
    }
    // public function getMillisecond(): float {
    //     [$t1, $t2] = explode(' ', microtime());
    //     return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    // }
    
    public function sendGet($url,$headers=[]){
        //用curl传参
        $ch = curl_init();
        if (count($headers) >= 1) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        //关闭ssl验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);


        curl_setopt($ch,CURLOPT_HEADER, 0);
        $output = curl_exec($ch);
        curl_close($ch);
        return json_decode($output, true);
    }

    //curl请求
    public function sendPost($url,$data = null,$headers = array()){
        $curl = curl_init();
        // $headers = [
        //     'Accept: application/json',
        //     'Content-Type: application/json',
        //     'User-Agent: My User Agent String'
        // ];
        if (count($headers) >= 1) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 跳过证书检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    public function sendPut($url,$data,$header){
        $curl = curl_init(); 
        curl_setopt($curl, CURLOPT_URL, $url); //定义请求地址
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); //
        curl_setopt($curl, CURLOPT_HEADER,0); //定义是否显示状态头 1:显示 ; 0:不显示 
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);//定义header
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);//定义是否直接输出返回流 
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //定义提交的数据
        $tmpInfo = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno'.curl_error($curl);
        }
        curl_close($curl); // 关键CURL会话
        return $tmpInfo; // 返回数据
    }
}

一把梭直接控制器拼接请求头快速调用,回调和模板上传需要自己写逻辑套用路径即可,印章定位需要根据平台工具操作获取签章位置-e签宝-电子签名|电子合同|专业电子签约云平台

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值