├── .gitignore ├── lib ├── Stripe │ ├── ApiError.php │ ├── ApiConnectionError.php │ ├── AuthenticationError.php │ ├── InvalidRequestError.php │ ├── CardError.php │ ├── Account.php │ ├── List.php │ ├── Event.php │ ├── Token.php │ ├── Transfer.php │ ├── SingletonApiResource.php │ ├── Error.php │ ├── Util │ │ └── Set.php │ ├── Stripe.php │ ├── Coupon.php │ ├── Plan.php │ ├── InvoiceItem.php │ ├── Invoice.php │ ├── Charge.php │ ├── Util.php │ ├── Customer.php │ ├── ApiResource.php │ ├── Object.php │ └── ApiRequestor.php └── Stripe.php ├── config.inc.sample.php ├── README.md └── index.php /.gitignore: -------------------------------------------------------------------------------- 1 | config.inc.php 2 | -------------------------------------------------------------------------------- /lib/Stripe/ApiError.php: -------------------------------------------------------------------------------- 1 | param = $param; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/Stripe/CardError.php: -------------------------------------------------------------------------------- 1 | param = $param; 9 | $this->code = $code; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/Stripe/Account.php: -------------------------------------------------------------------------------- 1 | _apiKey); 14 | list($response, $apiKey) = $requestor->request('get', $this['url'], $params); 15 | return Stripe_Util::convertToStripeObject($response, $apiKey); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/Stripe/Event.php: -------------------------------------------------------------------------------- 1 | refresh(); 9 | return $instance; 10 | } 11 | 12 | public static function classUrl($class) 13 | { 14 | $base = self::className($class); 15 | return "/v1/${base}"; 16 | } 17 | 18 | public function instanceUrl() 19 | { 20 | $class = get_class($this); 21 | $base = self::classUrl($class); 22 | return "$base"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/Stripe/Error.php: -------------------------------------------------------------------------------- 1 | http_status = $http_status; 9 | $this->http_body = $http_body; 10 | $this->json_body = $json_body; 11 | } 12 | 13 | public function getHttpStatus() 14 | { 15 | return $this->http_status; 16 | } 17 | 18 | public function getHttpBody() 19 | { 20 | return $this->http_body; 21 | } 22 | 23 | public function getJsonBody() 24 | { 25 | return $this->json_body; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/Stripe/Util/Set.php: -------------------------------------------------------------------------------- 1 | _elts = array(); 10 | foreach ($members as $item) 11 | $this->_elts[$item] = true; 12 | } 13 | 14 | public function includes($elt) 15 | { 16 | return isset($this->_elts[$elt]); 17 | } 18 | 19 | public function add($elt) 20 | { 21 | $this->_elts[$elt] = true; 22 | } 23 | 24 | public function discard($elt) 25 | { 26 | unset($this->_elts[$elt]); 27 | } 28 | 29 | // TODO: make Set support foreach 30 | public function toArray() 31 | { 32 | return array_keys($this->_elts); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/Stripe/Stripe.php: -------------------------------------------------------------------------------- 1 | request('get', $url, $params); 34 | return Stripe_Util::convertToStripeObject($response, $apiKey); 35 | } 36 | 37 | public function save() 38 | { 39 | $class = get_class(); 40 | return self::_scopedSave($class); 41 | } 42 | 43 | public function pay() 44 | { 45 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 46 | $url = $this->instanceUrl() . '/pay'; 47 | list($response, $apiKey) = $requestor->request('post', $url); 48 | $this->refreshFrom($response, $apiKey); 49 | return $this; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/Stripe.php: -------------------------------------------------------------------------------- 1 | _apiKey); 38 | $url = $this->instanceUrl() . '/refund'; 39 | list($response, $apiKey) = $requestor->request('post', $url, $params); 40 | $this->refreshFrom($response, $apiKey); 41 | return $this; 42 | } 43 | 44 | public function capture($params=null) 45 | { 46 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 47 | $url = $this->instanceUrl() . '/capture'; 48 | list($response, $apiKey) = $requestor->request('post', $url, $params); 49 | $this->refreshFrom($response, $apiKey); 50 | return $this; 51 | } 52 | 53 | public function updateDispute($params=null) 54 | { 55 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 56 | $url = $this->instanceUrl() . '/dispute'; 57 | list($response, $apiKey) = $requestor->request('post', $url, $params); 58 | $this->refreshFrom(array('dispute' => $response), $apiKey, true); 59 | return $this->dispute; 60 | } 61 | } -------------------------------------------------------------------------------- /lib/Stripe/Util.php: -------------------------------------------------------------------------------- 1 | $v) { 21 | // FIXME: this is an encapsulation violation 22 | if (Stripe_Object::$_permanentAttributes->includes($k)) { 23 | continue; 24 | } 25 | if ($v instanceof Stripe_Object) { 26 | $results[$k] = $v->__toArray(true); 27 | } 28 | else if (is_array($v)) { 29 | $results[$k] = self::convertStripeObjectToArray($v); 30 | } 31 | else { 32 | $results[$k] = $v; 33 | } 34 | } 35 | return $results; 36 | } 37 | 38 | public static function convertToStripeObject($resp, $apiKey) 39 | { 40 | $types = array('charge' => 'Stripe_Charge', 41 | 'customer' => 'Stripe_Customer', 42 | 'list' => 'Stripe_List', 43 | 'invoice' => 'Stripe_Invoice', 44 | 'invoiceitem' => 'Stripe_InvoiceItem', 45 | 'event' => 'Stripe_Event', 46 | 'transfer' => 'Stripe_Transfer', 47 | 'plan' => 'Stripe_Plan'); 48 | if (self::isList($resp)) { 49 | $mapped = array(); 50 | foreach ($resp as $i) 51 | array_push($mapped, self::convertToStripeObject($i, $apiKey)); 52 | return $mapped; 53 | } else if (is_array($resp)) { 54 | if (isset($resp['object']) && is_string($resp['object']) && isset($types[$resp['object']])) 55 | $class = $types[$resp['object']]; 56 | else 57 | $class = 'Stripe_Object'; 58 | return Stripe_Object::scopedConstructFrom($class, $resp, $apiKey); 59 | } else { 60 | return $resp; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/Stripe/Customer.php: -------------------------------------------------------------------------------- 1 | id; 46 | $ii = Stripe_InvoiceItem::create($params, $this->_apiKey); 47 | return $ii; 48 | } 49 | 50 | public function invoices($params=null) 51 | { 52 | if (!$params) 53 | $params = array(); 54 | $params['customer'] = $this->id; 55 | $invoices = Stripe_Invoice::all($params, $this->_apiKey); 56 | return $invoices; 57 | } 58 | 59 | public function invoiceItems($params=null) 60 | { 61 | if (!$params) 62 | $params = array(); 63 | $params['customer'] = $this->id; 64 | $iis = Stripe_InvoiceItem::all($params, $this->_apiKey); 65 | return $iis; 66 | } 67 | 68 | public function charges($params=null) 69 | { 70 | if (!$params) 71 | $params = array(); 72 | $params['customer'] = $this->id; 73 | $charges = Stripe_Charge::all($params, $this->_apiKey); 74 | return $charges; 75 | } 76 | 77 | public function updateSubscription($params=null) 78 | { 79 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 80 | $url = $this->instanceUrl() . '/subscription'; 81 | list($response, $apiKey) = $requestor->request('post', $url, $params); 82 | $this->refreshFrom(array('subscription' => $response), $apiKey, true); 83 | return $this->subscription; 84 | } 85 | 86 | public function cancelSubscription($params=null) 87 | { 88 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 89 | $url = $this->instanceUrl() . '/subscription'; 90 | list($response, $apiKey) = $requestor->request('delete', $url, $params); 91 | $this->refreshFrom(array('subscription' => $response), $apiKey, true); 92 | return $this->subscription; 93 | } 94 | 95 | public function deleteDiscount() 96 | { 97 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 98 | $url = $this->instanceUrl() . '/discount'; 99 | list($response, $apiKey) = $requestor->request('delete', $url); 100 | $this->refreshFrom(array('discount' => null), $apiKey, true); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /lib/Stripe/ApiResource.php: -------------------------------------------------------------------------------- 1 | refresh(); 9 | return $instance; 10 | } 11 | 12 | public function refresh() 13 | { 14 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 15 | $url = $this->instanceUrl(); 16 | 17 | list($response, $apiKey) = $requestor->request('get', $url, $this->_retrieveOptions); 18 | $this->refreshFrom($response, $apiKey); 19 | return $this; 20 | } 21 | 22 | public static function className($class) 23 | { 24 | // Useful for namespaces: Foo\Stripe_Charge 25 | if ($postfix = strrchr($class, '\\')) 26 | $class = substr($postfix, 1); 27 | if (substr($class, 0, strlen('Stripe')) == 'Stripe') 28 | $class = substr($class, strlen('Stripe')); 29 | $class = str_replace('_', '', $class); 30 | $name = urlencode($class); 31 | $name = strtolower($name); 32 | return $name; 33 | } 34 | 35 | public static function classUrl($class) 36 | { 37 | $base = self::className($class); 38 | return "/v1/${base}s"; 39 | } 40 | 41 | public function instanceUrl() 42 | { 43 | $id = $this['id']; 44 | $class = get_class($this); 45 | if (!$id) { 46 | throw new Stripe_InvalidRequestError("Could not determine which URL to request: $class instance has invalid ID: $id", null); 47 | } 48 | $id = Stripe_ApiRequestor::utf8($id); 49 | $base = self::classUrl($class); 50 | $extn = urlencode($id); 51 | return "$base/$extn"; 52 | } 53 | 54 | private static function _validateCall($method, $params=null, $apiKey=null) 55 | { 56 | if ($params && !is_array($params)) 57 | throw new Stripe_Error("You must pass an array as the first argument to Stripe API method calls. (HINT: an example call to create a charge would be: \"StripeCharge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => 4242424242424242, 'exp_month' => 5, 'exp_year' => 2015)))\")"); 58 | if ($apiKey && !is_string($apiKey)) 59 | throw new Stripe_Error('The second argument to Stripe API method calls is an optional per-request apiKey, which must be a string. (HINT: you can set a global apiKey by "Stripe::setApiKey()")'); 60 | } 61 | 62 | protected static function _scopedAll($class, $params=null, $apiKey=null) 63 | { 64 | self::_validateCall('all', $params, $apiKey); 65 | $requestor = new Stripe_ApiRequestor($apiKey); 66 | $url = self::classUrl($class); 67 | list($response, $apiKey) = $requestor->request('get', $url, $params); 68 | return Stripe_Util::convertToStripeObject($response, $apiKey); 69 | } 70 | 71 | protected static function _scopedCreate($class, $params=null, $apiKey=null) 72 | { 73 | self::_validateCall('create', $params, $apiKey); 74 | $requestor = new Stripe_ApiRequestor($apiKey); 75 | $url = self::classUrl($class); 76 | list($response, $apiKey) = $requestor->request('post', $url, $params); 77 | return Stripe_Util::convertToStripeObject($response, $apiKey); 78 | } 79 | 80 | protected function _scopedSave($class) 81 | { 82 | self::_validateCall('save'); 83 | if ($this->_unsavedValues) { 84 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 85 | $params = array(); 86 | foreach ($this->_unsavedValues->toArray() as $k) 87 | $params[$k] = $this->$k; 88 | $url = $this->instanceUrl(); 89 | list($response, $apiKey) = $requestor->request('post', $url, $params); 90 | $this->refreshFrom($response, $apiKey); 91 | } 92 | return $this; 93 | } 94 | 95 | protected function _scopedDelete($class, $params=null) 96 | { 97 | self::_validateCall('delete'); 98 | $requestor = new Stripe_ApiRequestor($this->_apiKey); 99 | $url = $this->instanceUrl(); 100 | list($response, $apiKey) = $requestor->request('delete', $url, $params); 101 | $this->refreshFrom($response, $apiKey); 102 | return $this; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | $_POST['txtAmount'] * 100, // amount in cents, again 14 | "currency" => "usd", 15 | "card" => $token, 16 | "description" => "Payment from pay.clickontyler.com") 17 | ); 18 | header('Location: /?payment=true'); 19 | exit; 20 | } 21 | catch(Stripe_CardError $e) 22 | { 23 | header('Location: /?payment=false'); 24 | exit; 25 | } 26 | } 27 | ?> 28 | 29 | 30 | 95 | 96 | 97 | 98 | 99 |

Pay Click On Tyler

100 | 101 |

Fill in the amount to pay and click "Pay with Card"
All payments are securely processed by Stripe

102 |
103 |

$

104 | 107 |
108 | 109 | 110 |

Thanks for your payment!

111 | 112 |

Card Declined. Please try again.

113 | 114 | 115 | 135 | 136 | -------------------------------------------------------------------------------- /lib/Stripe/Object.php: -------------------------------------------------------------------------------- 1 | _apiKey = $apiKey; 21 | $this->_values = array(); 22 | $this->_unsavedValues = new Stripe_Util_Set(); 23 | $this->_transientValues = new Stripe_Util_Set(); 24 | 25 | $this->_retrieveOptions = array(); 26 | if (is_array($id)) { 27 | foreach($id as $key => $value) { 28 | if ($key != 'id') 29 | $this->_retrieveOptions[$key] = $value; 30 | } 31 | $id = $id['id']; 32 | } 33 | 34 | if ($id) 35 | $this->id = $id; 36 | } 37 | 38 | // Standard accessor magic methods 39 | public function __set($k, $v) 40 | { 41 | // TODO: may want to clear from $_transientValues. (Won't be user-visible.) 42 | $this->_values[$k] = $v; 43 | if (!self::$_permanentAttributes->includes($k)) 44 | $this->_unsavedValues->add($k); 45 | } 46 | public function __isset($k) 47 | { 48 | return isset($this->_values[$k]); 49 | } 50 | public function __unset($k) 51 | { 52 | unset($this->_values[$k]); 53 | $this->_transientValues->add($k); 54 | $this->_unsavedValues->discard($k); 55 | } 56 | public function __get($k) 57 | { 58 | if (array_key_exists($k, $this->_values)) { 59 | return $this->_values[$k]; 60 | } else if ($this->_transientValues->includes($k)) { 61 | $class = get_class($this); 62 | $attrs = join(', ', array_keys($this->_values)); 63 | error_log("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"); 64 | return null; 65 | } else { 66 | $class = get_class($this); 67 | error_log("Stripe Notice: Undefined property of $class instance: $k"); 68 | return null; 69 | } 70 | } 71 | 72 | // ArrayAccess methods 73 | public function offsetSet($k, $v) 74 | { 75 | $this->$k = $v; 76 | } 77 | 78 | public function offsetExists($k) 79 | { 80 | return array_key_exists($k, $this->_values); 81 | } 82 | 83 | public function offsetUnset($k) 84 | { 85 | unset($this->$k); 86 | } 87 | public function offsetGet($k) 88 | { 89 | return array_key_exists($k, $this->_values) ? $this->_values[$k] : null; 90 | } 91 | 92 | // This unfortunately needs to be public to be used in Util.php 93 | public static function scopedConstructFrom($class, $values, $apiKey=null) 94 | { 95 | $obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey); 96 | $obj->refreshFrom($values, $apiKey); 97 | return $obj; 98 | } 99 | 100 | public static function constructFrom($values, $apiKey=null) 101 | { 102 | $class = get_class(); 103 | return self::scopedConstructFrom($class, $values, $apiKey); 104 | } 105 | 106 | public function refreshFrom($values, $apiKey, $partial=false) 107 | { 108 | $this->_apiKey = $apiKey; 109 | // Wipe old state before setting new. This is useful for e.g. updating a 110 | // customer, where there is no persistent card parameter. Mark those values 111 | // which don't persist as transient 112 | if ($partial) 113 | $removed = new Stripe_Util_Set(); 114 | else 115 | $removed = array_diff(array_keys($this->_values), array_keys($values)); 116 | 117 | foreach ($removed as $k) { 118 | if (self::$_permanentAttributes->includes($k)) 119 | continue; 120 | unset($this->$k); 121 | } 122 | 123 | foreach ($values as $k => $v) { 124 | if (self::$_permanentAttributes->includes($k)) 125 | continue; 126 | $this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey); 127 | $this->_transientValues->discard($k); 128 | $this->_unsavedValues->discard($k); 129 | } 130 | } 131 | 132 | public function __toJSON() 133 | { 134 | if (defined('JSON_PRETTY_PRINT')) 135 | return json_encode($this->__toArray(true), JSON_PRETTY_PRINT); 136 | else 137 | return json_encode($this->__toArray(true)); 138 | } 139 | 140 | public function __toString() 141 | { 142 | return $this->__toJSON(); 143 | } 144 | 145 | public function __toArray($recursive=false) 146 | { 147 | if ($recursive) 148 | return Stripe_Util::convertStripeObjectToArray($this->_values); 149 | else 150 | return $this->_values; 151 | } 152 | } 153 | 154 | 155 | Stripe_Object::init(); 156 | -------------------------------------------------------------------------------- /lib/Stripe/ApiRequestor.php: -------------------------------------------------------------------------------- 1 | _apiKey = $apiKey; 10 | } 11 | 12 | public static function apiUrl($url='') 13 | { 14 | $apiBase = Stripe::$apiBase; 15 | return "$apiBase$url"; 16 | } 17 | 18 | public static function utf8($value) 19 | { 20 | if (is_string($value) && mb_detect_encoding($value, "UTF-8", TRUE) != "UTF-8") 21 | return utf8_encode($value); 22 | else 23 | return $value; 24 | } 25 | 26 | private static function _encodeObjects($d) 27 | { 28 | if ($d instanceof Stripe_ApiResource) { 29 | return self::utf8($d->id); 30 | } else if ($d === true) { 31 | return 'true'; 32 | } else if ($d === false) { 33 | return 'false'; 34 | } else if (is_array($d)) { 35 | $res = array(); 36 | foreach ($d as $k => $v) 37 | $res[$k] = self::_encodeObjects($v); 38 | return $res; 39 | } else { 40 | return self::utf8($d); 41 | } 42 | } 43 | 44 | public static function encode($arr, $prefix=null) 45 | { 46 | if (!is_array($arr)) 47 | return $arr; 48 | 49 | $r = array(); 50 | foreach ($arr as $k => $v) { 51 | if (is_null($v)) 52 | continue; 53 | 54 | if ($prefix && $k && !is_int($k)) 55 | $k = $prefix."[".$k."]"; 56 | else if ($prefix) 57 | $k = $prefix."[]"; 58 | 59 | if (is_array($v)) { 60 | $r[] = self::encode($v, $k, true); 61 | } else { 62 | $r[] = urlencode($k)."=".urlencode($v); 63 | } 64 | } 65 | 66 | return implode("&", $r); 67 | } 68 | 69 | public function request($meth, $url, $params=null) 70 | { 71 | if (!$params) 72 | $params = array(); 73 | list($rbody, $rcode, $myApiKey) = $this->_requestRaw($meth, $url, $params); 74 | $resp = $this->_interpretResponse($rbody, $rcode); 75 | return array($resp, $myApiKey); 76 | } 77 | 78 | public function handleApiError($rbody, $rcode, $resp) 79 | { 80 | if (!is_array($resp) || !isset($resp['error'])) 81 | throw new Stripe_ApiError("Invalid response object from API: $rbody (HTTP response code was $rcode)", $rcode, $rbody, $resp); 82 | $error = $resp['error']; 83 | switch ($rcode) { 84 | case 400: 85 | case 404: 86 | throw new Stripe_InvalidRequestError(isset($error['message']) ? $error['message'] : null, 87 | isset($error['param']) ? $error['param'] : null, 88 | $rcode, $rbody, $resp); 89 | case 401: 90 | throw new Stripe_AuthenticationError(isset($error['message']) ? $error['message'] : null, $rcode, $rbody, $resp); 91 | case 402: 92 | throw new Stripe_CardError(isset($error['message']) ? $error['message'] : null, 93 | isset($error['param']) ? $error['param'] : null, 94 | isset($error['code']) ? $error['code'] : null, 95 | $rcode, $rbody, $resp); 96 | default: 97 | throw new Stripe_ApiError(isset($error['message']) ? $error['message'] : null, $rcode, $rbody, $resp); 98 | } 99 | } 100 | 101 | private function _requestRaw($meth, $url, $params) 102 | { 103 | $myApiKey = $this->_apiKey; 104 | if (!$myApiKey) 105 | $myApiKey = Stripe::$apiKey; 106 | if (!$myApiKey) 107 | throw new Stripe_AuthenticationError('No API key provided. (HINT: set your API key using "Stripe::setApiKey()". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support@stripe.com if you have any questions.'); 108 | 109 | $absUrl = $this->apiUrl($url); 110 | $params = self::_encodeObjects($params); 111 | $langVersion = phpversion(); 112 | $uname = php_uname(); 113 | $ua = array('bindings_version' => Stripe::VERSION, 114 | 'lang' => 'php', 115 | 'lang_version' => $langVersion, 116 | 'publisher' => 'stripe', 117 | 'uname' => $uname); 118 | $headers = array('X-Stripe-Client-User-Agent: ' . json_encode($ua), 119 | 'User-Agent: Stripe/v1 PhpBindings/' . Stripe::VERSION, 120 | 'Authorization: Bearer ' . $myApiKey); 121 | if (Stripe::$apiVersion) 122 | $headers[] = 'Stripe-Version: ' . Stripe::$apiVersion; 123 | list($rbody, $rcode) = $this->_curlRequest($meth, $absUrl, $headers, $params); 124 | return array($rbody, $rcode, $myApiKey); 125 | } 126 | 127 | private function _interpretResponse($rbody, $rcode) 128 | { 129 | try { 130 | $resp = json_decode($rbody, true); 131 | } catch (Exception $e) { 132 | throw new Stripe_ApiError("Invalid response body from API: $rbody (HTTP response code was $rcode)", $rcode, $rbody); 133 | } 134 | 135 | if ($rcode < 200 || $rcode >= 300) { 136 | $this->handleApiError($rbody, $rcode, $resp); 137 | } 138 | return $resp; 139 | } 140 | 141 | private function _curlRequest($meth, $absUrl, $headers, $params) 142 | { 143 | $curl = curl_init(); 144 | $meth = strtolower($meth); 145 | $opts = array(); 146 | if ($meth == 'get') { 147 | $opts[CURLOPT_HTTPGET] = 1; 148 | if (count($params) > 0) { 149 | $encoded = self::encode($params); 150 | $absUrl = "$absUrl?$encoded"; 151 | } 152 | } else if ($meth == 'post') { 153 | $opts[CURLOPT_POST] = 1; 154 | $opts[CURLOPT_POSTFIELDS] = self::encode($params); 155 | } else if ($meth == 'delete') { 156 | $opts[CURLOPT_CUSTOMREQUEST] = 'DELETE'; 157 | if (count($params) > 0) { 158 | $encoded = self::encode($params); 159 | $absUrl = "$absUrl?$encoded"; 160 | } 161 | } else { 162 | throw new Stripe_ApiError("Unrecognized method $meth"); 163 | } 164 | 165 | $absUrl = self::utf8($absUrl); 166 | $opts[CURLOPT_URL] = $absUrl; 167 | $opts[CURLOPT_RETURNTRANSFER] = true; 168 | $opts[CURLOPT_CONNECTTIMEOUT] = 30; 169 | $opts[CURLOPT_TIMEOUT] = 80; 170 | $opts[CURLOPT_RETURNTRANSFER] = true; 171 | $opts[CURLOPT_HTTPHEADER] = $headers; 172 | if (!Stripe::$verifySslCerts) 173 | $opts[CURLOPT_SSL_VERIFYPEER] = false; 174 | 175 | curl_setopt_array($curl, $opts); 176 | $rbody = curl_exec($curl); 177 | 178 | $errno = curl_errno($curl); 179 | if ($errno == CURLE_SSL_CACERT || 180 | $errno == CURLE_SSL_PEER_CERTIFICATE || 181 | $errno == 77 // CURLE_SSL_CACERT_BADFILE (constant not defined in PHP though) 182 | ) { 183 | array_push($headers, 'X-Stripe-Client-Info: {"ca":"using Stripe-supplied CA bundle"}'); 184 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 185 | curl_setopt($curl, CURLOPT_CAINFO, 186 | dirname(__FILE__) . '/../data/ca-certificates.crt'); 187 | $rbody = curl_exec($curl); 188 | } 189 | 190 | if ($rbody === false) { 191 | $errno = curl_errno($curl); 192 | $message = curl_error($curl); 193 | curl_close($curl); 194 | $this->handleCurlError($errno, $message); 195 | } 196 | 197 | $rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 198 | curl_close($curl); 199 | return array($rbody, $rcode); 200 | } 201 | 202 | public function handleCurlError($errno, $message) 203 | { 204 | $apiBase = Stripe::$apiBase; 205 | switch ($errno) { 206 | case CURLE_COULDNT_CONNECT: 207 | case CURLE_COULDNT_RESOLVE_HOST: 208 | case CURLE_OPERATION_TIMEOUTED: 209 | $msg = "Could not connect to Stripe ($apiBase). Please check your internet connection and try again. If this problem persists, you should check Stripe's service status at https://twitter.com/stripestatus, or let us know at support@stripe.com."; 210 | break; 211 | case CURLE_SSL_CACERT: 212 | case CURLE_SSL_PEER_CERTIFICATE: 213 | $msg = "Could not verify Stripe's SSL certificate. Please make sure that your network is not intercepting certificates. (Try going to $apiBase in your browser.) If this problem persists, let us know at support@stripe.com."; 214 | break; 215 | default: 216 | $msg = "Unexpected error communicating with Stripe. If this problem persists, let us know at support@stripe.com."; 217 | } 218 | 219 | $msg .= "\n\n(Network error [errno $errno]: $message)"; 220 | throw new Stripe_ApiConnectionError($msg); 221 | } 222 | } 223 | --------------------------------------------------------------------------------