highsidelabs/amazon-business-api

Amazon 商务 API 的 PHP 客户端

1.3.0 2024-04-04 20:14 UTC

This package is auto-updated.

Last update: 2024-09-04 21:18:35 UTC


README

Total downloads Latest stable version License

Amazon Business API for PHP

用于连接 Amazon 商务 API 的 PHP 库。

相关包

  • jlevers/selling-partner-api: 一个用于 Amazon 卖家 API 的 PHP 库,与这个包具有几乎相同的接口。我们最受欢迎的包。
  • highsidelabs/laravel-spapi: 一个用于上述包的 Laravel 包装器,使得在 Laravel 项目中集成 SP API 变得快速且简单。
  • highsidelabs/walmart-api: 一个用于 Walmart 卖家和供应商 API 的 PHP 库,包括市场、直接发货供应商、内容提供者和仓储供应商 API。

此包由 Highside Labs 开发和维护。如果您需要支持与 Amazon 的 (或任何其他电子商务平台的) API 集成,我们将非常乐意帮助!请给我们发邮件至 hi@highsidelabs.co。我们期待与您交流 :)

如果您觉得我们的任何包很有用,请考虑 成为赞助商,或通过下面的按钮进行捐款。我们感激您提供的任何支持!

Donate to Highside Labs

(在我们的博客中有关于使用此包的更深入指南,这里。)

功能

  • 支持截至 2022 年 11 月 13 日的所有 Amazon 商务 API 操作(见此处 以获取所有调用的文档链接)
  • 支持使用 IAM 用户和 IAM 角色ARN创建的应用程序(文档

安装

composer require highsidelabs/amazon-business-api

目录

查看下面的 入门 部分以获取快速概述。

此 README 分为几个部分

入门

我们写了一篇博客文章,更详细地介绍了如何连接到 Amazon 商务 API,这里。如果您需要更多帮助进行设置,请查看。

先决条件

您需要一些东西才能开始

  • 一个 Amazon 商务 API 开发者账户
  • 一个配置为使用 Amazon 商务 API 的 AWS IAM 用户或角色
  • 一个 Amazon 商务 API 应用程序

如果您想了解如何设置这些内容的更多信息,请查看这篇博客文章。它提供了整个设置过程的详细说明。该指南针对的是Selling Partner API,但所有设置步骤对于Amazon Business API都是相同的。

设置

Configuration构造函数接受一个参数:一个关联数组,包含连接到Amazon Business API所需的所有配置信息

$config = new AmazonBusinessApi\Configuration([
    'lwaClientId' => '<LWA client ID>',
    'lwaClientSecret' => '<LWA client secret>',
    'lwaRefreshToken' => '<LWA refresh token>',
    'awsAccessKeyId' => '<AWS access key ID>',
    'awsSecretAccessKey' => '<AWS secret access key>',
    // If you're not working in the North American marketplace, change
    // this to another endpoint from lib/Endpoint.php
    'endpoint' => AmazonBusinessApi\Endpoint::NA,
]);

如果您使用IAM角色ARN而不是用户ARN创建了Amazon Business API应用程序,请将角色ARN传递到配置数组中

$config = new AmazonBusinessApi\Configuration([
    'lwaClientId' => '<LWA client ID>',
    'lwaClientSecret' => '<LWA client secret>',
    'lwaRefreshToken' => '<LWA refresh token>',
    'awsAccessKeyId' => '<AWS access key ID>',
    'awsSecretAccessKey' => '<AWS secret access key>',
    // If you're not working in the North American marketplace, change
    // this to another endpoint from lib/Endpoint.php
    'endpoint' => AmazonBusinessApi\Endpoint::NA,
    'roleArn' => '<Role ARN>',
]);

Configuration类的lwaClientIdlwaClientSecretlwaRefreshTokenawsAccessKeyIdawsSecretAccessKeyendpoint属性存在getter和setter方法。这些方法的命名与它们所交互的属性名称一致:getLwaClientIdsetLwaClientIdgetLwaClientSecret等。

然后可以将$config传递给任何AmazonBusinessApi\Api\*Api类的构造函数。请参阅示例部分以获取完整的示例。

配置选项

传递给Configuration构造函数的数组可以接受以下键

  • lwaClientId (string):必需。用于执行API请求的SP API应用程序的LWA客户端ID。
  • lwaClientSecret (string):必需。用于执行API请求的SP API应用程序的LWA客户端密钥。
  • lwaRefreshToken (string):必需。用于执行API请求的SP API应用程序的LWA刷新令牌。
  • awsAccessKeyId (string):必需。具有SP API ExecuteAPI权限的AWS IAM用户访问密钥ID。
  • awsSecretAccessKey (string):必需。具有SP API ExecuteAPI权限的AWS IAM用户密钥。
  • endpoint (array):必需。包含一个url键(端点URL)和一个region键(AWS区域)的数组。在lib/Endpoint.php中有这些数组的预定义常量:(NAEUFE。有关详细信息,请参阅此处
  • accessToken (string):由刷新令牌生成的访问令牌。
  • accessTokenExpiration (int):与accessToken过期时间相对应的Unix时间戳。如果提供了accessToken,则必须提供accessTokenExpiration(反之亦然)。
  • onUpdateCredentials (callable|Closure):当生成新访问令牌时调用的回调函数。该函数应接受一个类型为AmazonBusinessApi\Credentials的单一参数。
  • roleArn (string):如果您使用AWS IAM角色ARN而不是用户ARN设置了Amazon Business API应用程序,请在此处传递该ARN。
  • authenticationClient (GuzzleHttp\ClientInterface):可选的GuzzleHttp\ClientInterface对象,用于从刷新令牌生成访问令牌
  • authorizationSigner (AmazonBusinessApi\Contract\AuthorizationSignerContract):可选的AmazonBusinessApi\Contract\AuthorizationSignerContract实现。请参阅自定义授权签名者部分
  • requestSigner (AmazonBusinessApi\Contract\RequestSignerContract):可选的AmazonBusinessApi\Contract\RequestSignerContract实现。请参阅自定义请求签名者部分。

示例

此示例假定您可以访问Product Search Amazon Business API角色,但该格式适用于任何Amazon Business API请求。

<?php
require_once(__DIR__ . '/vendor/autoload.php');

use AmazonBusinessApi\Api\ProductSearchV20200826Api as ProductSearchApi;
use AmazonBusinessApi\Configuration;
use AmazonBusinessApi\Endpoint;

$config = new Configuration([
    'lwaClientId' => 'amzn1.application-oa2-client.....',
    'lwaClientSecret' => 'abcd....',
    'lwaRefreshToken' => 'Aztr|IwEBI....',
    'awsAccessKeyId' => 'AKIA....',
    'awsSecretAccessKey' => 'ABCD....',
    // If you're not working in the North American marketplace, change
    // this to another endpoint from lib/Endpoint.php
    'endpoint' => Endpoint::NA
]);

$api = new ProductSearchApi($config);
try {
    $result = $api->productsRequest('B0B96H7LGX', 'US', 'en_US', 'johndoe@acmecorp.com');
    print_r($result);
} catch (Exception $e) {
    echo 'Exception when calling ProductSearchApi->productsRequest: ', $e->getMessage(), PHP_EOL;
}

?>

调试模式

当您进行API请求时,要获取调试输出,可以调用$config->setDebug(true)。默认情况下,调试输出通过php://output输出到stdout,但您可以使用$config->setDebugFile('<path>')将其重定向到文件。

<?php
require_once(__DIR__ . '/vendor/autoload.php');

use AmazonBusinessApi\Configuration;

$config = new Configuration([/* ... */]);
$config->setDebug(true);
// To redirect debug info to a file:
$config->setDebugFile('./debug.log');

支持的 API 段

每个API类名都包含API的版本号。这允许在单个包版本中访问同一API的多个版本。这使得类名看起来有些丑陋,但允许同时使用同一API段的新旧版本,这在许多情况下非常有用。可以通过将use语句格式化如下来修复这些丑陋的名称:

use AmazonBusinessApi\Api\ProductSearchV20200826Api as ProductSearchApi;
use AmazonBusinessApi\Model\ProductSearchV20200826 as ProductSearch;

这也意味着,如果引入了一个现有API的新版本,则可以更新库以包含该新版本,而不会引入破坏性更改。

使用模型类

大多数操作都与其一个或多个模型相关联。这些模型是包含进行某种类型API请求所需的数据或包含给定请求类型返回的数据的类。所有模型都共享相同的一般接口:您可以在初始化期间指定模型的所有属性,或者事后设置每个属性。以下是一个使用用户管理API的AccountHolder模型的示例(文档),(源代码)。

AccountHolder模型有三个属性:emailgiven_namefamily_name。(如果您想知道如何确定模型具有哪些属性,请查看上面的docs链接。)要创建具有所有这些属性设置的AccountHolder模型实例

$accountHolder = new AmazonBusinessApi\Model\UserManagementV20210830Api\AccountHolder([
    'email' => 'janedoe@acmecorp.com',
    'given_name' => 'Jane',
    'family_name' => 'Doe'
]);

或者,您还可以创建一个Buyer模型实例,然后填充其字段

$accountHolder = new AmazonBusinessApi\Model\UserManagementV20210830Api\AccountHolder();
$accountHolder->email = 'janedoe@acmecorp.com';
$accountHolder->givenName = 'Jane';
$accountHolder->familyName = 'Doe';

每个模型也有您可能期望的属性访问器

$accountHolder->email;          // -> 'janedoe@acmecorp.com'
$accountHolder->givenName;      // -> 'Jane'
$accountHolder->familyName;     // -> 'Doe'

模型可以(并且通常确实)具有其他模型作为属性

$requestBody = new AmazonBusinessApi\Model\UserManagementV20210830Api\CreateBusinessUserAccountRequest([
    // ...
    'account_holder' => $accountHolder,
    // ...
]);

$requestBody->accountHolder;        // -> [AccountHolder instance]
$requestBody->requestBody->email;  // -> 'janedoe@acmecorp.com'

如果模型属性应该是一个数组,其类型签名将类似于ModelClass[](注意尾随的[])。例如,OrderingV1ApiplaceOrder方法接受一个名为PlaceOrderRequest的模型,其属性名为line_itemsline_items的类型是RequestLineItem[],属性应设置如下

use AmazonBusinessApi\Model\OrderingV1;

$placeOrderRequest = new OrderingV1\PlaceOrderRequest([
    // ...
    'line_items' => [
        new OrderingV1\RequestLineItem([
            'quantity' => 1,
            // ...
        ]),
        new OrderingV1\RequestLineItem([
            'quantity' => 2,
            // ...
        ]),
    ],
    // ...
]);

响应头

Amazon在每次SP API响应中包含一些有用的头信息。如果出于任何原因需要这些头信息,可以通过在响应对象上调用getHeaders()来获取响应头信息的关联数组。例如

<?php
require_once(__DIR__ . '/vendor/autoload.php');

use AmazonBusinessApi\Api\ProductSearchV20200826Api as ProductSearchApi;
use AmazonBusinessApi\Configuration;
use AmazonBusinessApi\Endpoint;

$config = new Configuration([...]);
$api = new ProductSearchApi($config);
try {
    $result = $api->productsRequest('B0B96H7LGX', 'US', 'en_US', 'johndoe@acmecorp.com');
    $headers = $result->headers;
    print_r($headers);
} catch (Exception $e) {
    echo 'Exception when calling ProductSearchApi->productsRequest: ', $e->getMessage(), PHP_EOL;
}

自定义授权签名者

您可能需要在签名API请求时执行自定义操作。您可以通过创建一个实现AuthorizationSignerContract接口并将其传递到Configuration构造函数数组中来创建自定义授权签名者。

// CustomAuthorizationSigner.php
use Psr\Http\Message\RequestInterface;
use AmazonBusinessApi\Contract\AuthorizationSignerContract;

class CustomAuthorizationSigner implements AuthorizationSignerContract
{
    public function sign(RequestInterface $request, Credentials $credentials): RequestInterface
    {
        // Calculate request signature and request date.
        
        $requestDate = '20220426T202300Z';
        $signatureHeaderValue = 'some calculated signature value';
        
        $signedRequest = $request
            ->withHeader('Authorization', $signatureHeaderValue)
            ->withHeader('x-amz-date', $requestDate);
        
        return $signedRequest;
    }

    // ...
}

// Consumer code
<?php
require_once(__DIR__ . '/vendor/autoload.php');

use AmazonBusinessApi\Api\ProductSearchV20200826Api as ProductSearchApi;
use AmazonBusinessApi\Configuration;
use AmazonBusinessApi\Endpoint;
use CustomAuthorizationSigner;

$config = new Configuration([
    ..., 
    'authorizationSigner' => new CustomAuthorizationSigner(),
]);
$api = new ProductSearchApi($config);
try {
    $result = $api->productsRequest('B0B96H7LGX', 'US', 'en_US', 'johndoe@acmecorp.com');
    print_r($result);
} catch (Exception $e) {
    echo 'Exception when calling ProductSearchApi->productsRequest: ', $e->getMessage(), PHP_EOL;
}

自定义请求签名者

您也可能需要自定义整个请求签名过程——例如,如果您需要在签名请求的过程中调用外部服务。您可以通过创建一个实现RequestSignerContract接口的实例,并将其传递到Configuration构造函数数组中来实现这一点。

// RemoteRequestSigner.php
use Psr\Http\Message\RequestInterface;
use AmazonBusinessApi\Contract\RequestSignerContract;

class RemoteRequestSigner implements RequestSignerContract
{
    public function signRequest(RequestInterface $request): RequestInterface {
        // Sign request by sending HTTP call
        // to external/separate service instance.
        
        return $signedRequest;
    }
}

// Consumer code
<?php
require_once(__DIR__ . '/vendor/autoload.php');

use AmazonBusinessApi\Api\ProductSearchV20200826Api as ProductSearchApi;
use AmazonBusinessApi\Configuration;
use AmazonBusinessApi\Endpoint;
use RemoteRequestSigner;

$config = new Configuration([
    ..., 
    'requestSigner' => new RemoteRequestSigner(),
]);
$api = new ProductSearchApi($config);
try {
    $result = $api->productsRequest('B0B96H7LGX', 'US', 'en_US', 'johndoe@acmecorp.com');
    print_r($result);
} catch (Exception $e) {
    echo 'Exception when calling ProductSearchApi->productsRequest: ', $e->getMessage(), PHP_EOL;
}