代码改变世界

SHEIN 开放平台授权

2025-08-13 11:20  天心PHP  阅读(73)  评论(0)    收藏  举报

文档地址:https://open.sheincorp.com/documents/system/2169474d-1d4a-41a9-b9fd-427f63f54a63

合作模式分为: 1:自主运营 2:全托管 3:半托管 4:SHEIN自营

运营方式分为: 1:自主运营 2:半托管

新建应用后,后台会有 app_id 和 app_secretkey

1.授权链接 

https://openapi-sem.sheincorp.com/#/empower?appid=13E9A81923234380294DE72594404DB6B&redirectUrl=aHR0cDovL3B1Ys3dsdmxpc2guZG2VsYW1hbjE32OC5jb20vc2VydmljZXMvc2hlaW4vc2hlaW5hY2NvdW50L2dldHRva2Vu&state=11

域名:https://openapi-sem.sheincorp.com/#/empower

appid :应用后台的 app_id 

redirectUrl : 回调地址  需要base64加密  

base64_encode('http://xxxx.com/services/shein/sheinaccount/gettoken')

state : 参数会原路返回   一般传id

2.授权成功得到tempToken(十分钟有效) 再用接口 https://openapi.sheincorp.com/open-api/auth/get-by-token 获得 openkeyid 和 secretkey

3.解密 secretKey

账户列表

CREATE TABLE `yibai_shein_account` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `account_name` varchar(50) NOT NULL DEFAULT '' COMMENT '账户名称',
  `short_name` varchar(50) NOT NULL DEFAULT '' COMMENT '账户简称',
  `site` varchar(10) NOT NULL DEFAULT '' COMMENT '站点',
  `cooperate` tinyint(1) NOT NULL DEFAULT '0' COMMENT '合作模式 1:自主运营 2:全托管 3:半托管 4:SHEIN自营',
  `ziniao_id` varchar(50) DEFAULT '' COMMENT '紫鸟id 对应 yy_ziniao_store_list',
  `app` tinyint(1) NOT NULL DEFAULT '0' COMMENT '运营方式 1:云羿自主运营 2:云羿半托管',
  `app_id` varchar(50) DEFAULT '' COMMENT 'App key',
  `app_secretkey` varchar(50) DEFAULT '' COMMENT 'APP_Secretkey',
  `receiving_company` varchar(255) DEFAULT '' COMMENT '收款公司',
  `status` tinyint(1) DEFAULT '0' COMMENT '1:启用 2:停用',
  `is_auth` tinyint(1) DEFAULT '0' COMMENT '是否授权 0:否 1:是 ',
  `openkeyid` varchar(100) DEFAULT NULL COMMENT 'openKeyId',
  `secretkey` varchar(100) DEFAULT NULL COMMENT 'secretKey',
  `secretkey_decrypt` varchar(100) DEFAULT NULL COMMENT 'secretKey解密',
  `create_times` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',
  `update_times` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_account_name` (`account_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='shein账户列表';

SheinaccountController.php

<?php
class SheinaccountController extends YbController{
    /**
     * /services/shein/sheinaccount/gettoken
     */
    public function actionGettoken(){
        $tempToken = Yii::app()->request->getParam('tempToken');
        $state = Yii::app()->request->getParam('state');
        if(!$tempToken || !$state){
            die('参数错误');
        }
        $accountModel = new SheinAccount();
        $info = $accountModel->getDbConnection()->createCommand()
            ->select('id,app_id,app_secretkey')
            ->from($accountModel->tableName())
            ->where("id=".$state)
            ->queryRow();
        $apiModel = new SheinaccountApi();
        $res = $apiModel->gettoken($info['app_id'],$info['app_secretkey'],$tempToken);
        if(isset($res[0]) && $res[0]==200){
            $udata['openkeyid'] = $res[1]['info']['openKeyId'];
            $udata['secretkey'] = $res[1]['info']['secretKey'];
            $udata['secretkey_decrypt'] = $apiModel->secretkey_decrypt($udata['secretkey'],$info['app_secretkey']);
            $udata['is_auth'] = 1;
            $udata['update_times'] = date('Y-m-d H:i:s');
            $accountModel->updateAll($udata,"id=".$state);
        }
        echo 'DOLL';
    }
}

SheinaccountApi.php

<?php
class SheinaccountApi
{
    //获取 openKeyId 和 secretKey
    public function gettoken($app_id,$app_secretkey,$tempToken)
    {
        $url = 'https://openapi.sheincorp.com/open-api/auth/get-by-token';
        $timestamp = round(time() * 1000);
        $headers[] = 'x-lt-appid:'.$app_id;
        $headers[] = 'x-lt-timestamp:'.$timestamp;
        $randomString = substr(uniqid(), -5);
        $finalSignature = $this->generateSheinSignature($app_id,$app_secretkey,'/open-api/auth/get-by-token',$timestamp,$randomString);
        $headers[] = 'x-lt-signature:'.$finalSignature;
        $headers[] = 'Content-Type:application/json;charset=UTF-8';
        $headers[] = 'language:zh-cn';
        $data['tempToken'] = $tempToken;
        $res = $this->cur_request($url,'POST',json_encode($data),$headers);
        print_r('<pre>');
        print_r($res);
        print_r('</pre>');
        /*Array
        (
            [0] => 200
            [1] => Array
                (
                    [code] => 0
                    [msg] => OK
                    [info] => Array
                        (
                            [secretKey] => HS8WEMKXrUhdFGAZsRCHUdOSDGSERRLSEGzomahGqHqzUwTQtTpbpPeuUS2FEI42e081ZczU
                            [appid] => 13E9A81234292380294DE725923234404DB6B
                            [openKeyId] => B722393233435423466364667A9D745FB658ED46F
                            [state] => 11
                            [supplierId] => 274345415
                            [supplierSource] => 10
                            [supplierBusinessMode] =>
                        )

                    [traceId] => 8dae9346a6f230d31e
                )

        )*/
        if($res[0]==200 && $res[1]['code']==0){
            return $res;
        }else{
            return [];
        }
    }

    //签名得到signa
    public function generateSheinSignature($openKeyId, $secretKey, $path, $timestamp, $randomKey)
    {
        // 步骤一:组装签名数据VALUE
        $value = $openKeyId . "&" . $timestamp . "&" . $path;
        // 步骤二:组装签名密钥KEY
        $key = $secretKey . $randomKey;
        // 步骤三:HMAC-SHA256计算并转换为十六进制
        $hmacResult = hash_hmac('sha256', $value, $key, false); // false意味着返回十六进制
        // 步骤四:Base64编码
        $base64Signature = base64_encode($hmacResult);
        // 步骤五:拼接RandomKey
        $finalSignature = $randomKey . $base64Signature;
        return $finalSignature;
    }

    //secretKey解密
    public function secretkey_decrypt($secretKey,$app_secretkey)
    {
        $iv = "space-station-de"; //固定IV
        $encrypted_data = base64_decode($secretKey);  // 待解密字段
        $decrypted_data = openssl_decrypt($encrypted_data, "AES-128-CBC", $app_secretkey, OPENSSL_RAW_DATA, $iv);
        return $decrypted_data;
    }


    public function cur_request($URL, $type, $params, $headers)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $URL);
        if ($headers != "") {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        } else {
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        switch ($type) {
            case "GET" :
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case "POST":
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                break;
            case "PUT" :
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                break;
            case "PATCH":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                break;
            case "DELETE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                break;
        }
        $file_contents = curl_exec($ch);//获得返回值
        $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return [$responseCode, json_decode($file_contents, true)];
    }
}