ApiOperations
2 years ago
BillingPortal
2 years ago
Checkout
2 years ago
Exception
4 years ago
FinancialConnections
2 years ago
HttpClient
2 years ago
Identity
2 years ago
Issuing
2 years ago
Radar
2 years ago
Reporting
4 years ago
Service
2 years ago
Sigma
4 years ago
Terminal
2 years ago
TestHelpers
2 years ago
Util
2 years ago
Account.php
2 years ago
AccountLink.php
4 years ago
AlipayAccount.php
4 years ago
ApiRequestor.php
2 years ago
ApiResource.php
2 years ago
ApiResponse.php
4 years ago
ApplePayDomain.php
4 years ago
ApplicationFee.php
2 years ago
ApplicationFeeRefund.php
4 years ago
Balance.php
4 years ago
BalanceTransaction.php
4 years ago
BankAccount.php
4 years ago
BaseStripeClient.php
2 years ago
BaseStripeClientInterface.php
4 years ago
BitcoinReceiver.php
2 years ago
BitcoinTransaction.php
4 years ago
Capability.php
4 years ago
Card.php
2 years ago
CashBalance.php
2 years ago
Charge.php
2 years ago
Collection.php
2 years ago
CountrySpec.php
4 years ago
Coupon.php
2 years ago
CreditNote.php
2 years ago
CreditNoteLineItem.php
4 years ago
Customer.php
2 years ago
CustomerBalanceTransaction.php
4 years ago
Discount.php
2 years ago
Dispute.php
4 years ago
EphemeralKey.php
4 years ago
ErrorObject.php
4 years ago
Event.php
2 years ago
ExchangeRate.php
4 years ago
File.php
2 years ago
FileLink.php
4 years ago
FundingInstructions.php
2 years ago
Invoice.php
2 years ago
InvoiceItem.php
2 years ago
InvoiceLineItem.php
2 years ago
LineItem.php
4 years ago
LoginLink.php
4 years ago
Mandate.php
4 years ago
OAuth.php
4 years ago
OAuthErrorObject.php
4 years ago
Order.php
2 years ago
OrderItem.php
4 years ago
OrderReturn.php
4 years ago
PaymentIntent.php
2 years ago
PaymentLink.php
2 years ago
PaymentMethod.php
2 years ago
Payout.php
4 years ago
Person.php
2 years ago
Plan.php
2 years ago
Price.php
2 years ago
Product.php
2 years ago
PromotionCode.php
2 years ago
Quote.php
2 years ago
Recipient.php
2 years ago
RecipientTransfer.php
4 years ago
Refund.php
2 years ago
RequestTelemetry.php
4 years ago
Review.php
4 years ago
SKU.php
2 years ago
SearchResult.php
2 years ago
SetupAttempt.php
4 years ago
SetupIntent.php
2 years ago
ShippingRate.php
2 years ago
SingletonApiResource.php
2 years ago
Source.php
4 years ago
SourceTransaction.php
4 years ago
Stripe.php
2 years ago
StripeClient.php
2 years ago
StripeClientInterface.php
4 years ago
StripeObject.php
2 years ago
StripeStreamingClientInterface.php
4 years ago
Subscription.php
2 years ago
SubscriptionItem.php
2 years ago
SubscriptionSchedule.php
2 years ago
TaxCode.php
2 years ago
TaxId.php
2 years ago
TaxRate.php
4 years ago
ThreeDSecure.php
4 years ago
Token.php
4 years ago
Topup.php
4 years ago
Transfer.php
2 years ago
TransferReversal.php
4 years ago
UsageRecord.php
4 years ago
UsageRecordSummary.php
4 years ago
Webhook.php
4 years ago
WebhookEndpoint.php
4 years ago
WebhookSignature.php
4 years ago
BaseStripeClient.php
313 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Stripe; |
| 4 | |
| 5 | class BaseStripeClient implements StripeClientInterface, StripeStreamingClientInterface |
| 6 | { |
| 7 | /** @var string default base URL for Stripe's API */ |
| 8 | const DEFAULT_API_BASE = 'https://api.stripe.com'; |
| 9 | |
| 10 | /** @var string default base URL for Stripe's OAuth API */ |
| 11 | const DEFAULT_CONNECT_BASE = 'https://connect.stripe.com'; |
| 12 | |
| 13 | /** @var string default base URL for Stripe's Files API */ |
| 14 | const DEFAULT_FILES_BASE = 'https://files.stripe.com'; |
| 15 | |
| 16 | /** @var array<string, mixed> */ |
| 17 | private $config; |
| 18 | |
| 19 | /** @var \Stripe\Util\RequestOptions */ |
| 20 | private $defaultOpts; |
| 21 | |
| 22 | /** |
| 23 | * Initializes a new instance of the {@link BaseStripeClient} class. |
| 24 | * |
| 25 | * The constructor takes a single argument. The argument can be a string, in which case it |
| 26 | * should be the API key. It can also be an array with various configuration settings. |
| 27 | * |
| 28 | * Configuration settings include the following options: |
| 29 | * |
| 30 | * - api_key (null|string): the Stripe API key, to be used in regular API requests. |
| 31 | * - client_id (null|string): the Stripe client ID, to be used in OAuth requests. |
| 32 | * - stripe_account (null|string): a Stripe account ID. If set, all requests sent by the client |
| 33 | * will automatically use the {@code Stripe-Account} header with that account ID. |
| 34 | * - stripe_version (null|string): a Stripe API verion. If set, all requests sent by the client |
| 35 | * will include the {@code Stripe-Version} header with that API version. |
| 36 | * |
| 37 | * The following configuration settings are also available, though setting these should rarely be necessary |
| 38 | * (only useful if you want to send requests to a mock server like stripe-mock): |
| 39 | * |
| 40 | * - api_base (string): the base URL for regular API requests. Defaults to |
| 41 | * {@link DEFAULT_API_BASE}. |
| 42 | * - connect_base (string): the base URL for OAuth requests. Defaults to |
| 43 | * {@link DEFAULT_CONNECT_BASE}. |
| 44 | * - files_base (string): the base URL for file creation requests. Defaults to |
| 45 | * {@link DEFAULT_FILES_BASE}. |
| 46 | * |
| 47 | * @param array<string, mixed>|string $config the API key as a string, or an array containing |
| 48 | * the client configuration settings |
| 49 | */ |
| 50 | public function __construct($config = []) |
| 51 | { |
| 52 | if (\is_string($config)) { |
| 53 | $config = ['api_key' => $config]; |
| 54 | } elseif (!\is_array($config)) { |
| 55 | throw new \Stripe\Exception\InvalidArgumentException('$config must be a string or an array'); |
| 56 | } |
| 57 | |
| 58 | $config = \array_merge($this->getDefaultConfig(), $config); |
| 59 | $this->validateConfig($config); |
| 60 | |
| 61 | $this->config = $config; |
| 62 | |
| 63 | $this->defaultOpts = \Stripe\Util\RequestOptions::parse([ |
| 64 | 'stripe_account' => $config['stripe_account'], |
| 65 | 'stripe_version' => $config['stripe_version'], |
| 66 | ]); |
| 67 | } |
| 68 | |
| 69 | /** |
| 70 | * Gets the API key used by the client to send requests. |
| 71 | * |
| 72 | * @return null|string the API key used by the client to send requests |
| 73 | */ |
| 74 | public function getApiKey() |
| 75 | { |
| 76 | return $this->config['api_key']; |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Gets the client ID used by the client in OAuth requests. |
| 81 | * |
| 82 | * @return null|string the client ID used by the client in OAuth requests |
| 83 | */ |
| 84 | public function getClientId() |
| 85 | { |
| 86 | return $this->config['client_id']; |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * Gets the base URL for Stripe's API. |
| 91 | * |
| 92 | * @return string the base URL for Stripe's API |
| 93 | */ |
| 94 | public function getApiBase() |
| 95 | { |
| 96 | return $this->config['api_base']; |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * Gets the base URL for Stripe's OAuth API. |
| 101 | * |
| 102 | * @return string the base URL for Stripe's OAuth API |
| 103 | */ |
| 104 | public function getConnectBase() |
| 105 | { |
| 106 | return $this->config['connect_base']; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Gets the base URL for Stripe's Files API. |
| 111 | * |
| 112 | * @return string the base URL for Stripe's Files API |
| 113 | */ |
| 114 | public function getFilesBase() |
| 115 | { |
| 116 | return $this->config['files_base']; |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Sends a request to Stripe's API. |
| 121 | * |
| 122 | * @param string $method the HTTP method |
| 123 | * @param string $path the path of the request |
| 124 | * @param array $params the parameters of the request |
| 125 | * @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request |
| 126 | * |
| 127 | * @return \Stripe\StripeObject the object returned by Stripe's API |
| 128 | */ |
| 129 | public function request($method, $path, $params, $opts) |
| 130 | { |
| 131 | $opts = $this->defaultOpts->merge($opts, true); |
| 132 | $baseUrl = $opts->apiBase ?: $this->getApiBase(); |
| 133 | $requestor = new \Stripe\ApiRequestor($this->apiKeyForRequest($opts), $baseUrl); |
| 134 | list($response, $opts->apiKey) = $requestor->request($method, $path, $params, $opts->headers); |
| 135 | $opts->discardNonPersistentHeaders(); |
| 136 | $obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts); |
| 137 | $obj->setLastResponse($response); |
| 138 | |
| 139 | return $obj; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Sends a request to Stripe's API, passing chunks of the streamed response |
| 144 | * into a user-provided $readBodyChunkCallable callback. |
| 145 | * |
| 146 | * @param string $method the HTTP method |
| 147 | * @param string $path the path of the request |
| 148 | * @param callable $readBodyChunkCallable a function that will be called |
| 149 | * @param array $params the parameters of the request |
| 150 | * @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request |
| 151 | * with chunks of bytes from the body if the request is successful |
| 152 | */ |
| 153 | public function requestStream($method, $path, $readBodyChunkCallable, $params, $opts) |
| 154 | { |
| 155 | $opts = $this->defaultOpts->merge($opts, true); |
| 156 | $baseUrl = $opts->apiBase ?: $this->getApiBase(); |
| 157 | $requestor = new \Stripe\ApiRequestor($this->apiKeyForRequest($opts), $baseUrl); |
| 158 | list($response, $opts->apiKey) = $requestor->requestStream($method, $path, $readBodyChunkCallable, $params, $opts->headers); |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | * Sends a request to Stripe's API. |
| 163 | * |
| 164 | * @param string $method the HTTP method |
| 165 | * @param string $path the path of the request |
| 166 | * @param array $params the parameters of the request |
| 167 | * @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request |
| 168 | * |
| 169 | * @return \Stripe\Collection of ApiResources |
| 170 | */ |
| 171 | public function requestCollection($method, $path, $params, $opts) |
| 172 | { |
| 173 | $obj = $this->request($method, $path, $params, $opts); |
| 174 | if (!($obj instanceof \Stripe\Collection)) { |
| 175 | $received_class = \get_class($obj); |
| 176 | $msg = "Expected to receive `Stripe\\Collection` object from Stripe API. Instead received `{$received_class}`."; |
| 177 | |
| 178 | throw new \Stripe\Exception\UnexpectedValueException($msg); |
| 179 | } |
| 180 | $obj->setFilters($params); |
| 181 | |
| 182 | return $obj; |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * Sends a request to Stripe's API. |
| 187 | * |
| 188 | * @param string $method the HTTP method |
| 189 | * @param string $path the path of the request |
| 190 | * @param array $params the parameters of the request |
| 191 | * @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request |
| 192 | * |
| 193 | * @return \Stripe\SearchResult of ApiResources |
| 194 | */ |
| 195 | public function requestSearchResult($method, $path, $params, $opts) |
| 196 | { |
| 197 | $obj = $this->request($method, $path, $params, $opts); |
| 198 | if (!($obj instanceof \Stripe\SearchResult)) { |
| 199 | $received_class = \get_class($obj); |
| 200 | $msg = "Expected to receive `Stripe\\SearchResult` object from Stripe API. Instead received `{$received_class}`."; |
| 201 | |
| 202 | throw new \Stripe\Exception\UnexpectedValueException($msg); |
| 203 | } |
| 204 | $obj->setFilters($params); |
| 205 | |
| 206 | return $obj; |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * @param \Stripe\Util\RequestOptions $opts |
| 211 | * |
| 212 | * @throws \Stripe\Exception\AuthenticationException |
| 213 | * |
| 214 | * @return string |
| 215 | */ |
| 216 | private function apiKeyForRequest($opts) |
| 217 | { |
| 218 | $apiKey = $opts->apiKey ?: $this->getApiKey(); |
| 219 | |
| 220 | if (null === $apiKey) { |
| 221 | $msg = 'No API key provided. Set your API key when constructing the ' |
| 222 | . 'StripeClient instance, or provide it on a per-request basis ' |
| 223 | . 'using the `api_key` key in the $opts argument.'; |
| 224 | |
| 225 | throw new \Stripe\Exception\AuthenticationException($msg); |
| 226 | } |
| 227 | |
| 228 | return $apiKey; |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * TODO: replace this with a private constant when we drop support for PHP < 5. |
| 233 | * |
| 234 | * @return array<string, mixed> |
| 235 | */ |
| 236 | private function getDefaultConfig() |
| 237 | { |
| 238 | return [ |
| 239 | 'api_key' => null, |
| 240 | 'client_id' => null, |
| 241 | 'stripe_account' => null, |
| 242 | 'stripe_version' => null, |
| 243 | 'api_base' => self::DEFAULT_API_BASE, |
| 244 | 'connect_base' => self::DEFAULT_CONNECT_BASE, |
| 245 | 'files_base' => self::DEFAULT_FILES_BASE, |
| 246 | ]; |
| 247 | } |
| 248 | |
| 249 | /** |
| 250 | * @param array<string, mixed> $config |
| 251 | * |
| 252 | * @throws \Stripe\Exception\InvalidArgumentException |
| 253 | */ |
| 254 | private function validateConfig($config) |
| 255 | { |
| 256 | // api_key |
| 257 | if (null !== $config['api_key'] && !\is_string($config['api_key'])) { |
| 258 | throw new \Stripe\Exception\InvalidArgumentException('api_key must be null or a string'); |
| 259 | } |
| 260 | |
| 261 | if (null !== $config['api_key'] && ('' === $config['api_key'])) { |
| 262 | $msg = 'api_key cannot be the empty string'; |
| 263 | |
| 264 | throw new \Stripe\Exception\InvalidArgumentException($msg); |
| 265 | } |
| 266 | |
| 267 | if (null !== $config['api_key'] && (\preg_match('/\s/', $config['api_key']))) { |
| 268 | $msg = 'api_key cannot contain whitespace'; |
| 269 | |
| 270 | throw new \Stripe\Exception\InvalidArgumentException($msg); |
| 271 | } |
| 272 | |
| 273 | // client_id |
| 274 | if (null !== $config['client_id'] && !\is_string($config['client_id'])) { |
| 275 | throw new \Stripe\Exception\InvalidArgumentException('client_id must be null or a string'); |
| 276 | } |
| 277 | |
| 278 | // stripe_account |
| 279 | if (null !== $config['stripe_account'] && !\is_string($config['stripe_account'])) { |
| 280 | throw new \Stripe\Exception\InvalidArgumentException('stripe_account must be null or a string'); |
| 281 | } |
| 282 | |
| 283 | // stripe_version |
| 284 | if (null !== $config['stripe_version'] && !\is_string($config['stripe_version'])) { |
| 285 | throw new \Stripe\Exception\InvalidArgumentException('stripe_version must be null or a string'); |
| 286 | } |
| 287 | |
| 288 | // api_base |
| 289 | if (!\is_string($config['api_base'])) { |
| 290 | throw new \Stripe\Exception\InvalidArgumentException('api_base must be a string'); |
| 291 | } |
| 292 | |
| 293 | // connect_base |
| 294 | if (!\is_string($config['connect_base'])) { |
| 295 | throw new \Stripe\Exception\InvalidArgumentException('connect_base must be a string'); |
| 296 | } |
| 297 | |
| 298 | // files_base |
| 299 | if (!\is_string($config['files_base'])) { |
| 300 | throw new \Stripe\Exception\InvalidArgumentException('files_base must be a string'); |
| 301 | } |
| 302 | |
| 303 | // check absence of extra keys |
| 304 | $extraConfigKeys = \array_diff(\array_keys($config), \array_keys($this->getDefaultConfig())); |
| 305 | if (!empty($extraConfigKeys)) { |
| 306 | // Wrap in single quote to more easily catch trailing spaces errors |
| 307 | $invalidKeys = "'" . \implode("', '", $extraConfigKeys) . "'"; |
| 308 | |
| 309 | throw new \Stripe\Exception\InvalidArgumentException('Found unknown key(s) in configuration array: ' . $invalidKeys); |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 |