亚马逊 广告接口对接 amazon advertising

3 篇文章 3 订阅
1 篇文章 0 订阅

Amazon Advertising API

最终目标效果

在这里插入图片描述

1. 授权 (加入亚马逊开发者白名单)

官方文档 https://advertising.amazon.com/API/docs/en-us/setting-up/account-setup

相对来说 授权还是比较麻烦的, 由于公司业务原因,我们注册的是第三方管理账户。 也就是说一个开发者账号管理多个店铺(防关联)。

建议开发这种大平台接口功能在前期阶段先多研究研究文档,一步一步来,这样在后面的功能开发阶段还是比较有用的。

由于我们注册的是第三方管理,在于亚马逊邮件往来阶段对方要我们提供一个公司介绍…
在这里插入图片描述
但我们这是自己的后台ERP没啥官网,只能去网上找个模板花两个小时做了一个单页面官网给他们发过去(有自己公司官网的直接发官网链接就好)…

正常的往来邮件最后会得到API所需的 client_id, client_secret在这里插入图片描述

2. 获取店铺授权token (Create API authorization and refresh tokens)

https://advertising.amazon.com/API/docs/en-us/setting-up/generate-api-tokens

这个就是给你一个链接, 把你实际的参数替换进去, 最后会跳转到登录界面(网页有登录记录的可能会跳过) 然后让你授权。

https://www.amazon.com/ap/oa?client_id=YOUR_LWA_CLIENT_ID&scope=cpc_advertising:campaign_management&response_type=code&redirect_uri=YOUR_RETURN_URL

参数说明

  • 链接的前半部分自己判断区域选择对应地址
  • YOUR_LWA_CLIENT_ID: client_id
  • YOUR_RETURN_URL: 这个当时我也蒙蔽了半天… 下图红色圈内的回调地址就是这个了…
    在这里插入图片描述
    在这里插入图片描述

登陆之后会给你也授权页面 点击 允许 就行
在这里插入图片描述

接下来就会跳转到你的回调地址(YOUR_RETURN_URL),并将authorization code 以GET 的形式传回来

array(2) { [“code”]=> string(20) “ANesDVfOevJXAuKXZVut” [“scope”]=> string(35) “cpc_advertising:campaign_management” }

自己处理逻辑 保存这个 code 有了这个code 下面的 获取token和刷新token直接按文档curl请求就好

public function getToken()
	{
        switch ( $this->region ) {
            case 'NA':
                $region = 'https://api.amazon.com/auth/o2/token';
                break;
            case 'EU':
                $region = 'https://api.amazon.co.uk/auth/o2/token';
                break;
            case 'FE':
                $region = 'https://api.amazon.co.jp/auth/o2/token';
                break;
            
            default:
                $region = 'https://api.amazon.com/auth/o2/token';
                break;
        }

		$header = array (
            'Content-Type:application/x-www-form-urlencoded;charset=UTF-8'
        );
        $code = "ANesDVfOevJXAuKXZVut";
		$redirect_uri = "https://network.*******.com/var/amz_advertising_return/file_getToken.php";
		
        $curlData = "grant_type=authorization_code&code={$code}&redirect_uri={$redirect_uri}&client_id={$this->client_id}&client_secret={$this->client_secret}";

        $res = $this->sendCurlPostRequest($region, $curlData, $header);
        $data = json_decode($res, true);
        // var_dump($res);
        // var_dump($data);die;
        $access_token = $data['access_token'];
        $refresh_token = $data['refresh_token'];
        $token_type = $data['token_type'];
        $token_time = time() + 3500;

        // db操作...
	}
	
    // 刷新 token
    public function refreshToken()
    {
        switch ( $this->region ) {
            case 'NA':
                $region = 'https://api.amazon.com/auth/o2/token';
                break;
            case 'EU':
                $region = 'https://api.amazon.co.uk/auth/o2/token';
                break;
            case 'FE':
                $region = 'https://api.amazon.co.jp/auth/o2/token';
                break;
            
            default:
                $region = 'https://api.amazon.com/auth/o2/token';
                break;
        }
        
        $header = array (
            'Content-Type:application/x-www-form-urlencoded;charset=UTF-8'
        );

        $curlData = "grant_type=refresh_token&client_id=$this->client_id&refresh_token=$this->refresh_token&client_secret=$this->client_secret";

        $res = $this->sendCurlPostRequest($region, $curlData, $header);
        $data = json_decode($res, true);
        $data['token_time'] = time() + 3500;

        $this->token = $data['access_token'];
        $this->local_log($data);die;
        global $link, $id;
        $sql="UPDATE db_ads SET access_token='{$data['access_token']}', refresh_token='{$data['refresh_token']}', token_time='{$data['token_time']}' WHERE shop_id='".$id."' ";
        mysqli_query($link, $sql);
    }

获取token之后要获取 profile_id,之后的接口请求基本都需要这个

 	// 获取店铺信息 profile_id
    public function getProfiles()
    {
        switch ( $this->region ) {
            case 'NA':
                $host = "https://advertising-api.amazon.com";
                break;
            case 'EU':
                $host = "https://api.amazon.co.uk/auth/o2/token";
                break;
            case 'FE':
                $host = "https://api.amazon.co.jp/auth/o2/token";
                break;
            
            default:
                $host = "https://advertising-api.amazon.com";
                break;
        }

        $url = $host."/v2/profiles";

        $headers = array(
            "Authorization: Bearer $this->token",
            "Amazon-Advertising-API-ClientId:$this->client_id",
            "Access-Control-Allow-Credentials: true",
            "Content-Type:application/json",
            "User-Agent:test1",
        );

        $profile = $this->sendCurlGetRequest($url, $headers);
        $profiles = json_decode($profile, true);

        // db操作...
        $this->profile_id = number_format($profiles[0]['profileId'], 0, '', '');
        global $link, $id;
        $sql="UPDATE db_ads SET profile_id='{$this->profile_id}', profiles='{$profile}' WHERE shop_id='".$id."' ";

        mysqli_query($link, $sql);
    }


到这为止基本上准备工作就做完了,接下来就是正式请求报告信息了

3.获取REPORTS

在这里插入图片描述
大概流程就是

请求生成报告 - 等待报告完成 - 获取报告信息 - 下载报告内容 - 解压

这里有个小坑,当时我下载报告怎么传参都有问题,查了好久发现他最终curl请求会307重定向,直接去跳转下载页面, 但是会报错,大概意思就是标头有问题:

Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified

就是你带header参数,他说你多余, 你不带,告诉你没权限…
谷歌N久之后找到原因:
在这里插入图片描述
解决办法就是把重定向的链接提取出来,再次不带header请求一次。


    // 请求报告
    public function requestReport()
    {
        // Record types can be: campaigns, adGroups, keywords, productAds, and targets

        // productAds: 'metrics' => 'campaignName,campaignId,adGroupName,adGroupId,impressions,clicks,cost,currency,asin,sku,attributedConversions1d,attributedConversions7d,attributedConversions14d,attributedConversions30d,attributedConversions1dSameSKU,attributedConversions7dSameSKU,attributedConversions14dSameSKU,attributedConversions30dSameSKU,attributedUnitsOrdered1d,attributedUnitsOrdered7d,attributedUnitsOrdered14d,attributedUnitsOrdered30d,attributedSales1d,attributedSales7d,attributedSales14d,attributedSales30d,attributedSales1dSameSKU,attributedSales7dSameSKU,attributedSales14dSameSKU,attributedSales30dSameSKU,attributedUnitsOrdered1dSameSKU,attributedUnitsOrdered7dSameSKU,attributedUnitsOrdered14dSameSKU,attributedUnitsOrdered30dSameSKU'

        $recordType = 'productAds';
        $header_ = $this->returnHeader();
        $url = $header_['host']."/v2/sp/{$recordType}/report";

		// 获取 前一天的信息
        $date = date('Ymd', time()-3600*24);
        $curlData = array(
            // 'segment'=> 'query',
            'reportDate'=> $date,
            'metrics' => 'campaignName,campaignId,adGroupName,adGroupId,impressions,clicks,cost,currency,asin,sku,attributedConversions1d,attributedConversions7d,attributedConversions14d,attributedConversions30d,attributedConversions1dSameSKU,attributedConversions7dSameSKU,attributedConversions14dSameSKU,attributedConversions30dSameSKU,attributedUnitsOrdered1d,attributedUnitsOrdered7d,attributedUnitsOrdered14d,attributedUnitsOrdered30d,attributedSales1d,attributedSales7d,attributedSales14d,attributedSales30d,attributedSales1dSameSKU,attributedSales7dSameSKU,attributedSales14dSameSKU,attributedSales30dSameSKU,attributedUnitsOrdered1dSameSKU,attributedUnitsOrdered7dSameSKU,attributedUnitsOrdered14dSameSKU,attributedUnitsOrdered30dSameSKU'
        );
        $curlData = json_encode($curlData);
        $res = $this->sendCurlPostRequest($url, $curlData, $header_['header']);
        
        $res = json_decode($res, true);
        $this->local_log($res);
        if (isset($res['reportId'])) {
            sleep(60); // 留点时间生成报告 测试用 实际情况需将reportId存入数据库, 间隔时间请求 getResquestInfo
            $this->getResquestInfo('reports', $res['reportId']);
        }
    }





    // 获取 报告/快照 请求信息
    public function getResquestInfo($type, $id)
    {
        if (!$id) {
            return false;
        }

        $header_ = $this->returnHeader();
        $url = $header_['host'] . "/v2/sp/$type/" . $id;
        $res = $this->sendCurlGetRequest($url, $header_['header']);

        $res = json_decode($res, true);
        $this->local_log($res);

        if ( $res['status'] === 'SUCCESS' ) {
            $data = $this->reportDownload($res['location']);
            echo file_get_contents($data);
            $this->local_log($data);

        }
    }

    // 下载报告
    public function reportDownload($location)
    {
        if (!$location) {
            return false;
        }

        $header = $this->returnHeader()['header'];

        $redirect_url = $this->sendCurlGetRequest($location, $header);
        
        if ($redirect_url) {
            $file = $this->downloadFile($redirect_url);
            $path = $file["save_path"];
            $size = $file["file_size"];
            if($size == 0)
            {   
                // 删除文件
                $this->delFile($path);
                return false;
            }

            // 解压
            $res = $this->unzipGz($path);
            return $res;
        }
        die;
    }


    public function downloadFile($url, $save_dir = '.') 
    {  
        if ( !$url ) {  
            return false;  
        }  

        global $id;
        $filename = date("Y-m-d")."_".$id.".json.gz";
        //创建保存目录  
        if (!file_exists($save_dir) && !mkdir($save_dir, 0777, true)) 
        {  
            echo "目录失败";
            return false;  
        } 
        $file = $save_dir."/". $filename; 
        ob_start();  
        readfile($url);  
        $content = ob_get_contents();  
        ob_end_clean();  
         
        //文件大小  
        $size = strlen($content);
        $fp2 = @fopen($file, 'a');  
        fwrite($fp2, $content);  
        fclose($fp2);  
        unset($content, $url); 
        
        $return  = array(  
            'save_path' => $file,  
            'file_size' => $size  
        ); 
        return $return ;
    } 

    // 解压GZ文件
    public function unzipGz($path)
    {
        if (!file_exists($path)) {
            return false;
        }
        $buffer_size = 4096; // read 4kb at a time
        $out_file_name = str_replace('.gz', '', $path);
        $file = gzopen($path, 'rb');
        $out_file = fopen($out_file_name, 'wb');
        $str='';
        while(!gzeof($file)) {
         fwrite($out_file, gzread($file, $buffer_size));
        }
        fclose($out_file);
        gzclose($file);
        $this->delFile($path);
        return $out_file_name;
    }

    // 删除文件
    public function delFile($path)
    {
        file_exists($path) && unlink($path);
        return ;
    }

    // 返回公共请求头
    public function returnHeader()
    {
        switch ( $this->region ) {
            case 'NA':
                $host = 'https://advertising-api.amazon.com';
                break;
            case 'EU':
                $host = 'https://advertising-api-eu.amazon.com';
                break;
            case 'FE':
                $host = 'https://advertising-api-fe.amazon.com';
                break;
            default:
                $host = "https://advertising-api.amazon.com";
                break;
        }
        $header = array(
            "Authorization: Bearer $this->token",
            "Amazon-Advertising-API-ClientId:$this->client_id",
            "Access-Control-Allow-Credentials: true",
            "Content-Type:application/json",
            "User-Agent:test1",
            "Amazon-Advertising-API-Scope:$this->profile_id"
        );
        return array('host'=>$host, 'header'=>$header);
    }

	// 模拟post请求
    public function sendCurlPostRequest($url, $curlData, $header)
    {
        $curl = curl_init();
        curl_setopt ($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl,CURLOPT_TIMEOUT,120);
        curl_setopt($curl,CURLOPT_ENCODING,'gzip');
        curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
        curl_setopt ($curl, CURLOPT_POST, 1);
        curl_setopt ($curl, CURLOPT_POSTFIELDS, $curlData);
        // https请求 不验证证书和hosts
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        $result = curl_exec($curl);

        if ( $result == false ){
            var_dump(curl_error($curl));
            die('CURL ERROR');
        }
        curl_close ($curl);

        return $result;
    }

    // 模拟get请求
    public function sendCurlGetRequest($url, $headers){
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_URL,$url);

        if($headers){
            curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
        }

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        // https请求 不验证证书和hosts
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        $output = curl_exec($ch);

        if ( $output == false ){
            var_dump(curl_error($ch));
            curl_close($ch);

            die('CURL ERROR');
        }

        $redirect_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

        curl_close($ch);

        // 判断重定向
        if ( $url != $redirect_url ) {
            return $redirect_url;
        }
        return $output;
    }

    // 本地打印结果
    public function local_log($msg)
    {
        if (!is_string($msg)) {
            $msg = json_encode($msg);
        }
        file_put_contents('local_log.log', date("Y-m-d H:i:s") . "\t" . $msg . "\n\n" .PHP_EOL, FILE_APPEND);
    }


到这就基本结束了,剩下的就是自己的业物逻辑处理了。 上面这个方法基本都是只写了一半, 都只是先获取数据 。现在我也还没彻底完成这个功能,只是先记录一下API的请求过程。防止过两天就忘了…毕竟刚完成的印象比较深刻。

欢迎互相交流…

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 35
    评论
亚马逊API接口申请是指开发者向亚马逊公司申请使用其提供的API接口的过程。亚马逊提供了一系列的API接口,使开发者能够通过编程的方式与亚马逊的服务进行交互,例如获取商品信息、下单和查询订单等操作。 首先,开发者需要创建一个亚马逊开发者账户,并登录开发者控制台。在控制台中,开发者可以查看和管理已经申请的API接口以及相关的信息。在申请API接口之前,开发者需要先确保自己的应用符合亚马逊的开发者政策和要求。 接下来,开发者需要选择所需的API接口并点击申请按钮。在申请过程中,开发者需要提供一些必要的信息,例如应用名称、描述、用户访问权限和使用场景等。亚马逊会根据开发者提供的信息评估申请,并在一定时间内进行审查和审核。 一般情况下,亚马逊会在申请提交后的几个工作日内完成审核。审核结果可能会以电子邮件的形式通知开发者。如果申请被批准,开发者可以在控制台中获取到相应的API密钥和凭证,用于在应用程序中进行API调用。 在使用亚马逊API接口期间,开发者需要遵守亚马逊的使用条款和政策,确保正确、合法地使用API接口亚马逊也会不定期地对开发者的应用进行审核和监测,以保证接口的正常使用和数据的安全性。 综上所述,亚马逊API接口申请的过程需要开发者进行账户注册、选择接口、提供必要信息、等待审核以及遵守相关政策和要求。通过申请并正确使用API接口,开发者可以高效地与亚马逊的服务进行交互,从而开发出丰富的商业应用和服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值