specbee/shopify

Shopify PHP SDK 用于与 Shopify API 交互。

2020.01.2 2021-06-21 19:24 UTC

README

这是一个简单的 Shopify PHP SDK,用于私有应用程序轻松与 Shopify API 交互。
Travis Build Status

Shopify API 文档 | Packagist | 构建状态

特性包括

  • 轻松执行 GET、PUT、POST 和 DELETE 资源操作
  • 处理和验证传入的 webhook
  • 自动速率限制,避免 API 调用出错

设置/安装

依赖于 guzzlehttp/guzzle
通过 Composer 获取...

获取稳定版本
composer require donutdan4114/shopify:v2020.01.*

获取最新不稳定版本
composer require donutdan4114/shopify:dev-master

API 版本

此包现在包括与 Shopify API 版本命名约定匹配的版本。版本格式为 vYYYY.MM.V#,其中增加 V# 不会破坏向后兼容性。请查看发行说明中的更改日志,以了解可能破坏向后兼容性的更改。

2020.01 版本中的新功能

此更新利用了 Shopify API 中的新分页系统。不再支持 page 查询参数。自动遍历页面的“资源分页器”将自动处理此更改。

如果您使用 page 参数有自定义代码,则需要像下面这样更新您的代码

$client = new Shopify\PublicApp(/* $args */);

// Get the first 25 products.
$result = $client->get('products', ['query' => ['limit' => 25]]);

// If you're paginating in the same request directly after the first API call
// you can simply use the getNextPage() method.
if ($client->hasNextPage()){
  // Get the next 25 products.
  $result = $client->getNextPage();
}

// If you're doing multiple page requests or client requests you
// will need to keep track of the page_info params yourself.
$page_info = $client->getNextPageParams();

// To get the next page you can now just pass $page_info into the query.
// This will get the next 25 products ("limit" is automatically set).
$result = $client->get('products', ['query' => $page_info]);

私有 & 公开应用程序

您可以使用此库创建私有或公开应用程序。使用私有应用程序更容易,因为它们不需要 access_token。但是,如果您想创建一个公开可访问的应用程序,您必须使用公共应用程序系统。

私有应用程序

只需使用 shop_domainapi_keypasswordshared_secret 实例化私有应用程序。

$client = new Shopify\PrivateApp($SHOPIFY_SHOP_DOMAIN, $SHOPIFY_API_KEY, $SHOPIFY_PASSWORD, $SHOPIFY_SHARED_SECRET);
$result = $client->get('shop');

公开应用程序

您必须首先设置公开应用程序。请查看文档。您需要一个授权 URL。

session_start();
$client = new Shopify\PublicApp($_GET['shop'], $APP_API_KEY, $APP_SECRET);

// You set a random state that you will confirm later.
$random_state = 'client-id:' . $_SESSION['client_id'];

$client->authorizeUser('[MY_DOMAIN]/redirect.php', [
  'read_products',
  'write_products',
], $random_state);

此时,用户将被带到他们的商店以授权应用程序使用他们的信息。如果用户接受,他们将被带到重定向 URL。

session_start();
$client = new Shopify\PublicApp($_GET['shop'], $APP_API_KEY, $APP_SECRET);

// Used to check request data is valid.
$client->setState('client-id:' . $_SESSION['client_id']);

if ($token = $client->getAccessToken()) {
  $_SESSION['shopify_access_token'] = $token;
  $_SESSION['shopify_shop_domain'] = $_GET['shop'];
  header("Location: dashboard.php");
}
else {
  die('invalid token');
}

dashboard.php 中,您可以通过设置 access_token 开始进行 API 请求。

session_start();
$client = new Shopify\PublicApp($_SESSION['shopify_shop_domain'], $APP_API_KEY, $APP_SECRET);
$client->setAccessToken($_SESSION['shopify_access_token']);
$products = $client->getProducts();

方法

GET

从 API 获取资源信息。

$client = new Shopify\PrivateApp($SHOPIFY_SHOP_DOMAIN, $SHOPIFY_API_KEY, $SHOPIFY_PASSWORD, $SHOPIFY_SHARED_SECRET);
$result = $client->get('shop');

$result 是解码后的 JSON stdClass

object(stdClass)#33 (1) {
  ["shop"]=>
  object(stdClass)#31 (44) {
    ["id"]=>
    int([YOUR_SHOP_ID])
    ["name"]=>
    string(15) "[YOUR_SHOP_NAME]"
    ["email"]=>
    string(22) "[YOUR_SHOP_EMAIL]"
    ["domain"]=>
    string(29) "[YOUR_SHOP_DOMAIN]"
    ...
  }
}

通过传递查询参数获取产品 ID

$result = $client->get('products', ['query' => ['fields' => 'id']]);
foreach($result->products as $product) {
  print $product->id;
}

POST

使用 POST 请求创建新内容。

$data = ['product' => ['title' => 'my new product']];
$result = $client->post('products', $data);

PUT

使用给定的 ID 更新现有内容。

$data = ['product' => ['title' => 'updated product name']];
$result = $client->put('products/' . $product_id, $data);

DELETE

轻松使用给定的 ID 删除资源。

$client->delete('products/' . $product_id);

简单包装器

为了更轻松地处理常见的 API 资源,有几个简写函数。

// Get shop info.
$shop_info = $client->getShopInfo();

// Get a specific product.
$product = $client->getProduct($product_id);

// Delete a specific product.
$client->deleteProduct($product_id);

// Create a product.
$product = $client->createProduct(['title' => 'my new product']);

// Count products easily.
$count = $client->getProductsCount(['updated_at_min' => time() - 3600]);

// Easily get all products without having to worry about page limits.
$products = $client->getProducts();

// This will fetch all products and will make multiple requests if necessary.
// You can easily supply filter arguments.
$products = $client->getProducts(['query' => ['vendor' => 'MY_VENDOR']]);

// For ease-of-use, you should use the getResources() method to automatically handle Shopify's pagination.
// This will ensure that if there are over 250 orders, you get them all returned to you.
$orders = $client->getResources('orders', ['query' => ['fields' => 'id,billing_address,customer']]);

// If efficiency and memory limits are a concern,  you can loop over results manually.
foreach ($this->client->getResourcePager('products', 25) as $product) {
  // Fetches 25 products at a time.
  // If you have 500 products, this will create 20 separate requests for you.
  // PHP memory will only be storing 25 products at a time, which keeps thing memory-efficient.
}

解析传入的 webhook

如果您在您的网站上设置了一个用于接受传入 Shopify webhook 的路由,您可以轻松解析数据并验证内容。有两种方法可以验证 webhook:手动或使用客户端。

// Process webhook manually.
$webhook = new Shopify\IncomingWebhook($SHOPIFY_SHARED_SECRET);
try {
  $webhook->validate();
  $data = $webhook->getData();
} catch (Shopify\WebhookException $e) {
  // Errors means you should not process the webhook data.
  error_log($e->getMessage());
}

// Process webhook using the $client.
try {
  $data = $client->getIncomingWebhook($validate = TRUE);
} catch (Shopify\ClientException $e) {
  error_log($e->getMessage());
}
if (!empty($data)) {
  // Do something with the webhook data.
}

错误处理

任何 API 错误都会抛出一个 Shopify\ClientException 实例。

try {
  $response = $client->put('products/BAD_ID');
} catch (Shopify\ClientException $e) {
  // Get request errors.
  error_log($e->getErrors());
  // Get last response object.
  $last_response = $e->getLastResponse();
  $code = $e->getCode();
  $code = $last_response->getStatusCode();
}

API 限制处理

此类可以根据 Shopify 的“漏桶”算法为您处理 API 速率限制。它将自动减慢请求速度,以免触及速率限制器。您可以使用以下方法禁用此功能:

$client->rate_limit = FALSE;

您可以使用 $client->getCallLimit()$client->callLimitReached() 方法来实现自己的速率限制逻辑。

测试

可以使用 phpunit 来运行测试。由于测试实际上会修改连接的商店,您必须显式允许运行测试,方法是将环境变量 SHOPIFY_ALLOW_TESTS 设置为 TRUE。否则,您将收到类似的消息

Shopify tests cannot be run.
Running Shopify tests will delete all connected store info.
Set environment variable SHOPIFY_ALLOW_TESTS=TRUE to allow tests to be run.