微信小程序 第三方平臺(tái)授權(quán)小程序業(yè)務(wù)

image

第一步:申請(qǐng)微信開(kāi)放平臺(tái)帳號(hào)并創(chuàng)建第三方平臺(tái)

image.png

image.png

image.png

image.png

第二步:公眾號(hào)/小程序授權(quán)給第三方平臺(tái)

<?php

// 微信第三方平臺(tái)授權(quán)流程
namespace app\home\controller;
class Weixin extends Common{

    private $appid = 'wx3e******165c';            
    //第三方平臺(tái)應(yīng)用appid

    private $appsecret = '13e**********d039';     
    //第三方平臺(tái)應(yīng)用appsecret

    private $token = 'ePF58******Q2Ae';          
    //第三方平臺(tái)應(yīng)用token(消息校驗(yàn)Token)

    private $encodingAesKey = 'bzH***FCamD';      
    //第三方平臺(tái)應(yīng)用Key(消息加解密Key)

    private $component_ticket= 'ticket@**xv-g';   
    //微信后臺(tái)推送的ticket,用于獲取第三方平臺(tái)接口調(diào)用憑據(jù)

    /*
    * 掃碼授權(quán)嘉汰,注意此URL必須放置在頁(yè)面當(dāng)中用戶點(diǎn)擊進(jìn)行跳轉(zhuǎn),
    * 不能通過(guò)程序跳轉(zhuǎn)檀夹,否則將出現(xiàn)“請(qǐng)確認(rèn)授權(quán)入口頁(yè)所在域名骡男,
    * 與授權(quán)后回調(diào)頁(yè)所在域名相同....”錯(cuò)誤
    * @params string $redirect_uri : 掃碼成功后的回調(diào)地址
    * @params int $auth_type : 授權(quán)類型判导,1公眾號(hào)纫塌,2小程序,
    * 3公眾號(hào)/小程序同時(shí)展現(xiàn)桨昙。不傳參數(shù)默認(rèn)都展示    
    */
    public function startAuth($redirect_uri,$auth_type = 3){
        $url = "https://mp.weixin.qq.com/cgi-bin/componentloginpage
                ?component_appid=".$this->appid."
                &pre_auth_code=".$this->get_pre_auth_code()."
                &redirect_uri=".urlencode($redirect_uri)."
                &auth_type=".$auth_type;
        return $url;
    }

    /*
    * 獲取第三方平臺(tái)access_token
    * 注意检号,此值應(yīng)保存腌歉,代碼這里沒(méi)保存
    */
    private function get_component_access_token(){
        $url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
        $data = '{
            "component_appid":"'.$this->appid.'" ,
            "component_appsecret": "'.$this->appsecret.'",
            "component_verify_ticket": "'.$this->component_ticket.'"
        }';
        $ret = json_decode($this->https_post($url,$data));
        if($ret->errcode == 0) {
            return $ret->component_access_token;
        } else {
            return $ret->errcode;
        }
    }

    /*
    *  第三方平臺(tái)方獲取預(yù)授權(quán)碼pre_auth_code
    */
    private function get_pre_auth_code(){
        $url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode
                ?component_access_token=".$this->get_component_access_token();
        $data = '{"component_appid":"'.$this->appid.'"}';
        $ret = json_decode($this->https_post($url,$data));
        if($ret->errcode == 0) {
            return $ret->pre_auth_code;
        } else {
            return $ret->errcode;
        }
    }

    /*
    * 發(fā)起POST網(wǎng)絡(luò)提交
    * @params string $url : 網(wǎng)絡(luò)地址
    * @params json $data : 發(fā)送的json格式數(shù)據(jù)
    */
    private function https_post($url,$data){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        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;
    }

    /*
    * 發(fā)起GET網(wǎng)絡(luò)提交
    * @params string $url : 網(wǎng)絡(luò)地址
    */
    private function https_get($url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
        curl_setopt($curl, CURLOPT_HEADER, FALSE) ; 
        curl_setopt($curl, CURLOPT_TIMEOUT,60);
        if (curl_errno($curl)) {
            return 'Errno'.curl_error($curl);
        }else{
            $result = curl_exec($curl);
        }
        curl_close($curl);
        return $result;
    }
}
<?php

/*
*    接收微信官方推送的ticket值以及取消授權(quán)等操作
*/
namespace app\home\controller;
use think\Db;
class Openoauth extends Common{

    private $appid = 'wx3e******165c';            
    //第三方平臺(tái)應(yīng)用appid

    private $appsecret = '13e**********d039';     
    //第三方平臺(tái)應(yīng)用appsecret

    private $token = 'ePF58******Q2Ae';           
    //第三方平臺(tái)應(yīng)用token(消息校驗(yàn)Token)

    private $encodingAesKey = 'bzH***FCamD';      
    //第三方平臺(tái)應(yīng)用Key(消息加解密Key)

    private $component_ticket= 'ticket@**xv-g';   
    //微信后臺(tái)推送的ticket,用于獲取第三方平臺(tái)接口調(diào)用憑據(jù)

    /*
    * 接收微信官方推送的消息(每10分鐘1次)
    * 這里需要引入微信官方提供的加解密碼示例包
    * 官方文檔:https://open.weixin.qq.com/cgi-bin/showdocument
    * ?action=dir_list&t=resource/res_list&verify=1&id=open1419318479&token=&lang=zh_CN
    * 示例包下載:https://wximg.gtimg.com/shake_tv/mpwiki/cryptoDemo.zip
    */
    public function index(){
        $encryptMsg = file_get_contents("php://input");
        $xml_tree = new \DOMDocument();
        $xml_tree->loadXML($encryptMsg);
        $xml_array = $xml_tree->getElementsByTagName("Encrypt");
        $encrypt = $xml_array->item(0)->nodeValue;
        require_once('wxBizMsgCrypt.php');
        $Prpcrypt = new \Prpcrypt($this->encodingAesKey);
        $postData = $Prpcrypt->decrypt($encrypt, $this->appid);
        if ($postData[0] != 0) {
            return $postData[0];
        } else {
            $msg = $postData[1];
            $xml = new \DOMDocument();
            $xml->loadXML($msg);
            $array_a = $xml->getElementsByTagName("InfoType");
            $infoType = $array_a->item(0)->nodeValue;
            if ($infoType == "unauthorized") {
                //取消公眾號(hào)/小程序授權(quán)
                $array_b = $xml->getElementsByTagName("AuthorizerAppid");
                $AuthorizerAppid = $array_b->item(0)->nodeValue;    
                //公眾號(hào)/小程序appid
                $where = array("type" => 1, "appid" => $AuthorizerAppid);
                $save = array(
                    "authorizer_access_token" => "", 
                    "authorizer_refresh_token" => "", 
                    "authorizer_expires" => 0
                );
                Db::name("wxuser")->where($where)->update($save);   
                //公眾號(hào)取消授權(quán)
                Db::name("wxminiprograms")
                ->where('authorizer_appid',$AuthorizerAppid)
                ->update($save);
                //小程序取消授權(quán)
            } else if ($infoType == "component_verify_ticket") {
                //微信官方推送的ticket值
                $array_e = $xml->getElementsByTagName("ComponentVerifyTicket");
                $component_verify_ticket = $array_e->item(0)->nodeValue;
                $result = Db::name("weixin_account")
                ->where(array("type" => 1))
                ->update(
                    array(
                        "component_verify_ticket" => $component_verify_ticket, 
                        "date_time" => time()
                    )
                );
                if ($result) {
                    $this->updateAccessToken($component_verify_ticket);
                    echo "success";
                }
            }
        }
    }

    /*
     * 更新component_access_token
     * @params string $component_verify_ticket
     * */
    private function updateAccessToken($component_verify_ticket){
        $weixin_account = Db::name('weixin_account')
        ->where(['type'=>1])
        ->field('id,appId,appSecret,component_access_token,token_expires')
        ->find();
        if($weixin_account['token_expires'] <= time() ) {
            $apiUrl = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
            $data = '{
                "component_appid":"'.$weixin_account['appId'].'" ,
                "component_appsecret": "'.$weixin_account['appSecret'].'",
                "component_verify_ticket": "'.$component_verify_ticket.'"
            }';
            $json = json_decode(_request($apiUrl,$data));
            if(isset($json->component_access_token)) {
                Db::name('weixin_account')
                ->where(['id'=>$weixin_account['id']])
                ->update(
                    [
                        'component_access_token'=>$json->component_access_token,
                        'token_expires'=>time()+7200
                    ]
                );
            }
        }
    }
}
<?php

/*
*    代小程序?qū)崿F(xiàn)業(yè)務(wù)
*/
namespace app\home\model;
use think\Model;
use think\Db;
use think\Cache;
class Miniprogram extends Model{

    private $thirdAppId;        
    //開(kāi)放平臺(tái)appid

    private $encodingAesKey;    
    //開(kāi)放平臺(tái)encodingAesKey

    private $thirdToken;        
    //開(kāi)放平臺(tái)token

    private $thirdAccessToken;  
    //開(kāi)放平臺(tái)access_token

    private $authorizer_appid;

    private  $authorizer_access_token;

    private  $authorizer_refresh_token;

    public function __construct($appid){
        $weixin_account = Db::name('weixin_account')
        ->where(['type' => 1])
        ->field('token,encodingAesKey,appId,component_access_token')
        ->find();
        if ($weixin_account) {
            $this->thirdAppId = $weixin_account['appId'];
            $this->encodingAesKey = $weixin_account['encodingAesKey'];
            $this->thirdToken = $weixin_account['token'];
            $this->thirdAccessToken = $weixin_account['component_access_token'];
            $miniprogram = Db::name('wxminiprograms')
                ->where('authorizer_appid',$appid)
                ->field('authorizer_access_token,authorizer_refresh_token,authorizer_expires')
                ->find();
            if($miniprogram){
                $this->authorizer_appid = $appid;
                if(time() > $miniprogram['authorizer_expires']){
                    $miniapp = $this->update_authorizer_access_token($appid,$miniprogram['authorizer_refresh_token']);
                    if($miniapp) {
                        $this->authorizer_access_token = $miniapp->authorizer_access_token;
                        $this->authorizer_refresh_token = $miniapp->authorizer_refresh_token;
                    } else {
                        $this->errorLog("更新小程序access_token失敗,appid:".$this->authorizer_appid,'');
                        exit;
                    }
                } else {
                    $this->authorizer_access_token = $miniprogram['authorizer_access_token'];
                    $this->authorizer_refresh_token = $miniprogram['authorizer_refresh_token'];
                }
            } else {
                $this->errorLog("小程序不存在,appid:".$this->authorizer_appid,'');
                exit;
            }
        } else {
            $this->errorLog("請(qǐng)?jiān)黾游⑿诺谌焦娞?hào)平臺(tái)賬戶信息",'');
            exit;
        }
    }

    /*
     * 設(shè)置小程序服務(wù)器地址,無(wú)需加https前綴齐苛,但域名必須可以通過(guò)https訪問(wèn)
     * @params string / array $domains : 域名地址翘盖。只接收一維數(shù)組。
     * */
    public  function setServerDomain($domain = 'test.moh.cc'){
        $url = "https://api.weixin.qq.com/wxa/modify_domain
                ?access_token=".$this->authorizer_access_token;
        if(is_array($domain)) {
            $https = ''; $wss = '';
            foreach ($domain as $key => $value) {
                $https .= '"https://'.$value.'",';
                $wss .= '"wss://'.$value.'",';
            }
            $https = rtrim($https,',');
            $wss = rtrim($wss,',');
            $data = '{
                "action":"add",
                "requestdomain":['.$https.'],
                "wsrequestdomain":['.$wss.'],
                "uploaddomain":['.$https.'],
                "downloaddomain":['.$https.']
            }';
        } else {
            $data = '{
                "action":"add",
                "requestdomain":"https://'.$domain.'",
                "wsrequestdomain":"wss://'.$domain.'",
                "uploaddomain":"https://'.$domain.'",
                "downloaddomain":"https://'.$domain.'"
            }';
        }
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("設(shè)置小程序服務(wù)器地址失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 設(shè)置小程序業(yè)務(wù)域名凹蜂,無(wú)需加https前綴馍驯,但域名必須可以通過(guò)https訪問(wèn)
     * @params string / array $domains : 域名地址。只接收一維數(shù)組玛痊。
     * */
    public function setBusinessDomain($domain = 'test.moh.cc'){
        $url = "https://api.weixin.qq.com/wxa/setwebviewdomain
                ?access_token=".$this->authorizer_access_token;
        if(is_array($domain)) {
            $https = '';
            foreach ($domain as $key => $value) {
                $https .= '"https://'.$value.'",';
            }
            $https = rtrim($https,',');
            $data = '{
                "action":"add",
                "webviewdomain":['.$https.']
            }';
        } else {
            $data = '{
                "action":"add",
                "webviewdomain":"https://'.$domain.'"
            }';
        }
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("設(shè)置小程序業(yè)務(wù)域名失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 成員管理汰瘫,綁定小程序體驗(yàn)者
     * @params string $wechatid : 體驗(yàn)者的微信號(hào)
     * */
    public function bindMember($wechatid){
        $url = "https://api.weixin.qq.com/wxa/bind_tester
                ?access_token=".$this->authorizer_access_token;
        $data = '{"wechatid":"'.$wechatid.'"}';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("綁定小程序體驗(yàn)者操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 成員管理,解綁定小程序體驗(yàn)者
     * @params string $wechatid : 體驗(yàn)者的微信號(hào)
     * */
    public function unBindMember($wechatid){
        $url = "https://api.weixin.qq.com/wxa/unbind_tester
                ?access_token=".$this->authorizer_access_token;
        $data = '{"wechatid":"'.$wechatid.'"}';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("解綁定小程序體驗(yàn)者操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
    * 成員管理擂煞,獲取小程序體驗(yàn)者列表
    * */
    public function listMember(){
        $url = "https://api.weixin.qq.com/wxa/memberauth
                ?access_token=".$this->authorizer_access_token;
        $data = '{"action":"get_experiencer"}';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return $ret->members;
        } else {
            $this->errorLog("獲取小程序體驗(yàn)者列表操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 為授權(quán)的小程序帳號(hào)上傳小程序代碼
     * @params int $template_id : 模板ID
     * @params json $ext_json : 小程序配置文件混弥,json格式
     * @params string $user_version : 代碼版本號(hào)
     * @params string $user_desc : 代碼描述
     * */
    public function uploadCode($template_id = 1, $user_version = 'v1.0.0', $user_desc = "小程序"){
        $ext_str = '{
            "extEnable": true,
            "extAppid": "wx572****bfb",
            "ext":{"appid": "'.$this->authorizer_appid.'"}
        }';
        $ext_json = json_encode($ext_str);
        $url = "https://api.weixin.qq.com/wxa/commit
                ?access_token=".$this->authorizer_access_token;
        $data = '{
            "template_id":"'.$template_id.'",
            "ext_json":'.$ext_json.',
            "user_version":"'.$user_version.'",
            "user_desc":"'.$user_desc.'"
        }';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("為授權(quán)的小程序帳號(hào)上傳小程序代碼操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 獲取體驗(yàn)小程序的體驗(yàn)二維碼
     * @params string $path :   指定體驗(yàn)版二維碼跳轉(zhuǎn)到某個(gè)具體頁(yè)面
     * */
    public function getExpVersion($path = ''){
        if($path){
            $url = "https://api.weixin.qq.com/wxa/get_qrcode
                    ?access_token=".$this->authorizer_access_token."&path=".urlencode($path);
        } else {
            $url = "https://api.weixin.qq.com/wxa/get_qrcode
                    ?access_token=".$this->authorizer_access_token;
        }
        $ret = json_decode(https_get($url));
        if($ret->errcode) {
            $this->errorLog("獲取體驗(yàn)小程序的體驗(yàn)二維碼操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        } else {
            return $url;
        }
    }

    /*
     * 提交審核
     * @params string $tag : 小程序標(biāo)簽,多個(gè)標(biāo)簽以空格分開(kāi)
     * @params strint $title : 小程序頁(yè)面標(biāo)題对省,長(zhǎng)度不超過(guò)32
     * */
    public function submitReview($tag = "禮品" ,$title = "行業(yè)社交"){
        $first_class = '';$second_class = '';$first_id = 0;$second_id = 0;
        $address = "pages/index/index";
        $category = $this->getCategory();
        if(!empty($category)) {
            $first_class = $category[0]->first_class ? $category[0]->first_class : '' ;
            $second_class = $category[0]->second_class ? $category[0]->second_class : '';
            $first_id = $category[0]->first_id ? $category[0]->first_id : 0;
            $second_id = $category[0]->second_id ? $category[0]->second_id : 0;
        }
        $getpage = $this->getPage();
        if(!empty($getpage) && isset($getpage[0])) {
            $address = $getpage[0];
        }
        $url = "https://api.weixin.qq.com/wxa/submit_audit
                ?access_token=".$this->authorizer_access_token;
        $data = '{
                "item_list":[{
                    "address":"'.$address.'",
                    "tag":"'.$tag.'",
                    "title":"'.$title.'",
                    "first_class":"'.$first_class.'",
                    "second_class":"'.$second_class.'",
                    "first_id":"'.$first_id.'",
                    "second_id":"'.$second_id.'"
                }]
            }';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            Db::name('wxminiprogram_audit')->insert([
                'appid'=>$this->authorizer_appid,
                'auditid'=>$ret->auditid,
                'create_time'=>date('Y-m-d H:i:s')
            ]);
            return true;
        } else {
            $this->errorLog("小程序提交審核操作失敗蝗拿,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 小程序?qū)徍顺坊?     * 單個(gè)帳號(hào)每天審核撤回次數(shù)最多不超過(guò)1次,一個(gè)月不超過(guò)10次蒿涎。
     * */
    public function unDoCodeAudit(){
        $url = "https://api.weixin.qq.com/wxa/undocodeaudit
                ?access_token=".$this->authorizer_access_token;
        $ret = json_decode(https_get($url));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("小程序?qū)徍顺坊夭僮魇“校琣ppid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 查詢指定版本的審核狀態(tài)
     * @params string $auditid : 提交審核時(shí)獲得的審核id
     * */
    public function getAuditStatus($auditid){
        $url = "https://api.weixin.qq.com/wxa/get_auditstatus
                ?access_token=".$this->authorizer_access_token;
        $data = '{"auditid":"'.$auditid.'"}';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            $reason = $ret->reason ? $ret->reason : '';
            Db::name('wxminiprogram_audit')
            ->where(['appid'=>$this->authorizer_appid,'auditid'=>$auditid])
            ->update([
                'status'=>$ret->status,
                'reason'=>$reason
            ]);
            return true;
        } else {
            $this->errorLog("查詢指定版本的審核狀態(tài)操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 查詢最新一次提交的審核狀態(tài)
     * */
    public function getLastAudit(){
        $url = "https://api.weixin.qq.com/wxa/get_latest_auditstatus
                ?access_token=".$this->authorizer_access_token;
        $ret = json_decode(https_get($url));
        if($ret->errcode == 0) {
            $reason = $ret->reason ? $ret->reason : '';
            Db::name('wxminiprogram_audit')
            ->where(['appid'=>$this->authorizer_appid,'auditid'=>$ret->auditid])
            ->update([
                'status'=>$ret->status,
                'reason'=>$reason
            ]);
            return $ret->auditid;
        } else {
            $this->errorLog("查詢最新一次提交的審核狀態(tài)操作失敗劳秋,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 發(fā)布已通過(guò)審核的小程序
     * */
    public function release(){
        $url = "https://api.weixin.qq.com/wxa/release
                ?access_token=".$this->authorizer_access_token;
        $data = '{}';
        $ret = json_decode(https_post($url,$data));
        if($ret->errcode == 0) {
            return true;
        } else {
            $this->errorLog("發(fā)布已通過(guò)審核的小程序操作失敗仓手,appid:".$this->authorizer_appid,$ret);
            return $ret->errcode;
        }
    }

    /*
     * 獲取授權(quán)小程序帳號(hào)的可選類目
     * */
    private function getCategory(){
        $url = "https://api.weixin.qq.com/wxa/get_category
                ?access_token=".$this->authorizer_access_token;
        $ret = json_decode(https_get($url));
        if($ret->errcode == 0) {
            return $ret->category_list;
        } else {
            $this->errorLog("獲取授權(quán)小程序帳號(hào)的可選類目操作失敗,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
     * 獲取小程序的第三方提交代碼的頁(yè)面配置
     * */
    private function getPage(){
        $url = "https://api.weixin.qq.com/wxa/get_page
                ?access_token=".$this->authorizer_access_token;
        $ret = json_decode(https_get($url));
        if($ret->errcode == 0) {
            return $ret->page_list;
        } else {
            $this->errorLog("獲取小程序的第三方提交代碼的頁(yè)面配置失敗玻淑,appid:".$this->authorizer_appid,$ret);
            return false;
        }
    }

    /*
    * 更新授權(quán)小程序的authorizer_access_token
    * @params string $appid : 小程序appid
    * @params string $refresh_token : 小程序authorizer_refresh_token
    * */
    private function update_authorizer_access_token($appid,$refresh_token){
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token
                ?component_access_token=' . $this->thirdAccessToken;
        $data = '{
            "component_appid":"' . $this->thirdAppId . '",
            "authorizer_appid":"' . $appid . '",
            "authorizer_refresh_token":"' . $refresh_token . '"
        }';
        $ret = json_decode(https_post($url, $data));
        if (isset($ret->authorizer_access_token)) {
            Db::name('wxminiprograms')
            ->where(['authorizer_appid' => $appid])
            ->update(
                [
                    'authorizer_access_token' => $ret->authorizer_access_token, 
                    'authorizer_expires' => (time() + 7200), 
                    'authorizer_refresh_token' => $ret->authorizer_refresh_token
                ]
            );
            return $ret;
        } else {
            $this->errorLog("更新授權(quán)小程序的authorizer_access_token操作失敗,appid:".$appid,$ret);
            return null;
        }
    }

    private function errorLog($msg,$ret){
        file_put_contents(ROOT_PATH . 'runtime/error/miniprogram.log', "[" . date('Y-m-d H:i:s') . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND);
    }

}
<?php

//代小程序?qū)崿F(xiàn)業(yè)務(wù)示例包
namespace app\user\controller;
use app\home\model\Miniprogram;
use think\Db;
class Wxminiprogram extends Pub{

    public $appid = 'wx57****1bfb';    
    //需要實(shí)現(xiàn)業(yè)務(wù)小程序appid

    public function index(){
        return view();
    }

    public function doAction(){
        if(request()->isPost()) {
            $action = input('action');
            $mini = new Miniprogram($this->appid);
            if($action == 'auth') {
                //小程序授權(quán)
                echo '<script>alert("已授權(quán)");history.back();</script>';
            } elseif($action == 'setServerDomain') {
                //設(shè)置小程序服務(wù)器域名地址
                if($mini->setServerDomain()){
                    echo '<script>alert("設(shè)置小程序服務(wù)器域名操作成功");history.back();</script>';
                } else {
                    echo '<script>alert("設(shè)置小程序服務(wù)器域名操作失敗或已設(shè)置嗽冒,請(qǐng)查看日志");history.back();</script>';
                }
            }  elseif($action == 'setBusinessDomain') {
                //設(shè)置業(yè)務(wù)域名
                if($mini->setBusinessDomain()){
                    echo '<script>alert("設(shè)置小程序業(yè)務(wù)域名操作成功");history.back();</script>';
                } else {
                    echo '<script>alert("設(shè)置小程序業(yè)務(wù)域名操作失敗或已設(shè)置,請(qǐng)查看日志");history.back();</script>';
                }
            }  elseif($action == 'bind') {
                //綁定小程序體驗(yàn)者
                $wechatid = input('wechatid');
                if($wechatid) {
                    if($mini->bindMember($wechatid)){
                        echo '<script>alert("綁定小程序體驗(yàn)者操作成功");history.back();</script>';
                    } else {
                        echo '<script>alert("綁定小程序體驗(yàn)者操作失敗岁忘,請(qǐng)查看日志");history.back();</script>';
                    }
                } else {
                    echo '<script>alert("請(qǐng)輸入微信號(hào)");history.back();</script>';
                }
            }  elseif($action == 'uploadCode') {
                //上傳小程序代碼
                if($mini->uploadCode(2)){
                    echo '<script>alert("上傳小程序代碼操作成功");history.back();</script>';
                } else {
                    echo '<script>alert("上傳小程序代碼操作失敗辛慰,請(qǐng)查看日志");history.back();</script>';
                }
            }  elseif($action == 'getExpVersion') {
                //獲取體驗(yàn)小程序的體驗(yàn)二維碼
                $qrcode = $mini->getExpVersion();
                if($qrcode){
                    echo '<script>window.location.href="'.$qrcode.'";</script>';
                } else {
                    echo '<script>alert("獲取體驗(yàn)小程序的體驗(yàn)二維碼操作失敗");history.back();</script>';
                }
            } elseif($action == 'review') {
                //提交審核
                $auditid = Db::name('wxminiprogram_audit')
                ->where(['appid'=>$this->appid,'status'=>['neq',0]])
                ->order('create_time','desc')
                ->value('auditid');
                if($auditid){
                    echo '<script>alert("有待處理的版本区匠,請(qǐng)先處理該版本相關(guān)事項(xiàng)再提交新的審核干像。審核ID:'.$auditid.'");history.back();</script>';
                } else {
                    if($mini->submitReview()){
                        echo '<script>alert("小程序提交審核操作成功");history.back();</script>';
                    } else {
                        echo '<script>alert("小程序提交審核操作失敗,請(qǐng)查看日志");history.back();</script>';
                    }
                }
            } elseif($action == 'getAudit') {
                //查詢指定版本的審核狀態(tài)
                $auditid = input('auditid');
                if($auditid) {
                    if($mini->getAuditStatus($auditid)){
                        $audit = Db::name('wxminiprogram_audit')
                        ->where(['appid'=>$this->appid,'auditid'=>$auditid])
                        ->field('status,reason')->find();
                        if($audit['status'] == 0) {
                            echo '<script>alert("該版本審核已通過(guò)");history.back();</script>';
                        } elseif($audit['status'] == 1) {
                            echo '<script>alert("該版本審核失敗驰弄,原因:'.$audit['reason'].'");history.back();</script>';
                        } elseif($audit['status'] == 2) {
                            echo '<script>alert("該版本小程序正在審核中......");history.back();</script>';
                        } else {
                            echo '<script>alert("未知狀態(tài)......");history.back();</script>';
                        }
                    } else {
                        echo '<script>alert("查詢指定版本的審核狀態(tài)操作失敗麻汰,請(qǐng)查看日志");history.back();</script>';
                    }
                } else {
                    echo '<script>alert("請(qǐng)輸入要查詢的審核ID");history.back();</script>';
                }

            } elseif($action == 'lastAudit') {
                //查詢最新一次提交的審核狀態(tài)
                $auditid = $mini->getLastAudit();
                if($auditid){
                    $audit = Db::name('wxminiprogram_audit')
                    ->where(['appid'=>$this->appid,'auditid'=>$auditid])
                    ->field('status,reason')->find();
                    if($audit['status'] == 0) {
                        echo '<script>alert("審核已通過(guò)");history.back();</script>';
                    } elseif($audit['status'] == 1) {
                        echo '<script>alert("審核失敗,原因:'.$audit['reason'].'");history.back();</script>';
                    } elseif($audit['status'] == 2) {
                        echo '<script>alert("小程序正在審核中......");history.back();</script>';
                    } else {
                        echo '<script>alert("未知狀態(tài)......");history.back();</script>';
                    }
                }else {
                    echo '<script>alert("查詢最新一次提交的審核狀態(tài)操作失敗戚篙,請(qǐng)查看日志");history.back();</script>';
                }
            } elseif($action == 'release') {
                //發(fā)布已通過(guò)審核的小程序
                $auditid = Db::name('wxminiprogram_audit')
                ->where(['appid'=>$this->appid,'status'=>['neq',0]])
                ->order('create_time','desc')
                ->value('auditid');
                if($auditid){
                    echo '<script>alert("有待處理的版本五鲫,請(qǐng)先處理該版本相關(guān)事項(xiàng)再發(fā)布版本。審核ID:'.$auditid.'");history.back();</script>';
                } else {
                    $errcode = $mini->release();
                    if($errcode){
                        echo '<script>alert("已發(fā)版");history.back();</script>';
                    } else {
                        echo '<script>alert("發(fā)版失敗岔擂,錯(cuò)誤代碼:'.$errcode.'");history.back();</script>';
                    }
                }
            }
        }
    }
}

wxminiprograms數(shù)據(jù)表位喂,保存已授權(quán)小程序的基本信息及授權(quán)相關(guān)信息
(authorizer_access_token/authorizer_refresh_token)這兩個(gè)值很重要浪耘,代小程序?qū)崿F(xiàn)業(yè)務(wù)基本上是通過(guò)這兩個(gè)值來(lái)實(shí)現(xiàn)

CREATE TABLE `wxminiprograms` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `uid` int(10) unsigned NOT NULL COMMENT '用戶ID',
  `nick_name` varchar(45) DEFAULT NULL COMMENT '微信小程序名稱',
  `alias` varchar(45) DEFAULT NULL COMMENT '別名',
  `token` varchar(45) DEFAULT NULL COMMENT '平臺(tái)生成的token值',
  `head_img` varchar(255) DEFAULT NULL COMMENT '微信小程序頭像',
  `verify_type_info` tinyint(1) DEFAULT NULL COMMENT '授權(quán)方認(rèn)證類型,-1代表未認(rèn)證塑崖,0代表微信認(rèn)證',
  `is_show` tinyint(1) DEFAULT '0' COMMENT '是否顯示七冲,0顯示,1隱藏',
  `user_name` varchar(45) DEFAULT NULL COMMENT '原始ID',
  `qrcode_url` varchar(255) DEFAULT NULL COMMENT '二維碼圖片的URL',
  `business_info` varchar(255) DEFAULT NULL COMMENT 'json格式规婆。用以了解以下功能的開(kāi)通狀況(0代表未開(kāi)通澜躺,1代表已開(kāi)通):   open_store:是否開(kāi)通微信門店功能   open_scan:是否開(kāi)通微信掃商品功能   open_pay:是否開(kāi)通微信支付功能   open_card:是否開(kāi)通微信卡券功能   open_shake:是否開(kāi)通微信搖一搖功能',
  `idc` int(10) unsigned DEFAULT NULL COMMENT 'idc',
  `principal_name` varchar(45) DEFAULT NULL COMMENT '小程序的主體名稱',
  `signature` varchar(255) DEFAULT NULL COMMENT '帳號(hào)介紹',
  `miniprograminfo` varchar(255) DEFAULT NULL COMMENT 'json格式。判斷是否為小程序類型授權(quán)抒蚜,包含network小程序已設(shè)置的各個(gè)服務(wù)器域名',
  `func_info` longtext COMMENT 'json格式掘鄙。權(quán)限集列表,ID為17到19時(shí)分別代表: 17.帳號(hào)管理權(quán)限 18.開(kāi)發(fā)管理權(quán)限 19.客服消息管理權(quán)限 請(qǐng)注意: 1)該字段的返回不會(huì)考慮小程序是否具備該權(quán)限集的權(quán)限(因?yàn)榭赡懿糠志邆洌?,
  `authorizer_appid` varchar(45) DEFAULT NULL COMMENT '小程序appid',
  `authorizer_access_token` varchar(255) DEFAULT NULL COMMENT '授權(quán)方接口調(diào)用憑據(jù)(在授權(quán)的公眾號(hào)或小程序具備API權(quán)限時(shí)嗡髓,才有此返回值)操漠,也簡(jiǎn)稱為令牌',
  `authorizer_expires` int(10) unsigned DEFAULT NULL COMMENT 'refresh有效期',
  `authorizer_refresh_token` varchar(255) DEFAULT NULL COMMENT '接口調(diào)用憑據(jù)刷新令牌',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '授權(quán)時(shí)間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信小程序授權(quán)列表'

wxminiprogram_audit數(shù)據(jù)表,保存提交審核的小程序

CREATE TABLE `wxminiprogram_audit` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `appid` varchar(45) NOT NULL COMMENT '小程序appid',
  `auditid` varchar(45) NOT NULL COMMENT '審核編號(hào)',
  `status` tinyint(1) unsigned NOT NULL DEFAULT '3' COMMENT '審核狀態(tài)器贩,其中0為審核成功颅夺,1為審核失敗,2為審核中蛹稍,3已提交審核',
  `reason` varchar(255) DEFAULT NULL COMMENT '當(dāng)status=1吧黄,審核被拒絕時(shí),返回的拒絕原因',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '提交審核時(shí)間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信小程序提交審核的小程序'
image.png

image.png

轉(zhuǎn)載http://www.php.cn/weixin-kaifa-406993.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唆姐,一起剝皮案震驚了整個(gè)濱河市拗慨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奉芦,老刑警劉巖赵抢,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異声功,居然都是意外死亡烦却,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門先巴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)其爵,“玉大人,你說(shuō)我怎么就攤上這事伸蚯∧γ欤” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵剂邮,是天一觀的道長(zhǎng)摇幻。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么绰姻? 我笑而不...
    開(kāi)封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任枉侧,我火速辦了婚禮,結(jié)果婚禮上狂芋,老公的妹妹穿的比我還像新娘棵逊。我一直安慰自己,他們只是感情好银酗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布辆影。 她就那樣靜靜地躺著,像睡著了一般黍特。 火紅的嫁衣襯著肌膚如雪蛙讥。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天灭衷,我揣著相機(jī)與錄音次慢,去河邊找鬼。 笑死翔曲,一個(gè)胖子當(dāng)著我的面吹牛迫像,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞳遍,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闻妓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了掠械?” 一聲冷哼從身側(cè)響起由缆,我...
    開(kāi)封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎猾蒂,沒(méi)想到半個(gè)月后均唉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肚菠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年舔箭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚊逢。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡层扶,死狀恐怖须床,靈堂內(nèi)的尸體忽然破棺而出哼蛆,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布奢讨,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拿诸。R本人自食惡果不足惜扒袖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望亩码。 院中可真熱鬧季率,春花似錦、人聲如沸描沟。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吏廉。三九已至泞遗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間席覆,已是汗流浹背史辙。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佩伤,地道東北人聊倔。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像生巡,于是被迫代替她去往敵國(guó)和親耙蔑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354