zfr/zfr-stripe

用于与 Stripe REST API 交互的 PHP 库


README

Latest Stable Version

ZfrStripe 是一个基于 Guzzle 的现代 PHP 库,用于 Stripe 支付系统

依赖

安装

仅支持使用 Composer 安装 ZfrStripe

php composer.phar require 'zfr/zfr-stripe:3.*'

教程

首先,您需要实例化 Stripe 客户端,传递您的私有 API 密钥(您可以在 Stripe 设置中找到它)

$client = new StripeClient('my-api-key');

您可以使用 setApiKey 方法更改客户端的 API 密钥。如果您使用 Stripe Connect,并且需要同时进行自己的 API 调用和代表用户的 API 调用,这将非常有用。

当前支持的最新 API 版本是 2015-10-16。您也可以显式地使用第二个参数指定客户端的版本

$client = new StripeClient('my-api-key', '2015-10-16');

版本控制

Stripe API 有一个奇特(但非常有用)的 版本控制策略,使得正确版本控制变得困难。技巧是,Stripe 可能会改变在新版本中如何传递某些属性(因此对旧版本是向后兼容的),但仍然引入新端点,这些端点也将对旧版本可用。

因此,每当 Stripe API 发布新的日期版本时,ZfrStripe 都将采用此策略

  • 如果引入了新的端点,但没有更改旧的端点,则将为所有支持的版本添加新的端点。标记一个新的次要版本,并将默认 Stripe 版本设置为最新版本。
  • 如果没有引入新的端点,但某些参数有所更改,则创建一个新的描述符,从而支持多个版本。标记一个新的次要版本,并将默认 Stripe 版本设置为最新版本。
  • 如果没有引入新的端点,并且没有参数更改,则标记一个新的次要版本,并将默认 Stripe 版本设置为最新版本。
  • 如果现有端点通过更改其 URL 进行更新,则发布 ZfrStripe 的大版本,因为无法保证兼容性。

目前,ZfrStripe 接受以下 Stripe API 版本:2015-02-182015-03-242015-04-072015-06-152015-07-072015-07-132015-07-282015-08-072015-08-192015-09-032015-09-082015-09-232015-10-012015-10-122015-10-16。我会尽快更新库以适应新版本。

如果您需要支持到 2014-03-28 的旧版本,请使用 ZfrStripe 的 v2 分支。如果您需要支持更旧的版本,请使用 ZfrStripe 的 v1 分支。

如何使用它?

使用客户端很简单。例如,这是创建新费用的方式:

$details = $client->createCharge([
    'amount'   => 500,
    'currency' => 'EUR',
    'customer' => 'cus_37EGGf4LMGgYy8'
]);

参数与官方文档(任何参考,您还可以检查 ZfrStripe\Client\ServiceDescription\Stripe-v1.1.php 文件)具有直接的逐个对应关系。要了解响应的外观,请参阅 官方 API 参考

使用不同的 Stripe API 版本

对于每个请求,我们向 Stripe 发送 "Stripe-Version" 标头。通常,最好的方法是在您的 Stripe 控制台中全局升级 API 版本。然而,您可能希望在代码的不同部分使用不同的版本,或者在开发过程中测试新功能,而不必全局更改整个 Stripe 账户。

为此,您可以在构造函数中显式设置所需版本。示例

$stripeClient = new StripeClient('my-api-key', '2014-03-28');

您可以通过使用 setApiVersion 方法动态更改版本。

$stripeClient = new StripeClient('my-api-key', '2014-03-28');

// Responses will be formatted according to the 2014-03-28 version...

$stripeClient->setApiVersion('2014-08-20');

// Responses will now be formatted according to the 2014-08-20 version...

或者,您也可以创建不同的 Stripe 客户端。

Stripe Connect

如果您使用 Stripe Connect,您将需要在代表您的客户端进行 API 调用。您无需做任何特殊操作:只需使用带有客户的访问令牌的 setApiKey 方法即可。

$client->setApiKey('my-customers-token');
// All API calls will be made on behalf of this customer now!

请注意,如果您想再次使用自己的密钥,您需要调用此方法的新调用。

展开

所有 Stripe API 请求都支持展开响应中的一些嵌套对象。因此,ZfrStripe 通过 expand 参数支持此功能,该参数必须是一个数组。

$details = $client->getCharges([
    'expand' => ['customer']
]);

迭代器

您可能想检索客户、事件或收费的列表。您无需手动执行所有请求,可以使用迭代器。ZfrStripe 为所有可迭代的资源提供迭代器。

$iterator = $client->getCustomersIterator();

foreach ($iterator as $user) {
    // Do something
}

默认情况下,ZfrStripe 每次API调用检索100个元素(这是 Stripe API 允许的最大值)。您可以通过使用 setPageSize 方法降低此限制。您还可以使用 setLimit 方法设置要检索的结果的上限。

最后,当使用迭代器时,您仍然可以使用 API 参数。例如,这将检索所有具有事件 customer.subscription.updated 的事件,每50个元素执行一次新的 API 调用(这意味着只有最多50个元素存储在内存中),并设置最大500个元素检索的限制。

$iterator = $client->getEventsIterator(array('type' => 'customer.subscription.updated'));
$iterator->setPageSize(50);
$iterator->setLimit(500);

foreach ($iterator as $event) {
    // Do something
}

您还可以利用 Stripe 的基于游标的分页。

$iterator = $client->getInvoicesIterator(['starting_after' => 'in_abcdef');

foreach ($iterator as $invoices) {
    // Do something
}

ZfrStripe 会负责获取批次中的最后一个项目,提取其 ID,然后继续进行请求,直到没有更多数据为止!

幂等性键

最近,Stripe 添加了对幂等性键的支持。此键添加到每个 POST 请求中,只要键相同,就可以防止操作被重复执行。您负责生成自己的幂等性键。

$key = 'ABC';

$stripeClient->createSubscription([
    'id'              => 'cus_abc',
    'plan'            => 'planA',
    'idempotency_key' => $key
]);

$stripeClient->createSubscription([
    'id'              => 'cus_abc',
    'plan'            => 'planA',
    'idempotency_key' => $key
]);

// Only one subscription is created

未记录的功能

在玩 Stripe API 时,我发现 API 有一些未记录但仍然可用的过滤功能。因此,我已经将这些功能中的一些添加到这个库中,但是请务必谨慎使用,因为 Stripe 可能会删除它们(或者可能在将来正式记录它们)。以下是实现的功能列表

过滤事件

您可以使用 object_id 参数根据对象 ID 过滤事件。这取决于上下文。例如,如果您专门检索订阅事件,则 object_id 将允许根据订阅进行过滤。

$events = $client->getEvents(['object_id' => 'cus_abc', 'type' => 'customer.*']);
检索已删除的客户

您可以通过使用 deleted 布尔值检索已删除的客户。

$customers = $client->getCustomers(['deleted' => true]);
检索未支付的费用

您可以通过使用 paid 布尔值检索未支付的费用。

$notPaidCharges = $client->getCharges(['paid' => false]);
检索分摊项目

您可以通过使用 proration 布尔值仅检索分摊发票项目。

$invoiceItems = $client->getInvoiceItems(['proration' => true]);

异常

ZfrStripe 尽其所能抛出有用的异常。可能会发生两种类型的异常

  • Guzzle 异常:默认情况下,Guzzle 会根据在服务描述中定义的规则在发送实际请求之前自动验证参数。如果您遇到这些异常,很可能是代码有误。
  • ZfrStripe 异常:如果 Stripe 侧发生错误,则抛出这些异常。每个异常都实现了 ZfrStripe\Exception\ExceptionInterface

以下都是异常

  • ZfrStripe\Exception\UnauthorizedException:您的 API 密钥可能不正确...
  • ZfrStripe\Exception\ApiRateLimitException:当您达到 Stripe API 限制时发生。
  • ZfrStripe\Exception\BadRequestException:当发生 400 错误代码时发生。
  • ZfrStripe\Exception\CardErrorException:表示任何卡片错误。根据Stripe的说法,当参数有效但请求失败时(例如,如果卡片CVC无效),会发生此错误。
  • ZfrStripe\Exception\NotFoundException:当客户端收到404异常时抛出。
  • ZfrStripe\Exception\RequestFailedException:表示通用的402错误。
  • ZfrStripe\Exception\ServerErrorException:Stripe可能出错的所有错误...

用法

use ZfrStripe\Exception\TransactionErrorException;

try {
    $client->createCard([
        'card' => [
            'number'    => '4242424242424242',
            'exp_month' => '01',
            'exp_year'  => '2016'
        ]
    ]);
} catch (CardErrorException $exception) {
    // Seems we couldn't create the card, maybe because it's invalid
    $why = $exception->getMessage();

    // Let's also get the response to have more info:
    $response = $exception->getResponse();
} catch (\Exception $exception) {
    // Catch any other exception...
}

完整参考

以下是所有方法的完整列表

与CHARGE相关的函数

  • array captureCharge(array $args = array())
  • array createCharge(array $args = array())
  • array getCharge(array $args = array())
  • array getCharges(array $args = array())
  • array refundCharge(array $args = array())
  • array updateCharge(array $args = array())

与CUSTOMER相关的函数

  • array createCustomer(array $args = array())
  • array deleteCustomer(array $args = array())
  • array getCustomer(array $args = array())
  • array getCustomers(array $args = array())
  • array updateCustomer(array $args = array())

与CARD相关的函数

  • array createCard(array $args = array())
  • array deleteCard(array $args = array())
  • array getCard(array $args = array())
  • array getCards(array $args = array())
  • array updateCard(array $args = array())

与RECIPIENT CARD相关的函数

  • array createRecipientCard(array $args = array())
  • array deleteRecipientCard(array $args = array())
  • array getRecipientCard(array $args = array())
  • array getRecipientCards(array $args = array())
  • array updateRecipientCard(array $args = array())

与SUBSCRIPTION相关的函数

  • array cancelSubscription(array $args = array())
  • array createSubscription(array $args = array())
  • array getSubscription(array $args = array())
  • array getSubscriptions(array $args = array())
  • array updateSubscription(array $args = array())

与PLAN相关的函数

  • array createPlan(array $args = array())
  • array deletePlan(array $args = array())
  • array getPlan(array $args = array())
  • array getPlans(array $args = array())
  • array updatePlan(array $args = array())

与COUPON相关的函数

  • array createCoupon(array $args = array())
  • array deleteCoupon(array $args = array())
  • array getCoupon(array $args = array())
  • array getCoupons(array $args = array())
  • array updateCoupon(array $args = array())

与DISCOUNT相关的函数

  • array deleteCustomerDiscount(array $args = array())
  • array deleteSubscriptionDiscount(array $args = array())

与INVOICE相关的函数

  • array createInvoice(array $args = array())
  • array getInvoice(array $args = array())
  • array getInvoiceLineItems(array $args = array())
  • array getInvoices(array $args = array())
  • array getUpcomingInvoice(array $args = array())
  • array getUpcomingInvoiceLineItems(array $args = array())
  • array payInvoice(array $args = array())
  • array updateInvoice(array $args = array())

与INVOICE ITEM相关的函数

  • array createInvoiceItem(array $args = array())
  • array deleteInvoiceItem(array $args = array())
  • array getInvoiceItem(array $args = array())
  • array getInvoiceItems(array $args = array())
  • array updateInvoiceItem(array $args = array())

与DISPUTE相关的函数

  • array getDispute(array $args = array())
  • array getDisputes(array $args = array())
  • array closeDispute(array $args = array())
  • array updateDispute(array $args = array())

与TRANSFER相关的函数

  • array cancelTransfer(array $args = array())
  • array createTransfer(array $args = array())
  • array getTransfer(array $args = array())
  • array getTransfers(array $args = array())
  • array updateTransfer(array $args = array())

与RECIPIENT相关的函数

  • array createRecipient(array $args = array())
  • array deleteRecipient(array $args = array())
  • array getRecipient(array $args = array())
  • array getRecipients(array $args = array())
  • array updateRecipient(array $args = array())

与REFUND相关的函数

  • array getRefund(array $args = array())
  • array getRefunds(array $args = array())
  • array updateRefund(array $args = array())

与APPLICATION FEE相关的函数

  • array getApplicationFee(array $args = array())
  • array getApplicationFees(array $args = array())
  • array refundApplicationFee(array $args = array())

与余额相关的函数

  • array getAccountBalance(array $args = array())
  • array getBalanceTransaction(array $args = array())
  • array getBalanceTransactions(array $args = array())

与令牌相关的函数

  • array createCardToken(array $args = array())
  • array createBankAccountToken(array $args = array())
  • array getToken(array $args = array())

与事件相关的函数

  • array getEvent(array $args = array())
  • array getEvents(array $args = array())

与账户相关的函数

  • array getAccount(array $args = array())