update stripe php

This commit is contained in:
ptibogxiv 2018-03-06 13:52:56 +01:00 committed by GitHub
parent f35606e434
commit 613e92e5e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 2201 additions and 1827 deletions

View File

@ -7,11 +7,13 @@ namespace Stripe;
*
* @property string $id
* @property string $object
* @property mixed $business_logo
* @property string $business_logo
* @property string $business_name
* @property mixed $business_url
* @property string $business_primary_color
* @property string $business_url
* @property bool $charges_enabled
* @property string $country
* @property int $created
* @property bool $debit_negative_balances
* @property mixed $decline_charge_on
* @property string $default_currency
@ -20,23 +22,46 @@ namespace Stripe;
* @property string $email
* @property mixed $external_accounts
* @property mixed $legal_entity
* @property bool $managed
* @property StripeObject $metadata
* @property mixed $payout_schedule
* @property mixed $payout_statement_descriptor
* @property string $payout_statement_descriptor
* @property bool $payouts_enabled
* @property mixed $product_description
* @property mixed $statement_descriptor
* @property mixed $support_email
* @property mixed $support_phone
* @property string $product_description
* @property string $statement_descriptor
* @property string $support_email
* @property string $support_phone
* @property string $timezone
* @property mixed $tos_acceptance
* @property mixed $verification
* @property mixed $keys
*
* @package Stripe
*/
class Account extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve {
retrieve as protected _retrieve;
}
use ApiOperations\Update;
public static function getSavedNestedResources()
{
static $savedNestedResources = null;
if ($savedNestedResources === null) {
$savedNestedResources = new Util\Set([
'external_account',
'bank_account',
]);
}
return $savedNestedResources;
}
const PATH_EXTERNAL_ACCOUNTS = '/external_accounts';
const PATH_LOGIN_LINKS = '/login_links';
public function instanceUrl()
{
if ($this['id'] === null) {
@ -47,7 +72,8 @@ class Account extends ApiResource
}
/**
* @param string|null $id
* @param array|string|null $id The ID of the account to retrieve, or an
* options array containing an `id` key.
* @param array|string|null $opts
*
* @return Account
@ -61,50 +87,6 @@ class Account extends ApiResource
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Account
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the account to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Account The updated account.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Account
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Account The deleted account.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
@ -120,13 +102,133 @@ class Account extends ApiResource
}
/**
* @param array|null $clientId
* @param array|string|null $opts
*
* @return StripeObject Object containing the response from the API.
*/
public function deauthorize($clientId = null, $opts = null)
{
$params = [
'client_id' => $clientId,
'stripe_user_id' => $this->id,
];
OAuth::deauthorize($params, $opts);
}
/**
* @param array|null $id The ID of the account on which to create the external account.
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Accounts
* @return BankAccount|Card
*/
public static function all($params = null, $opts = null)
public static function createExternalAccount($id, $params = null, $opts = null)
{
return self::_all($params, $opts);
return self::_createNestedResource($id, static::PATH_EXTERNAL_ACCOUNTS, $params, $opts);
}
/**
* @param array|null $id The ID of the account to which the external account belongs.
* @param array|null $externalAccountId The ID of the external account to retrieve.
* @param array|null $params
* @param array|string|null $opts
*
* @return BankAccount|Card
*/
public static function retrieveExternalAccount($id, $externalAccountId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_EXTERNAL_ACCOUNTS, $externalAccountId, $params, $opts);
}
/**
* @param array|null $id The ID of the account to which the external account belongs.
* @param array|null $externalAccountId The ID of the external account to update.
* @param array|null $params
* @param array|string|null $opts
*
* @return BankAccount|Card
*/
public static function updateExternalAccount($id, $externalAccountId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_EXTERNAL_ACCOUNTS, $externalAccountId, $params, $opts);
}
/**
* @param array|null $id The ID of the account to which the external account belongs.
* @param array|null $externalAccountId The ID of the external account to delete.
* @param array|null $params
* @param array|string|null $opts
*
* @return BankAccount|Card
*/
public static function deleteExternalAccount($id, $externalAccountId, $params = null, $opts = null)
{
return self::_deleteNestedResource($id, static::PATH_EXTERNAL_ACCOUNTS, $externalAccountId, $params, $opts);
}
/**
* @param array|null $id The ID of the account on which to retrieve the external accounts.
* @param array|null $params
* @param array|string|null $opts
*
* @return BankAccount|Card
*/
public static function allExternalAccounts($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_EXTERNAL_ACCOUNTS, $params, $opts);
}
/**
* @param array|null $id The ID of the account on which to create the login link.
* @param array|null $params
* @param array|string|null $opts
*
* @return LoginLink
*/
public static function createLoginLink($id, $params = null, $opts = null)
{
return self::_createNestedResource($id, static::PATH_LOGIN_LINKS, $params, $opts);
}
public function serializeParameters($force = false)
{
$update = parent::serializeParameters($force);
if (isset($this->_values['legal_entity'])) {
$entity = $this['legal_entity'];
if (isset($entity->_values['additional_owners'])) {
$owners = $entity['additional_owners'];
$entityUpdate = isset($update['legal_entity']) ? $update['legal_entity'] : [];
$entityUpdate['additional_owners'] = $this->serializeAdditionalOwners($entity, $owners);
$update['legal_entity'] = $entityUpdate;
}
}
return $update;
}
private function serializeAdditionalOwners($legalEntity, $additionalOwners)
{
if (isset($legalEntity->_originalValues['additional_owners'])) {
$originalValue = $legalEntity->_originalValues['additional_owners'];
} else {
$originalValue = [];
}
if (($originalValue) && (count($originalValue) > count($additionalOwners))) {
throw new \InvalidArgumentException(
"You cannot delete an item from an array, you must instead set a new array"
);
}
$updateArr = [];
foreach ($additionalOwners as $i => $v) {
$update = ($v instanceof StripeObject) ? $v->serializeParameters() : $v;
if ($update !== []) {
if (!$originalValue || ($update != $legalEntity->serializeParamsValue($originalValue[$i], null, false, true))) {
$updateArr[$i] = $update;
}
}
}
return $updateArr;
}
}

View File

@ -6,8 +6,64 @@ namespace Stripe;
* Class AlipayAccount
*
* @package Stripe
*
* @deprecated Alipay accounts are deprecated. Please use the sources API instead.
* @link https://stripe.com/docs/sources/alipay
*/
class AlipayAccount extends ExternalAccount
class AlipayAccount extends ApiResource
{
use ApiOperations\Delete;
use ApiOperations\Update;
/**
* @return string The instance URL for this resource. It needs to be special
* cased because it doesn't fit into the standard resource pattern.
*/
public function instanceUrl()
{
if ($this['customer']) {
$base = Customer::classUrl();
$parent = $this['customer'];
$path = 'sources';
} else {
$msg = "Alipay accounts cannot be accessed without a customer ID.";
throw new Error\InvalidRequest($msg, null);
}
$parentExtn = urlencode(Util\Util::utf8($parent));
$extn = urlencode(Util\Util::utf8($this['id']));
return "$base/$parentExtn/$path/$extn";
}
/**
* @param array|string $_id
* @param array|string|null $_opts
*
* @throws \Stripe\Error\InvalidRequest
*
* @deprecated Alipay accounts are deprecated. Please use the sources API instead.
* @link https://stripe.com/docs/sources/alipay
*/
public static function retrieve($_id, $_opts = null)
{
$msg = "Alipay accounts cannot be accessed without a customer ID. " .
"Retrieve an Alipay account using \$customer->sources->retrieve('alipay_account_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
/**
* @param string $_id
* @param array|null $_params
* @param array|string|null $_options
*
* @throws \Stripe\Error\InvalidRequest
*
* @deprecated Alipay accounts are deprecated. Please use the sources API instead.
* @link https://stripe.com/docs/sources/alipay
*/
public static function update($_id, $_params = null, $_options = null)
{
$msg = "Alipay accounts cannot be accessed without a customer ID. " .
"Call save() on \$customer->sources->retrieve('alipay_account_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
}

View File

@ -33,7 +33,7 @@ class ApiRequestor
} elseif ($d === false) {
return 'false';
} elseif (is_array($d)) {
$res = array();
$res = [];
foreach ($d as $k => $v) {
$res[$k] = self::_encodeObjects($v);
}
@ -54,17 +54,13 @@ class ApiRequestor
*/
public function request($method, $url, $params = null, $headers = null)
{
if (!$params) {
$params = array();
}
if (!$headers) {
$headers = array();
}
$params = $params ?: [];
$headers = $headers ?: [];
list($rbody, $rcode, $rheaders, $myApiKey) =
$this->_requestRaw($method, $url, $params, $headers);
$json = $this->_interpretResponse($rbody, $rcode, $rheaders);
$resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
return array($resp, $myApiKey);
return [$resp, $myApiKey];
}
/**
@ -74,6 +70,7 @@ class ApiRequestor
* @param array $resp
*
* @throws Error\InvalidRequest if the error is caused by the user.
* @throws Error\Idempotency if the error is caused by an idempotency key.
* @throws Error\Authentication if the error is caused by a lack of
* permissions.
* @throws Error\Permission if the error is caused by insufficient
@ -84,7 +81,7 @@ class ApiRequestor
* hitting the API.
* @throws Error\Api otherwise.
*/
public function handleApiError($rbody, $rcode, $rheaders, $resp)
public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
{
if (!is_array($resp) || !isset($resp['error'])) {
$msg = "Invalid response object from API: $rbody "
@ -92,35 +89,75 @@ class ApiRequestor
throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
}
$error = $resp['error'];
$msg = isset($error['message']) ? $error['message'] : null;
$param = isset($error['param']) ? $error['param'] : null;
$code = isset($error['code']) ? $error['code'] : null;
$errorData = $resp['error'];
$error = null;
if (is_string($errorData)) {
$error = self::_specificOAuthError($rbody, $rcode, $rheaders, $resp, $errorData);
}
if (!$error) {
$error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
}
throw $error;
}
private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
{
$msg = isset($errorData['message']) ? $errorData['message'] : null;
$param = isset($errorData['param']) ? $errorData['param'] : null;
$code = isset($errorData['code']) ? $errorData['code'] : null;
$type = isset($errorData['type']) ? $errorData['type'] : null;
switch ($rcode) {
case 400:
// 'rate_limit' code is deprecated, but left here for backwards compatibility
// for API versions earlier than 2015-09-08
if ($code == 'rate_limit') {
throw new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
}
if ($type == 'idempotency_error') {
return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
}
// intentional fall-through
case 404:
throw new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
case 401:
throw new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
case 402:
throw new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
case 403:
throw new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
case 429:
throw new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
default:
throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
}
}
private static function _specificOAuthError($rbody, $rcode, $rheaders, $resp, $errorCode)
{
$description = isset($resp['error_description']) ? $resp['error_description'] : $errorCode;
switch ($errorCode) {
case 'invalid_client':
return new Error\OAuth\InvalidClient($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
case 'invalid_grant':
return new Error\OAuth\InvalidGrant($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
case 'invalid_request':
return new Error\OAuth\InvalidRequest($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
case 'invalid_scope':
return new Error\OAuth\InvalidScope($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
case 'unsupported_grant_type':
return new Error\OAuth\UnsupportedGrantType($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
case 'unsupported_response_type':
return new Error\OAuth\UnsupportedResponseType($errorCode, $description, $rcode, $rbody, $resp, $rheaders);
}
return null;
}
private static function _formatAppInfo($appInfo)
{
if ($appInfo !== null) {
@ -137,44 +174,34 @@ class ApiRequestor
}
}
private static function _defaultHeaders($apiKey)
private static function _defaultHeaders($apiKey, $clientInfo = null)
{
$appInfo = Stripe::getAppInfo();
$uaString = 'Stripe/v1 PhpBindings/' . Stripe::VERSION;
$langVersion = phpversion();
$uname = php_uname();
$httplib = 'unknown';
$ssllib = 'unknown';
if (function_exists('curl_version')) {
$curlVersion = curl_version();
$httplib = 'curl ' . $curlVersion['version'];
$ssllib = $curlVersion['ssl_version'];
}
$appInfo = Stripe::getAppInfo();
$ua = array(
$ua = [
'bindings_version' => Stripe::VERSION,
'lang' => 'php',
'lang_version' => $langVersion,
'publisher' => 'stripe',
'uname' => $uname,
'httplib' => $httplib,
'ssllib' => $ssllib,
);
];
if ($clientInfo) {
$ua = array_merge($clientInfo, $ua);
}
if ($appInfo !== null) {
$uaString .= ' ' . self::_formatAppInfo($appInfo);
$ua['application'] = $appInfo;
}
$defaultHeaders = array(
$defaultHeaders = [
'X-Stripe-Client-User-Agent' => json_encode($ua),
'User-Agent' => $uaString,
'Authorization' => 'Bearer ' . $apiKey,
);
];
return $defaultHeaders;
}
@ -193,9 +220,17 @@ class ApiRequestor
throw new Error\Authentication($msg);
}
// Clients can supply arbitrary additional keys to be included in the
// X-Stripe-Client-User-Agent header via the optional getUserAgentInfo()
// method
$clientUAInfo = null;
if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
$clientUAInfo = $this->httpClient()->getUserAgentInfo();
}
$absUrl = $this->_apiBase.$url;
$params = self::_encodeObjects($params);
$defaultHeaders = $this->_defaultHeaders($myApiKey);
$defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
if (Stripe::$apiVersion) {
$defaultHeaders['Stripe-Version'] = Stripe::$apiVersion;
}
@ -222,7 +257,7 @@ class ApiRequestor
}
$combinedHeaders = array_merge($defaultHeaders, $headers);
$rawHeaders = array();
$rawHeaders = [];
foreach ($combinedHeaders as $header => $value) {
$rawHeaders[] = $header . ': ' . $value;
@ -235,7 +270,7 @@ class ApiRequestor
$params,
$hasFile
);
return array($rbody, $rcode, $rheaders, $myApiKey);
return [$rbody, $rcode, $rheaders, $myApiKey];
}
private function _processResourceParam($resource, $hasCurlFile)
@ -272,7 +307,7 @@ class ApiRequestor
}
if ($rcode < 200 || $rcode >= 300) {
$this->handleApiError($rbody, $rcode, $rheaders, $resp);
$this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
}
return $resp;
}

View File

@ -9,11 +9,42 @@ namespace Stripe;
*/
abstract class ApiResource extends StripeObject
{
private static $HEADERS_TO_PERSIST = array('Stripe-Account' => true, 'Stripe-Version' => true);
use ApiOperations\Request;
public static function baseUrl()
/**
* @return \Stripe\Util\Set A list of fields that can be their own type of
* API resource (say a nested card under an account for example), and if
* that resource is set, it should be transmitted to the API on a create or
* update. Doing so is not the default behavior because API resources
* should normally be persisted on their own RESTful endpoints.
*/
public static function getSavedNestedResources()
{
return Stripe::$apiBase;
static $savedNestedResources = null;
if ($savedNestedResources === null) {
$savedNestedResources = new Util\Set();
}
return $savedNestedResources;
}
/**
* @var boolean A flag that can be set a behavior that will cause this
* resource to be encoded and sent up along with an update of its parent
* resource. This is usually not desirable because resources are updated
* individually on their own endpoints, but there are certain cases,
* replacing a customer's source for example, where this is allowed.
*/
public $saveWithParent = false;
public function __set($k, $v)
{
parent::__set($k, $v);
$v = $this->$k;
if ((static::getSavedNestedResources()->includes($k)) &&
($v instanceof ApiResource)) {
$v->saveWithParent = true;
}
return $v;
}
/**
@ -59,6 +90,14 @@ abstract class ApiResource extends StripeObject
return $name;
}
/**
* @return string The base URL for the given class.
*/
public static function baseUrl()
{
return Stripe::$apiBase;
}
/**
* @return string The endpoint URL for the given class.
*/
@ -92,112 +131,4 @@ abstract class ApiResource extends StripeObject
{
return static::resourceUrl($this['id']);
}
protected static function _validateParams($params = null)
{
if ($params && !is_array($params)) {
$message = "You must pass an array as the first argument to Stripe API "
. "method calls. (HINT: an example call to create a charge "
. "would be: \"Stripe\\Charge::create(array('amount' => 100, "
. "'currency' => 'usd', 'card' => array('number' => "
. "4242424242424242, 'exp_month' => 5, 'exp_year' => 2015)))\")";
throw new Error\Api($message);
}
}
protected function _request($method, $url, $params = array(), $options = null)
{
$opts = $this->_opts->merge($options);
list($resp, $options) = static::_staticRequest($method, $url, $params, $opts);
$this->setLastResponse($resp);
return array($resp->json, $options);
}
protected static function _staticRequest($method, $url, $params, $options)
{
$opts = Util\RequestOptions::parse($options);
$requestor = new ApiRequestor($opts->apiKey, static::baseUrl());
list($response, $opts->apiKey) = $requestor->request($method, $url, $params, $opts->headers);
foreach ($opts->headers as $k => $v) {
if (!array_key_exists($k, self::$HEADERS_TO_PERSIST)) {
unset($opts->headers[$k]);
}
}
return array($response, $opts);
}
protected static function _retrieve($id, $options = null)
{
$opts = Util\RequestOptions::parse($options);
$instance = new static($id, $opts);
$instance->refresh();
return $instance;
}
protected static function _all($params = null, $options = null)
{
self::_validateParams($params);
$url = static::classUrl();
list($response, $opts) = static::_staticRequest('get', $url, $params, $options);
$obj = Util\Util::convertToStripeObject($response->json, $opts);
if (!is_a($obj, 'Stripe\\Collection')) {
$class = get_class($obj);
$message = "Expected type \"Stripe\\Collection\", got \"$class\" instead";
throw new Error\Api($message);
}
$obj->setLastResponse($response);
$obj->setRequestParams($params);
return $obj;
}
protected static function _create($params = null, $options = null)
{
self::_validateParams($params);
$url = static::classUrl();
list($response, $opts) = static::_staticRequest('post', $url, $params, $options);
$obj = Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param string $id The ID of the API resource to update.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource the updated API resource
*/
protected static function _update($id, $params = null, $options = null)
{
self::_validateParams($params);
$url = static::resourceUrl($id);
list($response, $opts) = static::_staticRequest('post', $url, $params, $options);
$obj = Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
protected function _save($options = null)
{
$params = $this->serializeParameters();
if (count($params) > 0) {
$url = $this->instanceUrl();
list($response, $opts) = $this->_request('post', $url, $params, $options);
$this->refreshFrom($response, $opts);
}
return $this;
}
protected function _delete($params = null, $options = null)
{
self::_validateParams($params);
$url = $this->instanceUrl();
list($response, $opts) = $this->_request('delete', $url, $params, $options);
$this->refreshFrom($response, $opts);
return $this;
}
}

View File

@ -9,7 +9,11 @@ namespace Stripe;
*/
class ApplePayDomain extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
/**
* @return string The class URL for this resource. It needs to be special
* cased because it doesn't fit into the standard resource pattern.
@ -18,48 +22,4 @@ class ApplePayDomain extends ApiResource
{
return '/v1/apple_pay/domains';
}
/**
* @param string $id The ID of the domain to retrieve.
* @param array|string|null $opts
*
* @return ApplePayDomain
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplePayDomain The created domain.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplePayDomain The deleted domain.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of ApplePayDomains
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
}

View File

@ -5,10 +5,31 @@ namespace Stripe;
/**
* Class ApplicationFee
*
* @property string $id
* @property string $object
* @property string $account
* @property int $amount
* @property int $amount_refunded
* @property string $application
* @property string $balance_transaction
* @property string $charge
* @property int $created
* @property string $currency
* @property bool $livemode
* @property string $originating_transaction
* @property bool $refunded
* @property Collection $refunds
*
* @package Stripe
*/
class ApplicationFee extends ApiResource
{
use ApiOperations\All;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve;
const PATH_REFUNDS = '/refunds';
/**
* This is a special case because the application fee endpoint has an
* underscore in it. The parent `className` function strips underscores.
@ -20,40 +41,6 @@ class ApplicationFee extends ApiResource
return 'application_fee';
}
/**
* @param string $id The ID of the application fee to retrieve.
* @param array|string|null $opts
*
* @return ApplicationFee
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param string $id The ID of the application fee to update.
* @param array|null $params
* @param array|string|null $options
*
* @return ApplicationFee The updated application fee.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of ApplicationFees
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
@ -66,4 +53,54 @@ class ApplicationFee extends ApiResource
$this->refresh();
return $this;
}
/**
* @param array|null $id The ID of the application fee on which to create the refund.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplicationFeeRefund
*/
public static function createRefund($id, $params = null, $opts = null)
{
return self::_createNestedResource($id, static::PATH_REFUNDS, $params, $opts);
}
/**
* @param array|null $id The ID of the application fee to which the refund belongs.
* @param array|null $refundId The ID of the refund to retrieve.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplicationFeeRefund
*/
public static function retrieveRefund($id, $refundId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_REFUNDS, $refundId, $params, $opts);
}
/**
* @param array|null $id The ID of the application fee to which the refund belongs.
* @param array|null $refundId The ID of the refund to update.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplicationFeeRefund
*/
public static function updateRefund($id, $refundId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_REFUNDS, $refundId, $params, $opts);
}
/**
* @param array|null $id The ID of the application fee on which to retrieve the refunds.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApplicationFeeRefund
*/
public static function allRefunds($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_REFUNDS, $params, $opts);
}
}

View File

@ -5,10 +5,23 @@ namespace Stripe;
/**
* Class ApplicationFeeRefund
*
* @property string $id
* @property string $object
* @property int $amount
* @property string $balance_transaction
* @property int $created
* @property string $currency
* @property string $fee
* @property StripeObject $metadata
*
* @package Stripe
*/
class ApplicationFeeRefund extends ApiResource
{
use ApiOperations\Update {
save as protected _save;
}
/**
* @return string The API URL for this Stripe refund.
*/

View File

@ -2,6 +2,8 @@
namespace Stripe;
use Countable;
/**
* Class AttachedObject
*
@ -9,7 +11,7 @@ namespace Stripe;
*
* @package Stripe
*/
class AttachedObject extends StripeObject
class AttachedObject extends StripeObject implements Countable
{
/**
* Updates this object.
@ -28,4 +30,14 @@ class AttachedObject extends StripeObject
$this->$k = $v;
}
}
/**
* Counts the number of elements in the AttachedObject instance.
*
* @return int the number of elements
*/
public function count()
{
return count($this->_values);
}
}

View File

@ -6,9 +6,9 @@ namespace Stripe;
* Class Balance
*
* @property string $object
* @property mixed $available
* @property bool $livedmode
* @property mixed $pending
* @property array $available
* @property bool $livemode
* @property array $pending
*
* @package Stripe
*/

View File

@ -12,11 +12,11 @@ namespace Stripe;
* @property int $created
* @property string $currency
* @property string $description
* @property float $exchange_rate
* @property int $fee
* @property mixed $fee_details
* @property int $net
* @property string $source
* @property mixed $sourced_transfers
* @property string $status
* @property string $type
*
@ -24,6 +24,9 @@ namespace Stripe;
*/
class BalanceTransaction extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* @return string The class URL for this resource. It needs to be special
* cased because it doesn't fit into the standard resource pattern.
@ -32,26 +35,4 @@ class BalanceTransaction extends ApiResource
{
return "/v1/balance/history";
}
/**
* @param string $id The ID of the balance transaction to retrieve.
* @param array|string|null $opts
*
* @return BalanceTransaction
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of BalanceTransactions
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
}

View File

@ -5,11 +5,82 @@ namespace Stripe;
/**
* Class BankAccount
*
* @property string $id
* @property string $object
* @property string $account
* @property string $account_holder_name
* @property string $account_holder_type
* @property string $bank_name
* @property string $country
* @property string $currency
* @property string $customer
* @property bool $default_for_currency
* @property string $fingerprint
* @property string $last4
* @property StripeObject $metadata
* @property string $routing_number
* @property string $status
*
* @package Stripe
*/
class BankAccount extends ExternalAccount
class BankAccount extends ApiResource
{
use ApiOperations\Delete;
use ApiOperations\Update;
/**
* @return string The instance URL for this resource. It needs to be special
* cased because it doesn't fit into the standard resource pattern.
*/
public function instanceUrl()
{
if ($this['customer']) {
$base = Customer::classUrl();
$parent = $this['customer'];
$path = 'sources';
} elseif ($this['account']) {
$base = Account::classUrl();
$parent = $this['account'];
$path = 'external_accounts';
} else {
$msg = "Bank accounts cannot be accessed without a customer ID or account ID.";
throw new Error\InvalidRequest($msg, null);
}
$parentExtn = urlencode(Util\Util::utf8($parent));
$extn = urlencode(Util\Util::utf8($this['id']));
return "$base/$parentExtn/$path/$extn";
}
/**
* @param array|string $_id
* @param array|string|null $_opts
*
* @throws \Stripe\Error\InvalidRequest
*/
public static function retrieve($_id, $_opts = null)
{
$msg = "Bank accounts cannot be accessed without a customer ID or account ID. " .
"Retrieve a bank account using \$customer->sources->retrieve('bank_account_id') or " .
"\$account->external_accounts->retrieve('bank_account_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
/**
* @param string $_id
* @param array|null $_params
* @param array|string|null $_options
*
* @throws \Stripe\Error\InvalidRequest
*/
public static function update($_id, $_params = null, $_options = null)
{
$msg = "Bank accounts cannot be accessed without a customer ID or account ID. " .
"Call save() on \$customer->sources->retrieve('bank_account_id') or " .
"\$account->external_accounts->retrieve('bank_account_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
/**
* @param array|null $params
* @param array|string|null $options
*

View File

@ -6,9 +6,15 @@ namespace Stripe;
* Class BitcoinReceiver
*
* @package Stripe
*
* @deprecated Bitcoin receivers are deprecated. Please use the sources API instead.
* @link https://stripe.com/docs/sources/bitcoin
*/
class BitcoinReceiver extends ExternalAccount
class BitcoinReceiver extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* @return string The class URL for this resource. It needs to be special
* cased because it doesn't fit into the standard resource pattern.
@ -24,62 +30,17 @@ class BitcoinReceiver extends ExternalAccount
*/
public function instanceUrl()
{
$result = parent::instanceUrl();
if ($result) {
return $result;
if ($this['customer']) {
$base = Customer::classUrl();
$parent = $this['customer'];
$path = 'sources';
$parentExtn = urlencode(Util\Util::utf8($parent));
$extn = urlencode(Util\Util::utf8($this['id']));
return "$base/$parentExtn/$path/$extn";
} else {
$id = $this['id'];
$id = Util\Util::utf8($id);
$extn = urlencode($id);
$base = BitcoinReceiver::classUrl();
$extn = urlencode(Util\Util::utf8($this['id']));
return "$base/$extn";
}
}
/**
* @param string $id The ID of the Bitcoin Receiver to retrieve.
* @param array|string|null $opts
*
* @return BitcoinReceiver
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of BitcoinReceivers
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return BitcoinReceiver The created Bitcoin Receiver item.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return BitcoinReceiver The refunded Bitcoin Receiver item.
*/
public function refund($params = null, $options = null)
{
$url = $this->instanceUrl() . '/refund';
list($response, $opts) = $this->_request('post', $url, $params, $options);
$this->refreshFrom($response, $opts);
return $this;
}
}

View File

@ -5,9 +5,93 @@ namespace Stripe;
/**
* Class Card
*
* @property string $id
* @property string $object
* @property string $address_city
* @property string $address_country
* @property string $address_line1
* @property string $address_line1_check
* @property string $address_line2
* @property string $address_state
* @property string $address_zip
* @property string $address_zip_check
* @property string $brand
* @property string $country
* @property string $customer
* @property string $cvc_check
* @property string $dynamic_last4
* @property int $exp_month
* @property int $exp_year
* @property string $fingerprint
* @property string $funding
* @property string $last4
* @property StripeObject $metadata
* @property string $name
* @property string $tokenization_method
*
* @package Stripe
*/
class Card extends ExternalAccount
class Card extends ApiResource
{
use ApiOperations\Delete;
use ApiOperations\Update;
/**
* @return string The instance URL for this resource. It needs to be special
* cased because cards are nested resources that may belong to different
* top-level resources.
*/
public function instanceUrl()
{
if ($this['customer']) {
$base = Customer::classUrl();
$parent = $this['customer'];
$path = 'sources';
} elseif ($this['account']) {
$base = Account::classUrl();
$parent = $this['account'];
$path = 'external_accounts';
} elseif ($this['recipient']) {
$base = Recipient::classUrl();
$parent = $this['recipient'];
$path = 'cards';
} else {
$msg = "Cards cannot be accessed without a customer ID, account ID or recipient ID.";
throw new Error\InvalidRequest($msg, null);
}
$parentExtn = urlencode(Util\Util::utf8($parent));
$extn = urlencode(Util\Util::utf8($this['id']));
return "$base/$parentExtn/$path/$extn";
}
/**
* @param array|string $_id
* @param array|string|null $_opts
*
* @throws \Stripe\Error\InvalidRequest
*/
public static function retrieve($_id, $_opts = null)
{
$msg = "Cards cannot be accessed without a customer, recipient or account ID. " .
"Retrieve a card using \$customer->sources->retrieve('card_id'), " .
"\$recipient->cards->retrieve('card_id'), or";
"\$account->external_accounts->retrieve('card_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
/**
* @param string $_id
* @param array|null $_params
* @param array|string|null $_options
*
* @throws \Stripe\Error\InvalidRequest
*/
public static function update($_id, $_params = null, $_options = null)
{
$msg = "Cards cannot be accessed without a customer, recipient or account ID. " .
"Call save() on \$customer->sources->retrieve('card_id'), " .
"\$recipient->cards->retrieve('card_id'), or";
"\$account->external_accounts->retrieve('card_id') instead.";
throw new Error\InvalidRequest($msg, null);
}
}

View File

@ -9,91 +9,47 @@ namespace Stripe;
* @property string $object
* @property int $amount
* @property int $amount_refunded
* @property mixed $application_fee
* @property string $application
* @property string $application_fee
* @property string $balance_transaction
* @property bool $captured
* @property int $created
* @property string $currency
* @property string $customer
* @property mixed $description
* @property mixed $destination
* @property string|null $dispute
* @property mixed $failure_code
* @property mixed $failure_message
* @property string $description
* @property string $destination
* @property string $dispute
* @property string $failure_code
* @property string $failure_message
* @property mixed $fraud_details
* @property mixed $invoice
* @property string $invoice
* @property bool $livemode
* @property mixed $metadata
* @property mixed $order
* @property StripeObject $metadata
* @property string $on_behalf_of
* @property string $order
* @property mixed $outcome
* @property bool $paid
* @property mixed $receipt_email
* @property mixed $receipt_number
* @property string $receipt_email
* @property string $receipt_number
* @property bool $refunded
* @property mixed $refunds
* @property Collection $refunds
* @property string $review
* @property mixed $shipping
* @property mixed $source
* @property mixed $source_transfer
* @property mixed $statement_descriptor
* @property string $source_transfer
* @property string $statement_descriptor
* @property string $status
* @property string $transfer
* @property string $transfer_group
*
* @package Stripe
*/
class Charge extends ApiResource
{
/**
* @param string $id The ID of the charge to retrieve.
* @param array|string|null $options
*
* @return Charge
*/
public static function retrieve($id, $options = null)
{
return self::_retrieve($id, $options);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Collection of Charges
*/
public static function all($params = null, $options = null)
{
return self::_all($params, $options);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Charge The created charge.
*/
public static function create($params = null, $options = null)
{
return self::_create($params, $options);
}
/**
* @param string $id The ID of the charge to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Charge The updated charge.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $options
*
* @return Charge The saved charge.
*/
public function save($options = null)
{
return $this->_save($options);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
@ -135,7 +91,7 @@ class Charge extends ApiResource
{
$url = $this->instanceUrl() . '/dispute';
list($response, $opts) = $this->_request('post', $url, $params, $options);
$this->refreshFrom(array('dispute' => $response), $opts, true);
$this->refreshFrom(['dispute' => $response], $opts, true);
return $this->dispute;
}
@ -161,7 +117,7 @@ class Charge extends ApiResource
*/
public function markAsFraudulent($opts = null)
{
$params = array('fraud_details' => array('user_report' => 'fraudulent'));
$params = ['fraud_details' => ['user_report' => 'fraudulent']];
$url = $this->instanceUrl();
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
@ -175,7 +131,7 @@ class Charge extends ApiResource
*/
public function markAsSafe($opts = null)
{
$params = array('fraud_details' => array('user_report' => 'safe'));
$params = ['fraud_details' => ['user_report' => 'safe']];
$url = $this->instanceUrl();
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);

View File

@ -12,9 +12,19 @@ namespace Stripe;
*
* @package Stripe
*/
class Collection extends ApiResource
class Collection extends StripeObject
{
protected $_requestParams = array();
use ApiOperations\Request;
protected $_requestParams = [];
/**
* @return string The base URL for the given class.
*/
public static function baseUrl()
{
return Stripe::$apiBase;
}
public function setRequestParams($params)
{
@ -56,7 +66,7 @@ class Collection extends ApiResource
}
/**
* @return AutoPagingIterator An iterator that can be used to iterate
* @return Util\AutoPagingIterator An iterator that can be used to iterate
* across all objects across all pages. As page boundaries are
* encountered, the next page will be fetched automatically for
* continued iteration.
@ -76,12 +86,11 @@ class Collection extends ApiResource
if (isset($url['query'])) {
// If the URL contains a query param, parse it out into $params so they
// don't interact weirdly with each other.
$query = array();
$query = [];
parse_str($url['query'], $query);
// PHP 5.2 doesn't support the ?: operator :(
$params = array_merge($params ? $params : array(), $query);
$params = array_merge($params ?: [], $query);
}
return array($url['path'], $params);
return [$url['path'], $params];
}
}

View File

@ -5,10 +5,21 @@ namespace Stripe;
/**
* Class CountrySpec
*
* @property string $id
* @property string $object
* @property string $default_currency
* @property mixed $supported_bank_account_currencies
* @property string[] $supported_payment_currencies
* @property string[] $supported_payment_methods
* @property mixed $verification_fields
*
* @package Stripe
*/
class CountrySpec extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* This is a special case because the country specs endpoint has an
* underscore in it. The parent `className` function strips underscores.
@ -19,26 +30,4 @@ class CountrySpec extends ApiResource
{
return 'country_spec';
}
/**
* @param string $country The ISO country code of the country we retrieve the CountrySpec for.
* @param array|string|null $opts
*
* @return CountrySpec
*/
public static function retrieve($country, $opts = null)
{
return self::_retrieve($country, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of CountrySpecs
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
}

View File

@ -5,73 +5,28 @@ namespace Stripe;
/**
* Class Coupon
*
* @property string $id
* @property string $object
* @property int $amount_off
* @property int $created
* @property string $currency
* @property string $duration
* @property int $duration_in_months
* @property bool $livemode
* @property int $max_redemptions
* @property StripeObject $metadata
* @property int $percent_off
* @property int $redeem_by
* @property int $times_redeemed
* @property bool $valid
*
* @package Stripe
*/
class Coupon extends ApiResource
{
/**
* @param string $id The ID of the coupon to retrieve.
* @param array|string|null $opts
*
* @return Coupon
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Coupon The created coupon.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the coupon to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Coupon The updated coupon.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Coupon The deleted coupon.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
/**
* @param array|string|null $opts
*
* @return Coupon The saved coupon.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Coupons
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -17,7 +17,7 @@ namespace Stripe;
* @property mixed $discount
* @property string $email
* @property bool $livemode
* @property array $metadata
* @property StripeObject $metadata
* @property mixed $shipping
* @property Collection $sources
* @property Collection $subscriptions
@ -26,71 +26,25 @@ namespace Stripe;
*/
class Customer extends ApiResource
{
/**
* @param string $id The ID of the customer to retrieve.
* @param array|string|null $opts
*
* @return Customer
*/
public static function retrieve($id, $opts = null)
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve;
use ApiOperations\Update;
public static function getSavedNestedResources()
{
return self::_retrieve($id, $opts);
static $savedNestedResources = null;
if ($savedNestedResources === null) {
$savedNestedResources = new Util\Set([
'source',
]);
}
return $savedNestedResources;
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Customers
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Customer The created customer.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the customer to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Customer The updated customer.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Customer The saved customer.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Customer The deleted customer.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
const PATH_SOURCES = '/sources';
/**
* @param array|null $params
@ -99,9 +53,7 @@ class Customer extends ApiResource
*/
public function addInvoiceItem($params = null)
{
if (!$params) {
$params = array();
}
$params = $params ?: [];
$params['customer'] = $this->id;
$ii = InvoiceItem::create($params, $this->_opts);
return $ii;
@ -114,9 +66,7 @@ class Customer extends ApiResource
*/
public function invoices($params = null)
{
if (!$params) {
$params = array();
}
$params = $params ?: [];
$params['customer'] = $this->id;
$invoices = Invoice::all($params, $this->_opts);
return $invoices;
@ -129,9 +79,7 @@ class Customer extends ApiResource
*/
public function invoiceItems($params = null)
{
if (!$params) {
$params = array();
}
$params = $params ?: [];
$params['customer'] = $this->id;
$iis = InvoiceItem::all($params, $this->_opts);
return $iis;
@ -144,9 +92,7 @@ class Customer extends ApiResource
*/
public function charges($params = null)
{
if (!$params) {
$params = array();
}
$params = $params ?: [];
$params['customer'] = $this->id;
$charges = Charge::all($params, $this->_opts);
return $charges;
@ -161,7 +107,7 @@ class Customer extends ApiResource
{
$url = $this->instanceUrl() . '/subscription';
list($response, $opts) = $this->_request('post', $url, $params);
$this->refreshFrom(array('subscription' => $response), $opts, true);
$this->refreshFrom(['subscription' => $response], $opts, true);
return $this->subscription;
}
@ -174,7 +120,7 @@ class Customer extends ApiResource
{
$url = $this->instanceUrl() . '/subscription';
list($response, $opts) = $this->_request('delete', $url, $params);
$this->refreshFrom(array('subscription' => $response), $opts, true);
$this->refreshFrom(['subscription' => $response], $opts, true);
return $this->subscription;
}
@ -185,6 +131,69 @@ class Customer extends ApiResource
{
$url = $this->instanceUrl() . '/discount';
list($response, $opts) = $this->_request('delete', $url);
$this->refreshFrom(array('discount' => null), $opts, true);
$this->refreshFrom(['discount' => null], $opts, true);
}
/**
* @param array|null $id The ID of the customer on which to create the source.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource
*/
public static function createSource($id, $params = null, $opts = null)
{
return self::_createNestedResource($id, static::PATH_SOURCES, $params, $opts);
}
/**
* @param array|null $id The ID of the customer to which the source belongs.
* @param array|null $sourceId The ID of the source to retrieve.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource
*/
public static function retrieveSource($id, $sourceId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_SOURCES, $sourceId, $params, $opts);
}
/**
* @param array|null $id The ID of the customer to which the source belongs.
* @param array|null $sourceId The ID of the source to update.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource
*/
public static function updateSource($id, $sourceId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_SOURCES, $sourceId, $params, $opts);
}
/**
* @param array|null $id The ID of the customer to which the source belongs.
* @param array|null $sourceId The ID of the source to delete.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource
*/
public static function deleteSource($id, $sourceId, $params = null, $opts = null)
{
return self::_deleteNestedResource($id, static::PATH_SOURCES, $sourceId, $params, $opts);
}
/**
* @param array|null $id The ID of the customer on which to retrieve the sources.
* @param array|null $params
* @param array|string|null $opts
*
* @return ApiResource
*/
public static function allSources($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_SOURCES, $params, $opts);
}
}

View File

@ -16,7 +16,7 @@ namespace Stripe;
* @property mixed $evidence_details
* @property bool $is_charge_refundable
* @property bool $livemode
* @property mixed $metadata
* @property StripeObject $metadata
* @property string $reason
* @property string $status
*
@ -24,49 +24,40 @@ namespace Stripe;
*/
class Dispute extends ApiResource
{
/**
* @param string $id The ID of the dispute to retrieve.
* @param array|string|null $options
*
* @return Dispute
*/
public static function retrieve($id, $options = null)
{
return self::_retrieve($id, $options);
}
use ApiOperations\All;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
* @param array|string|null $options
*
* @return array An array of Disputes.
* Possible string representations of dispute reasons.
* @link https://stripe.com/docs/api#dispute_object
*/
public static function all($params = null, $options = null)
{
return self::_all($params, $options);
}
const REASON_BANK_CANNOT_PROCESS = 'bank_cannot_process';
const REASON_CREDIT_NOT_PROCESSED = 'credit_not_processed';
const REASON_CUSTOMER_INITIATED = 'customer_initiated';
const REASON_DEBIT_NOT_AUTHORIZED = 'debit_not_authorized';
const REASON_DUPLICATE = 'duplicate';
const REASON_FRAUDULENT = 'fraudulent';
const REASON_GENERAL = 'general';
const REASON_INCORRECT_ACCOUNT_DETAILS = 'incorrect_account_details';
const REASON_INSUFFICIENT_FUNDS = 'insufficient_funds';
const REASON_PRODUCT_NOT_RECEIVED = 'product_not_received';
const REASON_PRODUCT_UNACCEPTABLE = 'product_unacceptable';
const REASON_SUBSCRIPTION_CANCELED = 'subscription_canceled';
const REASON_UNRECOGNIZED = 'unrecognized';
/**
* @param string $id The ID of the dispute to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Dispute The updated dispute.
* Possible string representations of dispute statuses.
* @link https://stripe.com/docs/api#dispute_object
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $options
*
* @return Dispute The saved charge.
*/
public function save($options = null)
{
return $this->_save($options);
}
const STATUS_CHARGE_REFUNDED = 'charge_refunded';
const STATUS_LOST = 'lost';
const STATUS_NEEDS_RESPONSE = 'needs_response';
const STATUS_UNDER_REVIEW = 'under_review';
const STATUS_WARNING_CLOSED = 'warning_closed';
const STATUS_WARNING_NEEDS_RESPONSE = 'warning_needs_response';
const STATUS_WARNING_UNDER_REVIEW = 'warning_under_review';
const STATUS_WON = 'won';
/**
* @param array|string|null $options

View File

@ -0,0 +1,49 @@
<?php
namespace Stripe;
/**
* Class EphemeralKey
*
* @property string $id
* @property string $object
* @property int $created
* @property int $expires
* @property bool $livemode
* @property string $secret
* @property array $associated_objects
*
* @package Stripe
*/
class EphemeralKey extends ApiResource
{
use ApiOperations\Create {
create as protected _create;
}
use ApiOperations\Delete;
/**
* This is a special case because the ephemeral key endpoint has an
* underscore in it. The parent `className` function strips underscores.
*
* @return string The name of the class.
*/
public static function className()
{
return 'ephemeral_key';
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return EphemeralKey The created key.
*/
public static function create($params = null, $opts = null)
{
if (!$opts['stripe_version']) {
throw new \InvalidArgumentException('stripe_version must be specified to create an ephemeral key');
}
return self::_create($params, $opts);
}
}

View File

@ -12,32 +12,103 @@ namespace Stripe;
* @property mixed $data
* @property bool $livemode
* @property int $pending_webhooks
* @property string $request
* @property mixed $request
* @property string $type
*
* @package Stripe
*/
class Event extends ApiResource
{
/**
* @param string $id The ID of the event to retrieve.
* @param array|string|null $opts
*
* @return Event
/**
* Possible string representations of event types.
* @link https://stripe.com/docs/api#event_types
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
const ACCOUNT_UPDATED = 'account.updated';
const ACCOUNT_APPLICATION_DEAUTHORIZED = 'account.application.deauthorized';
const ACCOUNT_EXTERNAL_ACCOUNT_CREATED = 'account.external_account.created';
const ACCOUNT_EXTERNAL_ACCOUNT_DELETED = 'account.external_account.deleted';
const ACCOUNT_EXTERNAL_ACCOUNT_UPDATED = 'account.external_account.updated';
const APPLICATION_FEE_CREATED = 'application_fee.created';
const APPLICATION_FEE_REFUNDED = 'application_fee.refunded';
const APPLICATION_FEE_REFUND_UPDATED = 'application_fee.refund.updated';
const BALANCE_AVAILABLE = 'balance.available';
const CHARGE_CAPTURED = 'charge.captured';
const CHARGE_FAILED = 'charge.failed';
const CHARGE_PENDING = 'charge.pending';
const CHARGE_REFUNDED = 'charge.refunded';
const CHARGE_SUCCEEDED = 'charge.succeeded';
const CHARGE_UPDATED = 'charge.updated';
const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed';
const CHARGE_DISPUTE_CREATED = 'charge.dispute.created';
const CHARGE_DISPUTE_FUNDS_REINSTATED = 'charge.dispute.funds_reinstated';
const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn';
const CHARGE_DISPUTE_UPDATED = 'charge.dispute.updated';
const CHARGE_REFUND_UPDATED = 'charge.refund.updated';
const COUPON_CREATED = 'coupon.created';
const COUPON_DELETED = 'coupon.deleted';
const COUPON_UPDATED = 'coupon.updated';
const CUSTOMER_CREATED = 'customer.created';
const CUSTOMER_DELETED = 'customer.deleted';
const CUSTOMER_UPDATED = 'customer.updated';
const CUSTOMER_DISCOUNT_CREATED = 'customer.discount.created';
const CUSTOMER_DISCOUNT_DELETED = 'customer.discount.deleted';
const CUSTOMER_DISCOUNT_UPDATED = 'customer.discount.updated';
const CUSTOMER_SOURCE_CREATED = 'customer.source.created';
const CUSTOMER_SOURCE_DELETED = 'customer.source.deleted';
const CUSTOMER_SOURCE_EXPIRING = 'customer.source.expiring';
const CUSTOMER_SOURCE_UPDATED = 'customer.source.updated';
const CUSTOMER_SUBSCRIPTION_CREATED = 'customer.subscription.created';
const CUSTOMER_SUBSCRIPTION_DELETED = 'customer.subscription.deleted';
const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'customer.subscription.trial_will_end';
const CUSTOMER_SUBSCRIPTION_UPDATED = 'customer.subscription.updated';
const FILE_CREATED = 'file.created';
const INVOICE_CREATED = 'invoice.created';
const INVOICE_PAYMENT_FAILED = 'invoice.payment_failed';
const INVOICE_PAYMENT_SUCCEEDED = 'invoice.payment_succeeded';
const INVOICE_SENT = 'invoice.sent';
const INVOICE_UPCOMING = 'invoice.upcoming';
const INVOICE_UPDATED = 'invoice.updated';
const INVOICEITEM_CREATED = 'invoiceitem.created';
const INVOICEITEM_DELETED = 'invoiceitem.deleted';
const INVOICEITEM_UPDATED = 'invoiceitem.updated';
const ORDER_CREATED = 'order.created';
const ORDER_PAYMENT_FAILED = 'order.payment_failed';
const ORDER_PAYMENT_SUCCEEDED = 'order.payment_succeeded';
const ORDER_UPDATED = 'order.updated';
const ORDER_RETURN_CREATED = 'order_return.created';
const PAYOUT_CANCELED = 'payout.canceled';
const PAYOUT_CREATED = 'payout.created';
const PAYOUT_FAILED = 'payout.failed';
const PAYOUT_PAID = 'payout.paid';
const PAYOUT_UPDATED = 'payout.updated';
const PING = 'ping';
const PLAN_CREATED = 'plan.created';
const PLAN_DELETED = 'plan.deleted';
const PLAN_UPDATED = 'plan.updated';
const PRODUCT_CREATED = 'product.created';
const PRODUCT_DELETED = 'product.deleted';
const PRODUCT_UPDATED = 'product.updated';
const RECIPIENT_CREATED = 'recipient.created';
const RECIPIENT_DELETED = 'recipient.deleted';
const RECIPIENT_UPDATED = 'recipient.updated';
const REVIEW_CLOSED = 'review.closed';
const REVIEW_OPENED = 'review.opened';
const SIGMA_SCHEDULED_QUERY_RUN_CREATED = 'sigma.scheduled_query_run.created';
const SKU_CREATED = 'sku.created';
const SKU_DELETED = 'sku.deleted';
const SKU_UPDATED = 'sku.updated';
const SOURCE_CANCELED = 'source.canceled';
const SOURCE_CHARGEABLE = 'source.chargeable';
const SOURCE_FAILED = 'source.failed';
const SOURCE_MANDATE_NOTIFICATION = 'source.mandate_notification';
const SOURCE_TRANSACTION_CREATED = 'source.transaction.created';
const TOPUP_CREATED = 'topup.created';
const TOPUP_FAILED = 'topup.failed';
const TOPUP_SUCCEEDED = 'topup.succeeded';
const TRANSFER_CREATED = 'transfer.created';
const TRANSFER_REVERSED = 'transfer.reversed';
const TRANSFER_UPDATED = 'transfer.updated';
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Events
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Retrieve;
}

View File

@ -0,0 +1,25 @@
<?php
namespace Stripe;
/**
* Class ExchangeRate
*
* @package Stripe
*/
class ExchangeRate extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* This is a special case because the exchange rates endpoint has an
* underscore in it. The parent `className` function strips underscores.
*
* @return string The name of the class.
*/
public static function className()
{
return 'exchange_rate';
}
}

View File

@ -5,6 +5,9 @@ namespace Stripe;
/**
* Class ExternalAccount
*
* @property string $id
* @property string $object
*
* @package Stripe
*/
abstract class ExternalAccount extends ApiResource

View File

@ -16,6 +16,10 @@ namespace Stripe;
*/
class FileUpload extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
public static function baseUrl()
{
return Stripe::$apiUploadBase;
@ -25,37 +29,4 @@ class FileUpload extends ApiResource
{
return 'file';
}
/**
* @param string $id The ID of the file upload to retrieve.
* @param array|string|null $opts
*
* @return FileUpload
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return FileUpload The created file upload.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of FileUploads
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
}

View File

@ -5,54 +5,52 @@ namespace Stripe;
/**
* Class Invoice
*
* @property string $id
* @property string $object
* @property int $amount_due
* @property int $amount_paid
* @property int $amount_remaining
* @property int $application_fee
* @property int $attempt_count
* @property bool $attempted
* @property string $billing
* @property string $charge
* @property bool $closed
* @property string $currency
* @property string $customer
* @property int $date
* @property string $description
* @property mixed $discount
* @property int $due_date
* @property int $ending_balance
* @property bool $forgiven
* @property Collection $lines
* @property bool $livemode
* @property StripeObject $metadata
* @property int $next_payment_attempt
* @property string $number
* @property bool $paid
* @property int $period_end
* @property int $period_start
* @property string $receipt_number
* @property int $starting_balance
* @property string $statement_descriptor
* @property string $subscription
* @property int $subscription_proration_date
* @property int $subtotal
* @property int $tax
* @property float $tax_percent
* @property int $total
* @property int $webhooks_delivered_at
*
* @package Stripe
*/
class Invoice extends ApiResource
{
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Invoice The created invoice.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the invoice to retrieve.
* @param array|string|null $opts
*
* @return Invoice
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Invoices
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param string $id The ID of the invoice to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Invoice The updated invoice.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
@ -69,23 +67,13 @@ class Invoice extends ApiResource
return $obj;
}
/**
* @param array|string|null $opts
*
* @return Invoice The saved invoice.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @return Invoice The paid invoice.
*/
public function pay($opts = null)
public function pay($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/pay';
list($response, $opts) = $this->_request('post', $url, null, $opts);
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}

View File

@ -5,73 +5,31 @@ namespace Stripe;
/**
* Class InvoiceItem
*
* @property string $id
* @property string $object
* @property int $amount
* @property string $currency
* @property string $customer
* @property int $date
* @property string $description
* @property bool $discountable
* @property string $invoice
* @property bool $livemode
* @property StripeObject $metadata
* @property mixed $period
* @property Plan $plan
* @property bool $proration
* @property int $quantity
* @property string $subscription
* @property string $subscription_item
*
* @package Stripe
*/
class InvoiceItem extends ApiResource
{
/**
* @param string $id The ID of the invoice item to retrieve.
* @param array|string|null $opts
*
* @return InvoiceItem
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of InvoiceItems
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return InvoiceItem The created invoice item.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the invoice item to update.
* @param array|null $params
* @param array|string|null $options
*
* @return InvoiceItem The updated invoice item.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return InvoiceItem The saved invoice item.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return InvoiceItem The deleted invoice item.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -0,0 +1,13 @@
<?php
namespace Stripe;
/**
* Class LoginLink
*
* @package Stripe
*/
class LoginLink extends ApiResource
{
}

View File

@ -0,0 +1,93 @@
<?php
namespace Stripe;
abstract class OAuth
{
/**
* Generates a URL to Stripe's OAuth form.
*
* @param array|null $params
* @param array|null $opts
*
* @return string The URL to Stripe's OAuth form.
*/
public static function authorizeUrl($params = null, $opts = null)
{
$params = $params ?: [];
$base = ($opts && array_key_exists('connect_base', $opts)) ? $opts['connect_base'] : Stripe::$connectBase;
$params['client_id'] = self::_getClientId($params);
if (!array_key_exists('response_type', $params)) {
$params['response_type'] = 'code';
}
$query = Util\Util::urlEncode($params);
return $base . '/oauth/authorize?' . $query;
}
/**
* Use an authoriztion code to connect an account to your platform and
* fetch the user's credentials.
*
* @param array|null $params
* @param array|null $opts
*
* @return StripeObject Object containing the response from the API.
*/
public static function token($params = null, $opts = null)
{
$base = ($opts && array_key_exists('connect_base', $opts)) ? $opts['connect_base'] : Stripe::$connectBase;
$requestor = new ApiRequestor(null, $base);
list($response, $apiKey) = $requestor->request(
'post',
'/oauth/token',
$params,
null
);
return Util\Util::convertToStripeObject($response->json, $opts);
}
/**
* Disconnects an account from your platform.
*
* @param array|null $params
* @param array|null $opts
*
* @return StripeObject Object containing the response from the API.
*/
public static function deauthorize($params = null, $opts = null)
{
$params = $params ?: [];
$base = ($opts && array_key_exists('connect_base', $opts)) ? $opts['connect_base'] : Stripe::$connectBase;
$requestor = new ApiRequestor(null, $base);
$params['client_id'] = self::_getClientId($params);
list($response, $apiKey) = $requestor->request(
'post',
'/oauth/deauthorize',
$params,
null
);
return Util\Util::convertToStripeObject($response->json, $opts);
}
private static function _getClientId($params = null)
{
$clientId = ($params && array_key_exists('client_id', $params)) ? $params['client_id'] : null;
if ($clientId === null) {
$clientId = Stripe::getClientId();
}
if ($clientId === null) {
$msg = 'No client_id provided. (HINT: set your client_id using '
. '"Stripe::setClientId(<CLIENT-ID>)". You can find your client_ids '
. 'in your Stripe dashboard at '
. 'https://dashboard.stripe.com/account/applications/settings, '
. 'after registering your account as a platform. See '
. 'https://stripe.com/docs/connect/standard-accounts for details, '
. 'or email support@stripe.com if you have any questions.';
throw new Error\Authentication($msg);
}
return $clientId;
}
}

View File

@ -5,64 +5,38 @@ namespace Stripe;
/**
* Class Order
*
* @property string $id
* @property string $object
* @property int $amount
* @property int $amount_returned
* @property string $application
* @property int $application_fee
* @property string $charge
* @property int $created
* @property string $currency
* @property string $customer
* @property string $email
* @property string $external_coupon_code
* @property mixed $items
* @property bool $livemode
* @property StripeObject $metadata
* @property Collection $returns
* @property string $selected_shipping_method
* @property mixed $shipping
* @property mixed $shipping_methods
* @property string $status
* @property mixed $status_transitions
* @property int $updated
* @property string $upstream_id
*
* @package Stripe
*/
class Order extends ApiResource
{
/**
* @param string $id The ID of the Order to retrieve.
* @param array|string|null $opts
*
* @return Order
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Order The created Order.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the order to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Order The updated order.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Order The saved Order.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Orders
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @return Order The paid order.

View File

@ -9,25 +9,17 @@ namespace Stripe;
*/
class OrderReturn extends ApiResource
{
/**
* @param string $id The ID of the OrderReturn to retrieve.
* @param array|string|null $opts
*
* @return Order
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* @param array|null $params
* @param array|string|null $opts
* This is a special case because the order returns endpoint has an
* underscore in it. The parent `className` function strips underscores.
*
* @return Collection of OrderReturns
* @return string The name of the class.
*/
public static function all($params = null, $opts = null)
public static function className()
{
return self::_all($params, $opts);
return 'order_return';
}
}

View File

@ -17,7 +17,7 @@ namespace Stripe;
* @property string $failure_code
* @property string $failure_message
* @property bool $livemode
* @property mixed $metadata
* @property StripeObject $metadata
* @property string $method
* @property string $recipient
* @property string $source_type
@ -29,50 +29,10 @@ namespace Stripe;
*/
class Payout extends ApiResource
{
/**
* @param string $id The ID of the payout to retrieve.
* @param array|string|null $opts
*
* @return Payout
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Payouts
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Payout The created payout.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the payout to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Payout The updated payout.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @return Payout The canceled payout.
@ -84,14 +44,4 @@ class Payout extends ApiResource
$this->refreshFrom($response, $opts);
return $this;
}
/**
* @param array|string|null $opts
*
* @return Payout The saved payout.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
}

View File

@ -7,84 +7,24 @@ namespace Stripe;
*
* @package Stripe
*
* @property $id
* @property $object
* @property $amount
* @property $created
* @property $currency
* @property $interval
* @property $interval_count
* @property $livemode
* @property AttachedObject $metadata
* @property $name
* @property $statement_descriptor
* @property $trial_period_days
* @property string $id
* @property string $object
* @property int $amount
* @property int $created
* @property string $currency
* @property string $interval
* @property int $interval_count
* @property bool $livemode
* @property StripeObject $metadata
* @property string $nickname
* @property string $product
* @property int $trial_period_days
*/
class Plan extends ApiResource
{
/**
* @param string $id The ID of the plan to retrieve.
* @param array|string|null $opts
*
* @return Plan
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Plan The created plan.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the plan to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Plan The updated plan.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Plan The deleted plan.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
/**
* @param array|string|null $opts
*
* @return Plan The saved plan.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Plans
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -5,73 +5,33 @@ namespace Stripe;
/**
* Class Product
*
* @property string $id
* @property string $object
* @property bool $active
* @property string[] $attributes
* @property string $caption
* @property int $created
* @property string[] $deactivate_on
* @property string $description
* @property array $images
* @property bool $livemode
* @property StripeObject $metadata
* @property string $name
* @property mixed $package_dimensions
* @property bool $shippable
* @property Collection $skus
* @property string $statement_descriptor
* @property string $type
* @property int $updated
* @property string $url
*
* @package Stripe
*/
class Product extends ApiResource
{
/**
* @param string $id The ID of the Product to retrieve.
* @param array|string|null $opts
*
* @return Product
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Product The created Product.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the product to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Product The updated product.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Product The saved Product.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Products
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Product The deleted product.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -9,71 +9,11 @@ namespace Stripe;
*/
class Recipient extends ApiResource
{
/**
* @param string $id The ID of the recipient to retrieve.
* @param array|string|null $opts
*
* @return Recipient
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Recipients
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Recipient The created recipient.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the recipient to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Recipient The updated recipient.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Recipient The saved recipient.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
*
* @return Recipient The deleted recipient.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
@ -82,9 +22,7 @@ class Recipient extends ApiResource
*/
public function transfers($params = null)
{
if ($params === null) {
$params = array();
}
$params = $params ?: [];
$params['recipient'] = $this->id;
$transfers = Transfer::all($params, $this->_opts);
return $transfers;

View File

@ -20,7 +20,7 @@ namespace Stripe;
* @property string $failure_code
* @property string $failure_message
* @property bool $livemode
* @property mixed $metadata
* @property StripeObject $metadata
* @property string $method
* @property string $recipient
* @property mixed $reversals

View File

@ -8,11 +8,13 @@ namespace Stripe;
* @property string $id
* @property string $object
* @property int $amount
* @property mixed $balance_transaction
* @property string $balance_transaction
* @property string $charge
* @property int $created
* @property string $currency
* @property mixed $metadata
* @property string $failure_balance_transaction
* @property string failure_reason
* @property StripeObject $metadata
* @property mixed $reason
* @property mixed $receipt_number
* @property string $status
@ -21,59 +23,8 @@ namespace Stripe;
*/
class Refund extends ApiResource
{
/**
* @param string $id The ID of the refund to retrieve.
* @param array|string|null $options
*
* @return Refund
*/
public static function retrieve($id, $options = null)
{
return self::_retrieve($id, $options);
}
/**
* @param string $id The ID of the refund to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Refund The updated refund.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Collection of Refunds
*/
public static function all($params = null, $options = null)
{
return self::_all($params, $options);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Refund The created refund.
*/
public static function create($params = null, $options = null)
{
return self::_create($params, $options);
}
/**
* @param array|string|null $opts
*
* @return Refund The saved refund.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -5,73 +5,28 @@ namespace Stripe;
/**
* Class SKU
*
* @property string $id
* @property string $object
* @property bool $active
* @property mixed $attributes
* @property int $created
* @property string $currency
* @property string $image
* @property mixed $inventory
* @property bool $livemode
* @property StripeObject $metadata
* @property mixed $package_dimensions
* @property int $price
* @property string $product
* @property int $updated
*
* @package Stripe
*/
class SKU extends ApiResource
{
/**
* @param string $id The ID of the SKU to retrieve.
* @param array|string|null $opts
*
* @return SKU
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return SKU The created SKU.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the SKU to update.
* @param array|null $params
* @param array|string|null $options
*
* @return SKU The updated SKU.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return SKU The saved SKU.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of SKUs
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return SKU The deleted sku.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -5,72 +5,39 @@ namespace Stripe;
/**
* Class Source
*
* @property string $id
* @property string $object
* @property int $amount
* @property string $client_secret
* @property mixed $code_verification
* @property int $created
* @property string $currency
* @property string $flow
* @property bool $livemode
* @property StripeObject $metadata
* @property mixed $owner
* @property mixed $receiver
* @property mixed $redirect
* @property string $statement_descriptor
* @property string $status
* @property string $type
* @property string $usage
*
* @package Stripe
*/
class Source extends ApiResource
{
/**
* @param string $id The ID of the Source to retrieve.
* @param array|string|null $opts
*
* @return Source
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Sources
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Source The created Source.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the source to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Source The updated source.
* @return Source The detached source.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return Source The saved source.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Source The deleted source.
*/
public function delete($params = null, $options = null)
public function detach($params = null, $options = null)
{
self::_validateParams($params);
@ -92,9 +59,8 @@ class Source extends ApiResource
$this->refreshFrom($response, $opts);
return $this;
} else {
$message = "Source objects cannot be deleted, they can only be "
. "detached from customer objects. This source object does not "
. "appear to be currently attached to a customer object.";
$message = "This source object does not appear to be currently attached "
. "to a customer object.";
throw new Error\Api($message);
}
}
@ -103,7 +69,35 @@ class Source extends ApiResource
* @param array|null $params
* @param array|string|null $options
*
* @return BankAccount The verified bank account.
* @return Source The detached source.
*
* @deprecated Use the `detach` method instead.
*/
public function delete($params = null, $options = null)
{
$this->detach($params, $options);
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Collection The list of source transactions.
*/
public function sourceTransactions($params = null, $options = null)
{
$url = $this->instanceUrl() . '/source_transactions';
list($response, $opts) = $this->_request('get', $url, $params, $options);
$obj = Util\Util::convertToStripeObject($response, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param array|null $params
* @param array|string|null $options
*
* @return Source The verified source.
*/
public function verify($params = null, $options = null)
{

View File

@ -0,0 +1,13 @@
<?php
namespace Stripe;
/**
* Class SourceTransaction
*
* @package Stripe
*/
class SourceTransaction extends ApiResource
{
}

View File

@ -12,9 +12,15 @@ class Stripe
// @var string The Stripe API key to be used for requests.
public static $apiKey;
// @var string The Stripe client_id to be used for Connect requests.
public static $clientId;
// @var string The base URL for the Stripe API.
public static $apiBase = 'https://api.stripe.com';
// @var string The base URL for the OAuth API.
public static $connectBase = 'https://connect.stripe.com';
// @var string The base URL for the Stripe API uploads endpoint.
public static $apiUploadBase = 'https://uploads.stripe.com';
@ -24,13 +30,29 @@ class Stripe
// @var string|null The account ID for connected accounts requests.
public static $accountId = null;
// @var string Path to the CA bundle used to verify SSL certificates
public static $caBundlePath = null;
// @var boolean Defaults to true.
public static $verifySslCerts = true;
// @var array The application's information (name, version, URL)
public static $appInfo = null;
const VERSION = '4.7.0';
// @var Util\LoggerInterface|null The logger to which the library will
// produce messages.
public static $logger = null;
// @var int Maximum number of request retries
public static $maxNetworkRetries = 0;
// @var float Maximum delay between retries, in seconds
private static $maxNetworkRetryDelay = 2.0;
// @var float Initial delay between retries, in seconds
private static $initialNetworkRetryDelay = 0.5;
const VERSION = '6.4.1';
/**
* @return string The API key used for requests.
@ -40,6 +62,35 @@ class Stripe
return self::$apiKey;
}
/**
* @return string The client_id used for Connect requests.
*/
public static function getClientId()
{
return self::$clientId;
}
/**
* @return Util\LoggerInterface The logger to which the library will
* produce messages.
*/
public static function getLogger()
{
if (self::$logger == null) {
return new Util\DefaultLogger();
}
return self::$logger;
}
/**
* @param Util\LoggerInterface $logger The logger to which the library
* will produce messages.
*/
public static function setLogger($logger)
{
self::$logger = $logger;
}
/**
* Sets the API key to be used for requests.
*
@ -50,6 +101,16 @@ class Stripe
self::$apiKey = $apiKey;
}
/**
* Sets the client_id to be used for Connect requests.
*
* @param string $clientId
*/
public static function setClientId($clientId)
{
self::$clientId = $clientId;
}
/**
* @return string The API version used for requests. null if we're using the
* latest version.
@ -67,6 +128,30 @@ class Stripe
self::$apiVersion = $apiVersion;
}
/**
* @return string
*/
private static function getDefaultCABundlePath()
{
return realpath(dirname(__FILE__) . '/../data/ca-certificates.crt');
}
/**
* @return string
*/
public static function getCABundlePath()
{
return self::$caBundlePath ?: self::getDefaultCABundlePath();
}
/**
* @param string $caBundlePath
*/
public static function setCABundlePath($caBundlePath)
{
self::$caBundlePath = $caBundlePath;
}
/**
* @return boolean
*/
@ -116,11 +201,41 @@ class Stripe
*/
public static function setAppInfo($appName, $appVersion = null, $appUrl = null)
{
if (self::$appInfo === null) {
self::$appInfo = array();
}
self::$appInfo = self::$appInfo ?: [];
self::$appInfo['name'] = $appName;
self::$appInfo['version'] = $appVersion;
self::$appInfo['url'] = $appUrl;
}
/**
* @return int Maximum number of request retries
*/
public static function getMaxNetworkRetries()
{
return self::$maxNetworkRetries;
}
/**
* @param int $maxNetworkRetries Maximum number of request retries
*/
public static function setMaxNetworkRetries($maxNetworkRetries)
{
self::$maxNetworkRetries = $maxNetworkRetries;
}
/**
* @return float Maximum delay between retries, in seconds
*/
public static function getMaxNetworkRetryDelay()
{
return self::$maxNetworkRetryDelay;
}
/**
* @return float Initial delay between retries, in seconds
*/
public static function getInitialNetworkRetryDelay()
{
return self::$initialNetworkRetryDelay;
}
}

View File

@ -2,38 +2,425 @@
namespace Stripe;
use ArrayAccess;
use InvalidArgumentException;
/**
* Class StripeObject
*
* @package Stripe
*/
class StripeObject implements ArrayAccess, JsonSerializable
class StripeObject implements \ArrayAccess, \Countable, \JsonSerializable
{
/**
* @var Util\Set Attributes that should not be sent to the API because
* they're not updatable (e.g. API key, ID).
*/
public static $permanentAttributes;
/**
* @var Util\Set Attributes that are nested but still updatable from
* the parent class's URL (e.g. metadata).
*/
public static $nestedUpdatableAttributes;
protected $_opts;
protected $_originalValues;
protected $_values;
protected $_unsavedValues;
protected $_transientValues;
protected $_retrieveOptions;
protected $_lastResponse;
public static function init()
/**
* @return Util\Set Attributes that should not be sent to the API because
* they're not updatable (e.g. ID).
*/
public static function getPermanentAttributes()
{
self::$permanentAttributes = new Util\Set(array('_opts', 'id'));
self::$nestedUpdatableAttributes = new Util\Set(array(
'metadata', 'legal_entity', 'address', 'dob', 'transfer_schedule', 'verification',
'tos_acceptance', 'personal_address',
// will make the array into an AttachedObject: weird, but works for now
'additional_owners', 0, 1, 2, 3, 4, // Max 3, but leave the 4th so errors work properly
'inventory',
'owner',
));
static $permanentAttributes = null;
if ($permanentAttributes === null) {
$permanentAttributes = new Util\Set([
'id',
]);
}
return $permanentAttributes;
}
public function __construct($id = null, $opts = null)
{
list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id);
$this->_opts = Util\RequestOptions::parse($opts);
$this->_originalValues = [];
$this->_values = [];
$this->_unsavedValues = new Util\Set();
$this->_transientValues = new Util\Set();
if ($id !== null) {
$this->_values['id'] = $id;
}
}
// Standard accessor magic methods
public function __set($k, $v)
{
if (static::getPermanentAttributes()->includes($k)) {
throw new \InvalidArgumentException(
"Cannot set $k on this object. HINT: you can't set: " .
join(', ', static::getPermanentAttributes()->toArray())
);
}
if ($v === "") {
throw new \InvalidArgumentException(
'You cannot set \''.$k.'\'to an empty string. '
.'We interpret empty strings as NULL in requests. '
.'You may set obj->'.$k.' = NULL to delete the property'
);
}
$this->_values[$k] = Util\Util::convertToStripeObject($v, $this->_opts);
$this->dirtyValue($this->_values[$k]);
$this->_unsavedValues->add($k);
}
public function __isset($k)
{
return isset($this->_values[$k]);
}
public function __unset($k)
{
unset($this->_values[$k]);
$this->_transientValues->add($k);
$this->_unsavedValues->discard($k);
}
public function &__get($k)
{
// function should return a reference, using $nullval to return a reference to null
$nullval = null;
if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
return $this->_values[$k];
} else if (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
$class = get_class($this);
$attrs = join(', ', array_keys($this->_values));
$message = "Stripe Notice: Undefined property of $class instance: $k. "
. "HINT: The $k attribute was set in the past, however. "
. "It was then wiped when refreshing the object "
. "with the result returned by Stripe's API, "
. "probably as a result of a save(). The attributes currently "
. "available on this object are: $attrs";
Stripe::getLogger()->error($message);
return $nullval;
} else {
$class = get_class($this);
Stripe::getLogger()->error("Stripe Notice: Undefined property of $class instance: $k");
return $nullval;
}
}
// Magic method for var_dump output. Only works with PHP >= 5.6
public function __debugInfo()
{
return $this->_values;
}
// ArrayAccess methods
public function offsetSet($k, $v)
{
$this->$k = $v;
}
public function offsetExists($k)
{
return array_key_exists($k, $this->_values);
}
public function offsetUnset($k)
{
unset($this->$k);
}
public function offsetGet($k)
{
return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
}
// Countable method
public function count()
{
return count($this->_values);
}
public function keys()
{
return array_keys($this->_values);
}
public function values()
{
return array_values($this->_values);
}
/**
* This unfortunately needs to be public to be used in Util\Util
*
* @param array $values
* @param null|string|array|Util\RequestOptions $opts
*
* @return StripeObject The object constructed from the given values.
*/
public static function constructFrom($values, $opts = null)
{
$obj = new static(isset($values['id']) ? $values['id'] : null);
$obj->refreshFrom($values, $opts);
return $obj;
}
/**
* Refreshes this object using the provided values.
*
* @param array $values
* @param null|string|array|Util\RequestOptions $opts
* @param boolean $partial Defaults to false.
*/
public function refreshFrom($values, $opts, $partial = false)
{
$this->_opts = Util\RequestOptions::parse($opts);
$this->_originalValues = self::deepCopy($values);
if ($values instanceof StripeObject) {
$values = $values->__toArray(true);
}
// Wipe old state before setting new. This is useful for e.g. updating a
// customer, where there is no persistent card parameter. Mark those values
// which don't persist as transient
if ($partial) {
$removed = new Util\Set();
} else {
$removed = new Util\Set(array_diff(array_keys($this->_values), array_keys($values)));
}
foreach ($removed->toArray() as $k) {
unset($this->$k);
}
$this->updateAttributes($values, $opts, false);
foreach ($values as $k => $v) {
$this->_transientValues->discard($k);
$this->_unsavedValues->discard($k);
}
}
/**
* Mass assigns attributes on the model.
*
* @param array $values
* @param null|string|array|Util\RequestOptions $opts
* @param boolean $dirty Defaults to true.
*/
public function updateAttributes($values, $opts = null, $dirty = true)
{
foreach ($values as $k => $v) {
// Special-case metadata to always be cast as a StripeObject
// This is necessary in case metadata is empty, as PHP arrays do
// not differentiate between lists and hashes, and we consider
// empty arrays to be lists.
if ($k === "metadata") {
$this->_values[$k] = StripeObject::constructFrom($v, $opts);
} else {
$this->_values[$k] = Util\Util::convertToStripeObject($v, $opts);
}
if ($dirty) {
$this->dirtyValue($this->_values[$k]);
}
$this->_unsavedValues->add($k);
}
}
/**
* @return array A recursive mapping of attributes to values for this object,
* including the proper value for deleted attributes.
*/
public function serializeParameters($force = false)
{
$updateParams = [];
foreach ($this->_values as $k => $v) {
// There are a few reasons that we may want to add in a parameter for
// update:
//
// 1. The `$force` option has been set.
// 2. We know that it was modified.
// 3. Its value is a StripeObject. A StripeObject may contain modified
// values within in that its parent StripeObject doesn't know about.
//
$original = array_key_exists($k, $this->_originalValues) ? $this->_originalValues[$k] : null;
$unsaved = $this->_unsavedValues->includes($k);
if ($force || $unsaved || $v instanceof StripeObject) {
$updateParams[$k] = $this->serializeParamsValue(
$this->_values[$k],
$original,
$unsaved,
$force,
$k
);
}
}
// a `null` that makes it out of `serializeParamsValue` signals an empty
// value that we shouldn't appear in the serialized form of the object
$updateParams = array_filter(
$updateParams,
function ($v) {
return $v !== null;
}
);
return $updateParams;
}
public function serializeParamsValue($value, $original, $unsaved, $force, $key = null)
{
// The logic here is that essentially any object embedded in another
// object that had a `type` is actually an API resource of a different
// type that's been included in the response. These other resources must
// be updated from their proper endpoints, and therefore they are not
// included when serializing even if they've been modified.
//
// There are _some_ known exceptions though.
//
// For example, if the value is unsaved (meaning the user has set it), and
// it looks like the API resource is persisted with an ID, then we include
// the object so that parameters are serialized with a reference to its
// ID.
//
// Another example is that on save API calls it's sometimes desirable to
// update a customer's default source by setting a new card (or other)
// object with `->source=` and then saving the customer. The
// `saveWithParent` flag to override the default behavior allows us to
// handle these exceptions.
//
// We throw an error if a property was set explicitly but we can't do
// anything with it because the integration is probably not working as the
// user intended it to.
if ($value === null) {
return "";
} elseif (($value instanceof APIResource) && (!$value->saveWithParent)) {
if (!$unsaved) {
return null;
} elseif (isset($value->id)) {
return $value;
} else {
throw new \InvalidArgumentException(
"Cannot save property `$key` containing an API resource of type " .
get_class($value) . ". It doesn't appear to be persisted and is " .
"not marked as `saveWithParent`."
);
}
} elseif (is_array($value)) {
if (Util\Util::isList($value)) {
// Sequential array, i.e. a list
$update = [];
foreach ($value as $v) {
array_push($update, $this->serializeParamsValue($v, null, true, $force));
}
// This prevents an array that's unchanged from being resent.
if ($update !== $this->serializeParamsValue($original, null, true, $force, $key)) {
return $update;
}
} else {
// Associative array, i.e. a map
return Util\Util::convertToStripeObject($value, $this->_opts)->serializeParameters();
}
} elseif ($value instanceof StripeObject) {
$update = $value->serializeParameters($force);
if ($original && $unsaved) {
$update = array_merge(self::emptyValues($original), $update);
}
return $update;
} else {
return $value;
}
}
public function jsonSerialize()
{
return $this->__toArray(true);
}
public function __toJSON()
{
return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
}
public function __toString()
{
$class = get_class($this);
return $class . ' JSON: ' . $this->__toJSON();
}
public function __toArray($recursive = false)
{
if ($recursive) {
return Util\Util::convertStripeObjectToArray($this->_values);
} else {
return $this->_values;
}
}
/**
* Sets all keys within the StripeObject as unsaved so that they will be
* included with an update when `serializeParameters` is called. This
* method is also recursive, so any StripeObjects contained as values or
* which are values in a tenant array are also marked as dirty.
*/
public function dirty()
{
$this->_unsavedValues = new Util\Set(array_keys($this->_values));
foreach ($this->_values as $k => $v) {
$this->dirtyValue($v);
}
}
protected function dirtyValue($value)
{
if (is_array($value)) {
foreach ($value as $v) {
$this->dirtyValue($v);
}
} elseif ($value instanceof StripeObject) {
$value->dirty();
}
}
/**
* Produces a deep copy of the given object including support for arrays
* and StripeObjects.
*/
protected static function deepCopy($obj)
{
if (is_array($obj)) {
$copy = [];
foreach ($obj as $k => $v) {
$copy[$k] = self::deepCopy($v);
}
return $copy;
} elseif ($obj instanceof StripeObject) {
return $obj::constructFrom(
self::deepCopy($obj->_values),
clone $obj->_opts
);
} else {
return $obj;
}
}
/**
* Returns a hash of empty values for all the values that are in the given
* StripeObject.
*/
public static function emptyValues($obj)
{
if (is_array($obj)) {
$values = $obj;
} elseif ($obj instanceof StripeObject) {
$values = $obj->_values;
} else {
throw new \InvalidArgumentException(
"empty_values got got unexpected object type: " . get_class($obj)
);
}
$update = array_fill_keys(array_keys($values), "");
return $update;
}
/**
@ -53,242 +440,4 @@ class StripeObject implements ArrayAccess, JsonSerializable
{
$this->_lastResponse = $resp;
}
protected $_opts;
protected $_values;
protected $_unsavedValues;
protected $_transientValues;
protected $_retrieveOptions;
protected $_lastResponse;
public function __construct($id = null, $opts = null)
{
$this->_opts = $opts ? $opts : new Util\RequestOptions();
$this->_values = array();
$this->_unsavedValues = new Util\Set();
$this->_transientValues = new Util\Set();
$this->_retrieveOptions = array();
if (is_array($id)) {
foreach ($id as $key => $value) {
if ($key != 'id') {
$this->_retrieveOptions[$key] = $value;
}
}
$id = $id['id'];
}
if ($id !== null) {
$this->id = $id;
}
}
// Standard accessor magic methods
public function __set($k, $v)
{
if ($v === "") {
throw new InvalidArgumentException(
'You cannot set \''.$k.'\'to an empty string. '
.'We interpret empty strings as NULL in requests. '
.'You may set obj->'.$k.' = NULL to delete the property'
);
}
if (self::$nestedUpdatableAttributes->includes($k)
&& isset($this->$k) && $this->$k instanceof AttachedObject && is_array($v)) {
$this->$k->replaceWith($v);
} else {
// TODO: may want to clear from $_transientValues (Won't be user-visible).
$this->_values[$k] = $v;
}
if (!self::$permanentAttributes->includes($k)) {
$this->_unsavedValues->add($k);
}
}
public function __isset($k)
{
return isset($this->_values[$k]);
}
public function __unset($k)
{
unset($this->_values[$k]);
$this->_transientValues->add($k);
$this->_unsavedValues->discard($k);
}
public function &__get($k)
{
// function should return a reference, using $nullval to return a reference to null
$nullval = null;
if (!empty($this->_values) && array_key_exists($k, $this->_values)) {
return $this->_values[$k];
} else if (!empty($this->_transientValues) && $this->_transientValues->includes($k)) {
$class = get_class($this);
$attrs = join(', ', array_keys($this->_values));
$message = "Stripe Notice: Undefined property of $class instance: $k. "
. "HINT: The $k attribute was set in the past, however. "
. "It was then wiped when refreshing the object "
. "with the result returned by Stripe's API, "
. "probably as a result of a save(). The attributes currently "
. "available on this object are: $attrs";
error_log($message);
return $nullval;
} else {
$class = get_class($this);
error_log("Stripe Notice: Undefined property of $class instance: $k");
return $nullval;
}
}
// ArrayAccess methods
public function offsetSet($k, $v)
{
$this->$k = $v;
}
public function offsetExists($k)
{
return array_key_exists($k, $this->_values);
}
public function offsetUnset($k)
{
unset($this->$k);
}
public function offsetGet($k)
{
return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
}
public function keys()
{
return array_keys($this->_values);
}
/**
* This unfortunately needs to be public to be used in Util\Util
*
* @param array $values
* @param array $opts
*
* @return StripeObject The object constructed from the given values.
*/
public static function constructFrom($values, $opts)
{
$obj = new static(isset($values['id']) ? $values['id'] : null);
$obj->refreshFrom($values, $opts);
return $obj;
}
/**
* Refreshes this object using the provided values.
*
* @param array $values
* @param array|Util\RequestOptions $opts
* @param boolean $partial Defaults to false.
*/
public function refreshFrom($values, $opts, $partial = false)
{
if (is_array($opts)) {
$opts = Util\RequestOptions::parse($opts);
}
$this->_opts = $opts;
// Wipe old state before setting new. This is useful for e.g. updating a
// customer, where there is no persistent card parameter. Mark those values
// which don't persist as transient
if ($partial) {
$removed = new Util\Set();
} else {
$removed = array_diff(array_keys($this->_values), array_keys($values));
}
foreach ($removed as $k) {
if (self::$permanentAttributes->includes($k)) {
continue;
}
unset($this->$k);
}
foreach ($values as $k => $v) {
if (self::$permanentAttributes->includes($k) && isset($this[$k])) {
continue;
}
if (self::$nestedUpdatableAttributes->includes($k) && is_array($v)) {
$this->_values[$k] = AttachedObject::constructFrom($v, $opts);
} else {
$this->_values[$k] = Util\Util::convertToStripeObject($v, $opts);
}
$this->_transientValues->discard($k);
$this->_unsavedValues->discard($k);
}
}
/**
* @return array A recursive mapping of attributes to values for this object,
* including the proper value for deleted attributes.
*/
public function serializeParameters()
{
$params = array();
if ($this->_unsavedValues) {
foreach ($this->_unsavedValues->toArray() as $k) {
$v = $this->$k;
if ($v === null) {
$v = '';
}
$params[$k] = $v;
}
}
// Get nested updates.
foreach (self::$nestedUpdatableAttributes->toArray() as $property) {
if (isset($this->$property)) {
if ($this->$property instanceof StripeObject) {
$serialized = $this->$property->serializeParameters();
if ($serialized) {
$params[$property] = $serialized;
}
}
}
}
return $params;
}
public function jsonSerialize()
{
return $this->__toArray(true);
}
public function __toJSON()
{
if (defined('JSON_PRETTY_PRINT')) {
return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
} else {
return json_encode($this->__toArray(true));
}
}
public function __toString()
{
$class = get_class($this);
return $class . ' JSON: ' . $this->__toJSON();
}
public function __toArray($recursive = false)
{
if ($recursive) {
return Util\Util::convertStripeObjectToArray($this->_values);
} else {
return $this->_values;
}
}
}
StripeObject::init();

View File

@ -5,10 +5,42 @@ namespace Stripe;
/**
* Class Subscription
*
* @property string $id
* @property string $object
* @property float $application_fee_percent
* @property string $billing
* @property bool $cancel_at_period_end
* @property int $canceled_at
* @property int $created
* @property int current_period_end
* @property int current_period_start
* @property string $customer
* @property int $days_until_due
* @property mixed $discount
* @property int $ended_at
* @property Collection $items
* @property boolean $livemode
* @property StripeObject $metadata
* @property Plan $plan
* @property int $quantity
* @property int $start
* @property string $status
* @property float $tax_percent
* @property int $trial_end
* @property int $trial_start
*
* @package Stripe
*/
class Subscription extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete {
delete as protected _delete;
}
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* These constants are possible representations of the status field.
*
@ -20,49 +52,15 @@ class Subscription extends ApiResource
const STATUS_TRIALING = 'trialing';
const STATUS_UNPAID = 'unpaid';
/**
* @param string $id The ID of the subscription to retrieve.
* @param array|string|null $opts
*
* @return Subscription
*/
public static function retrieve($id, $opts = null)
public static function getSavedNestedResources()
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Subscriptions
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Subscription The created subscription.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the subscription to retrieve.
* @param array|null $params
* @param array|string|null $options
*
* @return Subscription The updated subscription.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
static $savedNestedResources = null;
if ($savedNestedResources === null) {
$savedNestedResources = new Util\Set([
'source',
]);
}
return $savedNestedResources;
}
/**
@ -75,16 +73,6 @@ class Subscription extends ApiResource
return $this->_delete($params, $opts);
}
/**
* @param array|string|null $opts
*
* @return Subscription The saved subscription.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @return Subscription The updated subscription.
*/
@ -92,6 +80,15 @@ class Subscription extends ApiResource
{
$url = $this->instanceUrl() . '/discount';
list($response, $opts) = $this->_request('delete', $url);
$this->refreshFrom(array('discount' => null), $opts, true);
$this->refreshFrom(['discount' => null], $opts, true);
}
public function serializeParameters($force = false)
{
$update = parent::serializeParameters($force);
if ($this->_unsavedValues->includes('items')) {
$update['items'] = $this->serializeParamsValue($this->items, null, true, $force, 'items');
}
return $update;
}
}

View File

@ -5,10 +5,24 @@ namespace Stripe;
/**
* Class SubscriptionItem
*
* @property string $id
* @property string $object
* @property int $created
* @property StripeObject $metadata
* @property Plan $plan
* @property int $quantity
* @property string $subscription
*
* @package Stripe
*/
class SubscriptionItem extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* This is a special case because the subscription items endpoint has an
* underscore in it. The parent `className` function strips underscores.
@ -19,70 +33,4 @@ class SubscriptionItem extends ApiResource
{
return 'subscription_item';
}
/**
* @param string $id The ID of the subscription item to retrieve.
* @param array|string|null $opts
*
* @return SubscriptionItem
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of SubscriptionItems
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return SubscriptionItem The created subscription item.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the subscription item to update.
* @param array|null $params
* @param array|string|null $options
*
* @return SubscriptionItem The updated subscription item.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
/**
* @param array|string|null $opts
*
* @return SubscriptionItem The saved subscription item.
*/
public function save($opts = null)
{
return $this->_save($opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return SubscriptionItem The deleted subscription item.
*/
public function delete($params = null, $opts = null)
{
return $this->_delete($params, $opts);
}
}

View File

@ -4,6 +4,9 @@ namespace Stripe;
class ThreeDSecure extends ApiResource
{
use ApiOperations\Create;
use ApiOperations\Retrieve;
/**
* @return string The endpoint URL for the given class.
*/
@ -11,26 +14,4 @@ class ThreeDSecure extends ApiResource
{
return "/v1/3d_secure";
}
/**
* @param string $id The ID of the 3DS auth to retrieve.
* @param array|string|null $options
*
* @return ThreeDSecure
*/
public static function retrieve($id, $options = null)
{
return self::_retrieve($id, $options);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return ThreeDSecure The created 3D Secure object.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
}

View File

@ -9,7 +9,7 @@ namespace Stripe;
* @property string $object
* @property mixed $bank_account
* @property mixed $card
* @property mixed $client_ip
* @property string $client_ip
* @property int $created
* @property bool $livemode
* @property string $type
@ -19,25 +19,6 @@ namespace Stripe;
*/
class Token extends ApiResource
{
/**
* @param string $id The ID of the token to retrieve.
* @param array|string|null $opts
*
* @return Token
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Token The created token.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
use ApiOperations\Create;
use ApiOperations\Retrieve;
}

View File

@ -0,0 +1,32 @@
<?php
namespace Stripe;
/**
* Class Topup
*
* @property string $id
* @property string $object
* @property int $amount
* @property string $balance_transaction
* @property int $created
* @property string $currency
* @property string $description
* @property int $expected_availability_date
* @property string $failure_code
* @property string $failure_message
* @property bool $livemode
* @property StripeObject $metadata
* @property mixed $source
* @property string $statement_descriptor
* @property string $status
*
* @package Stripe
*/
class Topup extends ApiResource
{
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Update;
}

View File

@ -12,63 +12,27 @@ namespace Stripe;
* @property string $balance_transaction
* @property int $created
* @property string $currency
* @property int $date
* @property mixed $destination
* @property mixed $destination_payment
* @property string $destination
* @property string $destination_payment
* @property bool $livemode
* @property mixed $metadata
* @property mixed $reversals
* @property StripeObject $metadata
* @property Collection $reversals
* @property bool $reversed
* @property mixed $source_transaction
* @property string $source_transaction
* @property string $source_type
* @property string $transfer_group
*
* @package Stripe
*/
class Transfer extends ApiResource
{
/**
* @param string $id The ID of the transfer to retrieve.
* @param array|string|null $opts
*
* @return Transfer
*/
public static function retrieve($id, $opts = null)
{
return self::_retrieve($id, $opts);
}
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve;
use ApiOperations\Update;
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Collection of Transfers
*/
public static function all($params = null, $opts = null)
{
return self::_all($params, $opts);
}
/**
* @param array|null $params
* @param array|string|null $opts
*
* @return Transfer The created transfer.
*/
public static function create($params = null, $opts = null)
{
return self::_create($params, $opts);
}
/**
* @param string $id The ID of the transfer to update.
* @param array|null $params
* @param array|string|null $options
*
* @return Transfer The updated transfer.
*/
public static function update($id, $params = null, $options = null)
{
return self::_update($id, $params, $options);
}
const PATH_REVERSALS = '/reversals';
/**
* @return TransferReversal The created transfer reversal.
@ -93,12 +57,52 @@ class Transfer extends ApiResource
}
/**
* @param array|null $id The ID of the transfer on which to create the reversal.
* @param array|null $params
* @param array|string|null $opts
*
* @return Transfer The saved transfer.
* @return TransferReversal
*/
public function save($opts = null)
public static function createReversal($id, $params = null, $opts = null)
{
return $this->_save($opts);
return self::_createNestedResource($id, static::PATH_REVERSALS, $params, $opts);
}
/**
* @param array|null $id The ID of the transfer to which the reversal belongs.
* @param array|null $reversalId The ID of the reversal to retrieve.
* @param array|null $params
* @param array|string|null $opts
*
* @return TransferReversal
*/
public static function retrieveReversal($id, $reversalId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_REVERSALS, $reversalId, $params, $opts);
}
/**
* @param array|null $id The ID of the transfer to which the reversal belongs.
* @param array|null $reversalId The ID of the reversal to update.
* @param array|null $params
* @param array|string|null $opts
*
* @return TransferReversal
*/
public static function updateReversal($id, $reversalId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_REVERSALS, $reversalId, $params, $opts);
}
/**
* @param array|null $id The ID of the transfer on which to retrieve the reversals.
* @param array|null $params
* @param array|string|null $opts
*
* @return TransferReversal
*/
public static function allReversals($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_REVERSALS, $params, $opts);
}
}

View File

@ -11,13 +11,17 @@ namespace Stripe;
* @property string $balance_transaction
* @property int $created
* @property string $currency
* @property mixed $metadata
* @property StripeObject $metadata
* @property string $transfer
*
* @package Stripe
*/
class TransferReversal extends ApiResource
{
use ApiOperations\Update {
save as protected _save;
}
/**
* @return string The API URL for this Stripe transfer reversal.
*/

View File

@ -0,0 +1,40 @@
<?php
namespace Stripe;
abstract class Webhook
{
const DEFAULT_TOLERANCE = 300;
/**
* Returns an Event instance using the provided JSON payload. Throws a
* \UnexpectedValueException if the payload is not valid JSON, and a
* \Stripe\SignatureVerificationException if the signature verification
* fails for any reason.
*
* @param string $payload the payload sent by Stripe.
* @param string $sigHeader the contents of the signature header sent by
* Stripe.
* @param string $secret secret used to generate the signature.
* @param int $tolerance maximum difference allowed between the header's
* timestamp and the current time
* @return \Stripe\Event the Event instance
* @throws \UnexpectedValueException if the payload is not valid JSON,
* @throws \Stripe\Error\SignatureVerification if the verification fails.
*/
public static function constructEvent($payload, $sigHeader, $secret, $tolerance = self::DEFAULT_TOLERANCE)
{
$data = json_decode($payload, true);
$jsonError = json_last_error();
if ($data === null && $jsonError !== JSON_ERROR_NONE) {
$msg = "Invalid payload: $payload "
. "(json_last_error() was $jsonError)";
throw new \UnexpectedValueException($msg);
}
$event = Event::constructFrom($data);
WebhookSignature::verifyHeader($payload, $sigHeader, $secret, $tolerance);
return $event;
}
}

View File

@ -0,0 +1,133 @@
<?php
namespace Stripe;
abstract class WebhookSignature
{
const EXPECTED_SCHEME = "v1";
/**
* Verifies the signature header sent by Stripe. Throws a
* SignatureVerification exception if the verification fails for any
* reason.
*
* @param string $payload the payload sent by Stripe.
* @param string $header the contents of the signature header sent by
* Stripe.
* @param string $secret secret used to generate the signature.
* @param int $tolerance maximum difference allowed between the header's
* timestamp and the current time
* @throws \Stripe\Error\SignatureVerification if the verification fails.
* @return bool
*/
public static function verifyHeader($payload, $header, $secret, $tolerance = null)
{
// Extract timestamp and signatures from header
$timestamp = self::getTimestamp($header);
$signatures = self::getSignatures($header, self::EXPECTED_SCHEME);
if ($timestamp == -1) {
throw new Error\SignatureVerification(
"Unable to extract timestamp and signatures from header",
$header,
$payload
);
}
if (empty($signatures)) {
throw new Error\SignatureVerification(
"No signatures found with expected scheme",
$header,
$payload
);
}
// Check if expected signature is found in list of signatures from
// header
$signedPayload = "$timestamp.$payload";
$expectedSignature = self::computeSignature($signedPayload, $secret);
$signatureFound = false;
foreach ($signatures as $signature) {
if (Util\Util::secureCompare($expectedSignature, $signature)) {
$signatureFound = true;
break;
}
}
if (!$signatureFound) {
throw new Error\SignatureVerification(
"No signatures found matching the expected signature for payload",
$header,
$payload
);
}
// Check if timestamp is within tolerance
if (($tolerance > 0) && ((time() - $timestamp) > $tolerance)) {
throw new Error\SignatureVerification(
"Timestamp outside the tolerance zone",
$header,
$payload
);
}
return true;
}
/**
* Extracts the timestamp in a signature header.
*
* @param string $header the signature header
* @return int the timestamp contained in the header, or -1 if no valid
* timestamp is found
*/
private static function getTimestamp($header)
{
$items = explode(",", $header);
foreach ($items as $item) {
$itemParts = explode("=", $item, 2);
if ($itemParts[0] == "t") {
if (!is_numeric($itemParts[1])) {
return -1;
}
return intval($itemParts[1]);
}
}
return -1;
}
/**
* Extracts the signatures matching a given scheme in a signature header.
*
* @param string $header the signature header
* @param string $scheme the signature scheme to look for.
* @return array the list of signatures matching the provided scheme.
*/
private static function getSignatures($header, $scheme)
{
$signatures = [];
$items = explode(",", $header);
foreach ($items as $item) {
$itemParts = explode("=", $item, 2);
if ($itemParts[0] == $scheme) {
array_push($signatures, $itemParts[1]);
}
}
return $signatures;
}
/**
* Computes the signature for a given payload and secret.
*
* The current scheme used by Stripe ("v1") is HMAC/SHA-256.
*
* @param string $payload the payload to sign.
* @param string $secret the secret used to generate the signature.
* @return string the signature as a string.
*/
private static function computeSignature($payload, $secret)
{
return hash_hmac("sha256", $payload, $secret);
}
}