PHP 对接 快手api
//.env 文件配置
[KS] appKey = "ks*************73" appSecret = "ek************boQ" signSecret = "f37**************a40f" serverHost = "https://openapi.kwaixiaodian.com"
<?php namespace app\shopapi\controller\kuaishou; use app\common\model\Config; use app\shopapi\controller\BaseShopController; /** * 快手 */ class TestController extends BaseShopController { public function ceshi() { echo 123;exit; }
/**
* stdClass Object转array
*/
function object2array(&$object) {
$object = json_decode( json_encode( $object),true);
return $object;
}
/*********************************************** 需要授权 获取access_token ***************************************/
//获取code
public function ks_auth_get_code(){
$app_id = env('KS.appKey'); //应用的 appKey
$redirect_uri = "https://".$_SERVER['HTTP_HOST']."/adminapi/user.user/ks_auth_get_redirect_uri"; //授权成功的回调uri,为APP在创建时填写的回调地址
$app_secret = env('KS.appSecret');
$scope = "merchant_distribution"; //读取或更新用户的分销信息
$state = ""; //传参 可以回调返回
$url_str = "https://open.kwaixiaodian.com/oauth/authorize?app_id=$app_id&redirect_uri=$redirect_uri&scope=$scope&response_type=code&state=$state";
echo $url_str;exit;
}
//获取 回调 返回的code 刷新refreshToken
public function ks_auth_get_redirect_uri(){
//var_dump($_REQUEST);exit;
$code = $_REQUEST['code'] ?? "";
$res = $this->getToken($code);
if($res['result'] == 1){
$access_token_info = Config::where(['type'=>'shop','name'=>'ks_access_token'])->find();
$time_str = time();
if($access_token_info){
Config::update(['value'=>$res['access_token'],'create_time'=>$time_str,'update_time'=>$time_str],['type'=>'shop','name'=>'ks_access_token']);
Config::update(['value'=>$res['refresh_token'],'create_time'=>$time_str,'update_time'=>$time_str],['type'=>'shop','name'=>'ks_refresh_token']);
}else{
Config::insert(['type'=>'shop','name'=>'ks_access_token','value'=>$res['access_token'],'create_time'=>$time_str,'update_time'=>$time_str]);
Config::insert(['type'=>'shop','name'=>'ks_refresh_token','value'=>$res['refresh_token'],'create_time'=>$time_str,'update_time'=>$time_str]);
}
}else{
//授权失败
echo "code失效";exit;
}
}
//获取授权 access_token
public function ks_auth_get_access_token($type = 'update'){
$refresh_token_info = Config::where(['type'=>'shop','name'=>'ks_refresh_token'])->find();
if($refresh_token_info){
$refresh_token_info = $refresh_token_info->toArray();
$refresh_token_info['create_time'] = $refresh_token_info['create_time'] ?? 0;
$refresh_token_info['update_time'] = $refresh_token_info['update_time'] ?? 0;
$refresh_token_info['value'] = $refresh_token_info['value'] ?? "";
//过期时间 refresh_token 180天 过期
$last_time = strtotime($refresh_token_info['update_time']) + 180*24*3600 - 24*60*60;
if ($last_time < time()) {
//时长令牌 过期
$res = "";
}else{
$res = $this->refreshToken($refresh_token_info['value']);
}
}else{
//时长令牌 过期
$res = "";
}
if(isset($res['result']) && $res['result'] == 1){
$access_token_info = Config::where(['type'=>'shop','name'=>'ks_access_token'])->find();
if($access_token_info){
Config::update(['value'=>$res['access_token']],['type'=>'shop','name'=>'ks_access_token']);
Config::update(['value'=>$res['refresh_token']],['type'=>'shop','name'=>'ks_refresh_token']);
}else{
Config::insert(['type'=>'shop','name'=>'ks_access_token','value'=>$res['access_token'],'create_time'=>time(),'update_time'=>time()]);
Config::insert(['type'=>'shop','name'=>'ks_refresh_token','value'=>$res['refresh_token'],'create_time'=>time(),'update_time'=>time()]);
}
return $res['access_token'];
}else{
return "";
}
}
//得到 最新可用的access_token 访问快手api用
public function ks_auth_access_token(){
$access_token_info = Config::where(['type'=>'shop','name'=>'ks_access_token'])->find();
if($access_token_info){
$access_token_info = $access_token_info->toArray();
//过期时间 access_token 48小时过期
$last_time = strtotime($access_token_info['update_time']) + 48*3600 - 60;
if ($last_time < time()) {
$AccessToken = $this->ks_auth_get_access_token('update');
}else{
$AccessToken = $access_token_info['value'];
}
}else{
$AccessToken = $this->ks_auth_get_access_token("insert");
}
return $AccessToken;
}
/*********************************************** 对接快手api ****************************************************/
//快手api
public function Api($apiType, $param, $method = 'get') {
$arr['appkey'] = env('KS.appKey');
$arr['version'] = '1';
$arr['access_token'] = $this->ks_auth_access_token();
$arr['timestamp'] = $this->getMillisecond();
$arr['method'] = trim($apiType);
$arr['param'] = $param ? json_encode($param) : '{}';
$arr['signMethod'] = 'MD5';
ksort($arr); // 排序
$arr['sign'] = $this->getSign($arr, env('KS.signSecret'));
$apiInfo = str_replace('.', '/', $arr['method']);
//print_r($arr);exit;
$url = env('KS.serverHost') .'/'. $apiInfo;
if ($method == 'get') {
$s = $this->curl_https_get($url. '?' . http_build_query($arr, '', '&'), array());
} else {
$s = $this->curl_https_post($url, $arr);
}
$s = json_decode($s, true);
return $s;
}
public function getSign($params, $key) {
$unSignParaString = $this->formatQueryParaMap($params, false);
$signStr = (md5($unSignParaString . "&signSecret=" . env('KS.signSecret')));
return $signStr;
}
public function formatQueryParaMap(array $paraMap, $urlEncode = false) {
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if (null != $v && "null" != $v) {
if ($urlEncode) {
$v = urlencode($v);
}
$buff.= $k . "=" . $v . "&";
}
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
/*获取13位时间戳*/
private static function getMillisecond() {
list($t1, $t2) = explode(' ', microtime());
return sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}
public function getAPIClient($redirectUrl,$scope='merchant_comment,merchant_item,merchant_logistics,merchant_order,merchant_servicemarket,merchant_user,user_info') {
$get_code_url = "https://open.kuaishou.com/oauth2/connect?app_id=".env('KS.appKey')."&scope={$scope}&response_type=code&redirect_uri={$redirectUrl}&state=your_state";
return $get_code_url;
}
public function getToken($code, $redirectUrl = '') {
$url = "https://openapi.kwaixiaodian.com/oauth2/access_token?app_id=".env('KS.appKey')."&app_secret=".env('KS.appSecret')."&code={$code}&grant_type=authorization_code";
$s = $this->curl_https_get($url);
$s = json_decode($s, true);
return $s;
}
/*用长时令牌refreshToken刷新访问令牌accessToken*/
public function refreshToken($refreshToken) {
$url = "https://openapi.kwaixiaodian.com/oauth2/refresh_token?app_id=".env('KS.appKey')."&app_secret=".env('KS.appSecret')."&refresh_token={$refreshToken}&grant_type=refresh_token";
$s = $this->curl_https_get($url);
$s = json_decode($s, true);
return $s;
}
private function curl_get_contents($url, $data = array(), $https = false) {
$results['error'] = '';
$results['status'] = 0;
$results['data'] = array();
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$curl = curl_init(); // 启动一个CURL会话
if (!empty($data) && is_array($data)) {
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
}
if ($https) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
}
curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
curl_setopt($curl, CURLOPT_USERAGENT, $user_agent); // 模拟用户使用的浏览器
curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
$results['data'] = curl_exec($curl); // 执行操作
if (curl_errno($curl)) {
$results['error'] = curl_error($curl); //捕抓异常
}
curl_close($curl); // 关闭CURL会话
return $results['data']; // 返回数据
}
public function curl_https_post($url, $data) {
return $this->curl_get_contents($url, $data, true);
}
public function curl_https_get($url) {
return $this->curl_get_contents($url, array(), true);
}
//调用
public function text($action_time = '', $now_time = '', $pcursor = ''){
$param = [
"cpsOrderStatus" => 0, //分销订单状态 [0:全部订单] [30:已付款] [50:已收货] [60:已结算] [80:已失效]
"pageSize" => 50, //页大小(最大限制为100)
"sortType" => 1, //排序类型 [1:按指定查询类型降序] [2:按指定查询类型升序],必传
"queryType" => 2, //查询类型 [1:按分销订单创建时间查询] [2:按分销订单更新时间查询],必传
"beginTime" => $action_time, //起始时间(毫秒),不能小于90天前,且需要小于结束时间
"endTime" => $now_time, //结束时间(毫秒),且与开始时间的时间范围不大于7天 (与开始时间的时间范围建议做成随时可配置,该范围可能在活动期间随时变化,比如变成小时级或者分钟级)
"pcursor" => $pcursor, //分销订单位点游标 (请求透传,"nomore"标识后续无数据)
];
$res = $this->Api("open.distribution.cps.distributor.order.cursor.list", $param); //用到 这种 游标的api
if (isset($res['code']) && $res['code'] == 1) {
$data = $res['data'];
if ($data['pcursor'] != "nomore") {
//有后续数据
$this->getKuaishou_Info_new($action_time, $now_time, $data['pcursor']);
}
}
}
}
浙公网安备 33010602011771号