PHP library for interacting with the Stripe REST API


Latest Stable Version

ZfrStripe is a modern PHP library based on Guzzle for Stripe payment system.



Installation of ZfrStripe is only officially supported using Composer:

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


First, you need to instantiate the Stripe client, passing your private API key (you can find it in your Stripe settings):

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

You can change the API key for the client using the setApiKey method. This is useful if you are using Stripe Connect and make both your own API calls and API calls on behalf of your users.

The currently latest supported version of the API is 2015-10-16. You can (and should) also explicitly specify the version of the client using the second parameter:

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


Stripe API has an odd (yet very useful) versioning policy that makes it hard to version it correctly. The trick is that Stripe may change how some properties are passed on return on new versions (hence being a BC for older version), but still introduce new endpoints that will be available to older versions too.

Therefore, each time a new dated version of Stripe API is released, ZfrStripe will adopt this policy:

  • If new endpoints are introduced, without changing old ones, the new endpoints are added for all supported versions. A minor version is tagged, and set the default Stripe version as the latest one.
  • If no new endpoints are introduced, but some parameter change, a new descriptor is created, hence supporting multiple versions. A minor version is tagged, and set the default Stripe version as the latest one.
  • If no new endpoints are introduced, and no parameter are changed, a minor version is tagged, and set the default Stripe version as the latest one.
  • If existing endpoints are updating by changing their URL, a major release of ZfrStripe is released as compatibility cannot be assured.

Currently, the following Stripe API versions are accepted by ZfrStripe: 2015-02-18, 2015-03-24, 2015-04-07, 2015-06-15, 2015-07-07, 2015-07-13, 2015-07-28, 2015-08-07, 2015-08-19, 2015-09-03, 2015-09-08, 2015-09-23, 2015-10-01, 2015-10-12, 2015-10-16. I will try to update the library as soon as new version are released.

If you need support for versions as old as 2014-03-28, please use branch v2 of ZfrStripe. If you need support for even older versions, please use branch v1 of ZfrStripe.

How to use it?

Using the client is easy. For instance, here is how you'd create a new charge:

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

The parameters have a direct one-to-one mapping with the official documentation (for any reference, you can also check the ZfrStripe\Client\ServiceDescription\Stripe-v1.1.php file). To know what the responses look like, please refer to the official API reference.

Using a different Stripe API version

For each requests, we send the "Stripe-Version" header to Stripe. Usually, the best way is to upgrade your API version globally in your Stripe dashboard. However, you may want to use two different versions in different part of your code, or test new features during development without changing it globally to your whole Stripe account.

To do that, you can explicitely set the wanted version in the constructor. Example:

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

You can dynamically change the version using the setApiVersion method:

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

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


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

Alternatively, you can also create different Stripe clients.

Stripe Connect

If you are using Stripe Connect, you will want to make API calls on behalf of your client. You have nothing special to do: just use the setApiKey method with the customer's access token:

// All API calls will be made on behalf of this customer now!

Please note that if you want to use again your own secret key, you will need to make a new call to this method.


All Stripe API requests have support to expand some nested objects inside responses. Therefore, ZfrStripe supports this through the expand parameter, which must be an array:

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


You may want to retrieve a list of customers, events or charges. Instead of manually doing all the requests yourself, you can use iterators. ZfrStripe provides iterators for all iterable resources:

$iterator = $client->getCustomersIterator();

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

By default, ZfrStripe retrieves 100 elements per API call (which is the maximum allowed by Stripe API). You may want to lower this limit by using the setPageSize method. You can also set a upper bound of how many results you want to retrieve by using the setLimit method.

Finally, you can still use API parameters when using an iterator. For instance, this will retrieve all the events that have the event customer.subscription.updated, doing a new API call each 50 elements (this means that only up to 50 elements are stored in memory), setting a limit of maximum 500 elements to retrieve:

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

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

You can also take advantage of Stripe cursor-based pagination:

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

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

ZfrStripe takes care of fetching the last item in the batch, extracting the id, and continuing doing requests until no more data is available!

Idempotency Key

Recently, Stripe has added support for idempotency key. This is added to every POST requests, and prevent an operation for being done twice, as long as the key is the same. You are responsible to generate your own idempotency key:

$key = 'ABC';

    'id'              => 'cus_abc',
    'plan'            => 'planA',
    'idempotency_key' => $key

    'id'              => 'cus_abc',
    'plan'            => 'planA',
    'idempotency_key' => $key

// Only one subscription is created

Undocumented features

While playing with Stripe API, I realized that the API has a few filtering capabilities that were not documented, but still accessible. Therefore, I've added some of them to this library but PLEASE be very defensive when you use them, as Stripe may remove them (or maybe officially document them in the future). Here is a list of the implemented hidden features:

Filter events

You can filter events by a object id using the object_id parameter. It will depend of the context. For instance if you are specifically retrieving subscription events, the object_id will allow to filter by subscription:

$events = $client->getEvents(['object_id' => 'cus_abc', 'type' => 'customer.*']);
Retrieve deleted customers

You can retrieve deleted customers by using the deleted boolean:

$customers = $client->getCustomers(['deleted' => true]);
Retrieve non-paid charges

You can retrieve non paid charges by using the paid boolean:

$notPaidCharges = $client->getCharges(['paid' => false]);
Retrieve proration items

You can retrieve proration invoice items only by using the proration boolean:

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


ZfrStripe tries its best to throw useful exceptions. Two kinds of exceptions can occur:

  • Guzzle exceptions: by default, Guzzle automatically validate parameters according to rules defined in the service description before sending the actual request. If you encounter those exceptions, you likely have broken code.
  • ZfrStripe exceptions: those exceptions are thrown if an error occurred on Stripe side. Each exception implement ZfrStripe\Exception\ExceptionInterface.

Here are all the exceptions:

  • ZfrStripe\Exception\UnauthorizedException: your API key is likely to be wrong...
  • ZfrStripe\Exception\ApiRateLimitException: occurs when you have reached the Stripe API limit.
  • ZfrStripe\Exception\BadRequestException: occurs for 400 error code.
  • ZfrStripe\Exception\CardErrorException: occurs for any card errors. According to Stripe, this error happen when parameters were valid but the request failed (for instance if a card CVC is invalid).
  • ZfrStripe\Exception\NotFoundException: is thrown whenever client receives a 404 exception.
  • ZfrStripe\Exception\RequestFailedException: occurs for generic 402 error.
  • ZfrStripe\Exception\ServerErrorException: any errors where Stripe is likely to be doing something wrong...


use ZfrStripe\Exception\TransactionErrorException;

try {
        '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...

Complete reference

Here is a complete list of all methods:


  • 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())


  • 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())


  • 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())


  • 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())


  • 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())


  • 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())


  • 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())


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


  • 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())


  • 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())


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


  • 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())


  • 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())


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


  • 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())