fixes #5249
This commit is contained in:
parent
389b08c572
commit
1f392444fc
@ -138,12 +138,12 @@
|
||||
</text>
|
||||
<stripe>
|
||||
<dev>
|
||||
<secret>***REMOVED***</secret>
|
||||
<public>***REMOVED***</public>
|
||||
<secret>_KEY_</secret>
|
||||
<public>_KEY_</public>
|
||||
</dev>
|
||||
<live>
|
||||
<secret>***REMOVED***</secret>
|
||||
<public>***REMOVED***</public>
|
||||
<secret>_KEY_</secret>
|
||||
<public>_KEY_</public>
|
||||
</live>
|
||||
</stripe>
|
||||
<balanced>
|
||||
|
||||
@ -100,6 +100,7 @@ spl_autoload_register(function ($className) {
|
||||
\Buzz\Bootstrap::init();
|
||||
\Github\Bootstrap::init();
|
||||
\Mailgun\Bootstrap::init();
|
||||
\Stripe\Bootstrap::init();
|
||||
|
||||
$configFile = $GLOBALS['config']['dirs']['config'].'config.demo.xml';
|
||||
if (file_exists($GLOBALS['config']['dirs']['config'].'config.xml')) {
|
||||
|
||||
@ -157,9 +157,6 @@ class Crunchbutton_App extends Cana_App {
|
||||
->config($config)
|
||||
->postInit($params);
|
||||
|
||||
require_once c::config()->dirs->library . '/Cana/Stripe.php';
|
||||
Stripe::setApiKey(c::config()->stripe->dev->secret);
|
||||
|
||||
switch ($_SERVER['SERVER_NAME']) {
|
||||
case 'spicywithdelivery.com':
|
||||
case 'beta.spicywithdelivery.com':
|
||||
@ -462,6 +459,16 @@ class Crunchbutton_App extends Cana_App {
|
||||
}
|
||||
return $this->_balanced;
|
||||
}
|
||||
|
||||
public function stripe() {
|
||||
if (!$this->_stripe) {
|
||||
\Stripe\Stripe::setApiKey(c::config()->stripe->{c::getEnv()}->secret);;
|
||||
$this->_stripe = true;
|
||||
}
|
||||
return $this->_stripe;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function lob($d = true) {
|
||||
if (!$this->_lob) {
|
||||
|
||||
@ -20,7 +20,8 @@ class Crunchbutton_Charge_Balanced extends Cana_Model {
|
||||
$c = $this->_card->debits->create([
|
||||
'amount' => $params['amount'] * 100,
|
||||
'appears_on_statement_as' => 'Crunchbutton',
|
||||
'description' => $params['restaurant']->name
|
||||
'description' => $params['restaurant']->name,
|
||||
'statement_descriptor' => $params['restaurant']->statementName()
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
@ -2,98 +2,103 @@
|
||||
|
||||
class Crunchbutton_Charge_Stripe extends Crunchbutton_Charge {
|
||||
public function __construct($params = []) {
|
||||
|
||||
$this->_customer = $params['customer_id'];
|
||||
$this->_card = $params['card_id'];
|
||||
}
|
||||
|
||||
public function charge($params = []) {
|
||||
|
||||
$env = c::getEnv();
|
||||
|
||||
Stripe::setApiKey(c::config()->stripe->{$env}->secret);
|
||||
c::stripe();
|
||||
|
||||
$success = false;
|
||||
$reason = false;
|
||||
|
||||
$user = $params[ 'user' ];
|
||||
|
||||
// Start with no customer id
|
||||
$customer_id = false;
|
||||
|
||||
// The user changed its card or it is a new one
|
||||
if( $params['card']['id'] ){
|
||||
// The first thing we need to do is check customer
|
||||
$token = $params['card']['uri'];
|
||||
// lets see if the customer exists
|
||||
if ( !$user || !$user->payment_type()->stripe_id ) {
|
||||
// if there is no user, create one
|
||||
try {
|
||||
$customer = Stripe_Customer::create( array(
|
||||
'description' => "Crunchbutton",
|
||||
'card' => $token
|
||||
) );
|
||||
} catch ( Exception $e ) {
|
||||
print_r( $e );
|
||||
die('creating customer error: 1');
|
||||
}
|
||||
} elseif ( $user && $user->payment_type()->stripe_id ) {
|
||||
// if there is already a user, update it
|
||||
try {
|
||||
$customer = Stripe_Customer::retrieve( $user->payment_type()->stripe_id );
|
||||
$customer->card = $token;
|
||||
$customer->save();
|
||||
} catch ( Exception $e ) {
|
||||
print_r( $e );
|
||||
die('creating customer error: 2');
|
||||
}
|
||||
}
|
||||
$customer_id = $customer->id;
|
||||
}
|
||||
// If we don't have a card token it means the user is already a customer
|
||||
else if( $user->payment_type()->stripe_id ) {
|
||||
$customer_id = $user->payment_type()->stripe_id;
|
||||
}
|
||||
|
||||
// yay, we have a valid customer
|
||||
if( $customer_id ){
|
||||
// Now we have to charge it
|
||||
if ($params['card']) {
|
||||
|
||||
// create a customer if it doesnt exist
|
||||
if (!$this->_customer) {
|
||||
try {
|
||||
$charge = Stripe_Charge::create([
|
||||
'amount' => $params['amount'] * 100,
|
||||
'currency' => 'usd',
|
||||
'customer' => $customer_id,
|
||||
'description' => $params['restaurant']->name,
|
||||
] );
|
||||
}
|
||||
// Shit happens
|
||||
catch(Stripe_CardError $e) {
|
||||
Log::debug( [ 'card error' => 'card declined', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Your card was declined. Please try again!';
|
||||
} catch (Stripe_InvalidRequestError $e) {
|
||||
Log::debug( [ 'card error' => 'invalid request', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
} catch (Stripe_AuthenticationError $e) {
|
||||
Log::debug( [ 'card error' => 'auth error', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
} catch (Stripe_ApiConnectionError $e) {
|
||||
Log::debug( [ 'card error' => 'api connection', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
} catch (Stripe_Error $e) {
|
||||
Log::debug( [ 'card error' => 'api connection', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
} catch (Exception $e) {
|
||||
$errors[] = 'Not enough card information.';
|
||||
}
|
||||
$customer = \Stripe\Customer::create([
|
||||
'description' => $params['name'],
|
||||
'email' => $params['email'],
|
||||
'source' => $params['card']['uri']
|
||||
]);
|
||||
|
||||
if ( $charge->paid && !$charge->refunded ) {
|
||||
$success = true;
|
||||
$txn = $charge->id;
|
||||
}
|
||||
}
|
||||
if (!$success && !$errors) {
|
||||
$errors[] = 'Not enough card information.';
|
||||
} catch ( Exception $e ) {
|
||||
$errors[] = 'Could not create customer with processor.';
|
||||
}
|
||||
$this->_customer = $customer->id;
|
||||
|
||||
// there is already a customer
|
||||
} else {
|
||||
try {
|
||||
$customer = \Stripe\Customer::retrieve($this->_customer);
|
||||
$customer->card = $params['card']['token'];
|
||||
$customer->save();
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
$errors[] = 'Could not retrieve or save customer to processor.';
|
||||
}
|
||||
}
|
||||
|
||||
$this->_card = $params['card']['id'];
|
||||
}
|
||||
|
||||
return [ 'status' => $success, 'txn' => $txn, 'errors' => $errors, 'customer' => $customer ];
|
||||
// Now we have to charge it
|
||||
try {
|
||||
$charge = \Stripe\Charge::create([
|
||||
'amount' => $params['amount'] * 100,
|
||||
'currency' => 'usd',
|
||||
'customer' => $this->_customer,
|
||||
//'source' => $this->_card,
|
||||
'description' => $params['restaurant']->name,
|
||||
'capture' => c::config()->site->config('processor_payments_capture') ? true : false,
|
||||
'statement_descriptor' => $params['restaurant']->statementName()
|
||||
]);
|
||||
|
||||
} catch(\Stripe\Stripe_CardError $e) {
|
||||
Log::debug( [ 'card error' => 'card declined', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Your card was declined. Please try again!';
|
||||
|
||||
} catch (\Stripe\Stripe_InvalidRequestError $e) {
|
||||
Log::debug( [ 'card error' => 'invalid request', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
|
||||
} catch (\Stripe\Stripe_AuthenticationError $e) {
|
||||
Log::debug( [ 'card error' => 'auth error', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
|
||||
} catch (\Stripe\Stripe_ApiConnectionError $e) {
|
||||
Log::debug( [ 'card error' => 'api connection', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
|
||||
} catch (\Stripe\Stripe_Error $e) {
|
||||
Log::debug( [ 'card error' => 'api connection', 'Exception' => $e->getJsonBody(), 'type' => 'stripe error' ]);
|
||||
$errors[] = 'Please update your credit card information.';
|
||||
|
||||
} catch (Exception $e) {
|
||||
//tripe\Error\InvalidRequest
|
||||
//Stripe\Error\Card
|
||||
print_r($e);
|
||||
$errors[] = 'Error processing credit card.';
|
||||
}
|
||||
|
||||
if ($charge && $charge->paid && !$charge->refunded) {
|
||||
$success = true;
|
||||
$txn = $charge->id;
|
||||
}
|
||||
|
||||
if (!$success && !$errors) {
|
||||
$errors[] = 'Completly vague payment error. Contact support and complain. We love complaints.'."\n\n".'angrycustomers@_DOMAIN_';
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => $success,
|
||||
'txn' => $txn,
|
||||
'errors' => $errors,
|
||||
'customer' => $this->_customer,
|
||||
'card' => $this->_card
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@ -564,11 +564,9 @@ class Crunchbutton_Order extends Crunchbutton_Order_Trackchange {
|
||||
|
||||
switch (Crunchbutton_User_Payment_Type::processor()) {
|
||||
case 'stripe':
|
||||
$payment_type->stripe_id = $this->_customer->id;
|
||||
$payment_type->stripe_id = $this->_paymentType;
|
||||
break;
|
||||
|
||||
case 'balanced':
|
||||
default:
|
||||
$payment_type->balanced_id = $this->_paymentType->id;
|
||||
break;
|
||||
}
|
||||
@ -949,32 +947,34 @@ class Crunchbutton_Order extends Crunchbutton_Order_Trackchange {
|
||||
|
||||
case 'card':
|
||||
$user = c::user()->id_user ? c::user() : null;
|
||||
$processorId = c::config()->site->config('processor_payments') == 'balanced' ? 'balanced_id' : 'stripe_id';
|
||||
|
||||
if( $user ){
|
||||
if ($user) {
|
||||
$paymentType = $user->payment_type();
|
||||
}
|
||||
|
||||
if (!$this->_card['id'] && !$paymentType->id_user_payment_type && $user->balanced_id) {
|
||||
// user only has a balanced customer id, not a payment. copy payment type over
|
||||
$paymentType = (new User_Payment_Type([
|
||||
'id_user' => $user->id_user,
|
||||
'active' => 1,
|
||||
// 'stripe_id' => $user->stripe_id,
|
||||
'balanced_id' => $user->balanced_id,
|
||||
'card' => $user->card,
|
||||
'card_exp_month' => $user->card_exp_month,
|
||||
'card_exp_year' => $user->card_exp_year,
|
||||
'date' => date('Y-m-d H:i:s')
|
||||
]))->save();
|
||||
// #5243 - if using stripe, get the stripe id from balanced, and update the paymenttype
|
||||
if (c::config()->site->config('processor_payments') == 'stripe' && $paymentType->balanced_id && !$paymentType->stripe_id) {
|
||||
$balancedCard = Crunchbutton_Balanced_Card::byId($paymentType->balanced_id);
|
||||
print_r($balancedCard);
|
||||
exit;
|
||||
}
|
||||
|
||||
// use a stored users card and the apporiate payment type
|
||||
|
||||
if (!$this->_card['id'] && $paymentType->id_user_payment_type) {
|
||||
// use a stored users card and the apporiate payment type
|
||||
|
||||
if ($paymentType->balanced_id) {
|
||||
if (c::config()->site->config('processor_payments') == 'stripe' && $paymentType->stripe_id) {
|
||||
$charge = new Charge_Stripe([
|
||||
'card_id' => $paymentType->stripe_id,
|
||||
'customer_id' => $user->stripe_id
|
||||
]);
|
||||
|
||||
} elseif (c::config()->site->config('processor_payments') == 'balanced' && $paymentType->balanced_id) {
|
||||
|
||||
if (substr($paymentType->balanced_id,0,2) != 'CC') {
|
||||
// we have stored the customer and not the payment type. need to fix that
|
||||
// @todo: i dont really understand wtf this is for - devin
|
||||
$cards = Crunchbutton_Balanced_Account::byId($paymentType->balanced_id)->cards;
|
||||
if (get_class($cards) == 'RESTful\Collection') {
|
||||
foreach ($cards as $card) {
|
||||
@ -996,23 +996,19 @@ class Crunchbutton_Order extends Crunchbutton_Order_Trackchange {
|
||||
$charge = new Charge_Balanced([
|
||||
'card_id' => $paymentType->balanced_id
|
||||
]);
|
||||
|
||||
} elseif ($paymentType->stripe_id) {
|
||||
$charge = new Charge_Stripe([
|
||||
'stripe_id' => $paymentType->stripe_id
|
||||
]);
|
||||
} else {
|
||||
die('processor mismatch');
|
||||
}
|
||||
}
|
||||
|
||||
// create the objects with no params
|
||||
if (!$charge) {
|
||||
switch (Crunchbutton_User_Payment_Type::processor()) {
|
||||
case 'balanced':
|
||||
$charge = new Charge_Balanced();
|
||||
break;
|
||||
case 'stripe':
|
||||
$charge = new Charge_Stripe([
|
||||
'stripe_id' => $user->stripe_id
|
||||
]);
|
||||
$charge = new Charge_Stripe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1029,6 +1025,7 @@ class Crunchbutton_Order extends Crunchbutton_Order_Trackchange {
|
||||
'card' => $this->_card,
|
||||
'name' => $this->name,
|
||||
'address' => $this->address,
|
||||
'email' => $user->email,
|
||||
'phone' => $this->phone,
|
||||
'user' => $user,
|
||||
'restaurant' => $this->restaurant()
|
||||
|
||||
@ -154,8 +154,17 @@ class Crunchbutton_Restaurant extends Cana_Table_Trackchange {
|
||||
return $phone;
|
||||
}
|
||||
|
||||
public function shortName() {
|
||||
return $this->short_name ? $this->short_name : $this->name;
|
||||
// name that appears on credit card statement
|
||||
public function statementName() {
|
||||
if (!isset($this->_statementName)) {
|
||||
$name = $this->short_name ? $this->short_name : $this->name;
|
||||
$name = preg_replace('/[^a-z ]/i','',$name);
|
||||
if (strlen($name) > 22) {
|
||||
$name = str_replace(' ', '', $name);
|
||||
}
|
||||
$this->_statementName = strtoupper(substr($name, 0, 22));
|
||||
}
|
||||
return $this->_statementName;
|
||||
}
|
||||
|
||||
public function _hasOption($option, $options) {
|
||||
|
||||
@ -3,18 +3,27 @@
|
||||
class Crunchbutton_User_Payment_Type extends Cana_Table {
|
||||
|
||||
public function processor() {
|
||||
return c::config()->processor;
|
||||
return c::config()->site->config('processor_payments')->value;
|
||||
}
|
||||
|
||||
public function getUserPaymentType( $id_user = null ){
|
||||
$id_user = ( $id_user ) ? $id_user : c::user()->id_user;
|
||||
if( $id_user ){
|
||||
$where = ' AND ' . Crunchbutton_User_Payment_Type::processor() . '_id IS NOT NULL';
|
||||
$payment = Crunchbutton_User_Payment_Type::q( 'SELECT * FROM user_payment_type WHERE id_user = ? AND active = true ' . $where . ' ORDER BY id_user_payment_type DESC LIMIT 1', [$id_user]);
|
||||
if( $payment->id_user_payment_type ){
|
||||
public function getUserPaymentType($id_user = null) {
|
||||
$id_user = $id_user ? $id_user : c::user()->id_user;
|
||||
|
||||
if ($id_user) {
|
||||
$payment = Crunchbutton_User_Payment_Type::q('
|
||||
SELECT * FROM user_payment_type
|
||||
WHERE
|
||||
id_user = ?
|
||||
AND active = true
|
||||
AND ' . Crunchbutton_User_Payment_Type::processor() . '_id IS NOT NULL
|
||||
ORDER BY id_user_payment_type DESC LIMIT 1
|
||||
', [$id_user]);
|
||||
|
||||
if ($payment->id_user_payment_type) {
|
||||
return $payment;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
62
include/library/Stripe/Account.php
Executable file
62
include/library/Stripe/Account.php
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Account extends ApiResource
|
||||
{
|
||||
public function instanceUrl()
|
||||
{
|
||||
if ($this['id'] === null) {
|
||||
return '/v1/account';
|
||||
} else {
|
||||
return parent::instanceUrl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $id
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public static function retrieve($id = null, $opts = null)
|
||||
{
|
||||
if (!$opts && is_string($id) && substr($id, 0, 3) === 'sk_') {
|
||||
$opts = $id;
|
||||
$id = null;
|
||||
}
|
||||
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 array|string|null $opts
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Account[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
471
include/library/Stripe/ApiRequestor.php
Executable file
471
include/library/Stripe/ApiRequestor.php
Executable file
@ -0,0 +1,471 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class ApiRequestor
|
||||
{
|
||||
private $_apiKey;
|
||||
|
||||
private $_apiBase;
|
||||
|
||||
private static $_preFlight = array();
|
||||
|
||||
private static $_blacklistedCerts = array(
|
||||
'05c0b3643694470a888c6e7feb5c9e24e823dc53',
|
||||
'5b7dc7fbc98d78bf76d4d4fa6f597a0c901fad5c',
|
||||
);
|
||||
|
||||
public function __construct($apiKey = null, $apiBase = null)
|
||||
{
|
||||
$this->_apiKey = $apiKey;
|
||||
if (!$apiBase) {
|
||||
$apiBase = Stripe::$apiBase;
|
||||
}
|
||||
$this->_apiBase = $apiBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|mixed $value A string to UTF8-encode.
|
||||
*
|
||||
* @return string|mixed The UTF8-encoded string, or the object passed in if
|
||||
* it wasn't a string.
|
||||
*/
|
||||
public static function utf8($value)
|
||||
{
|
||||
if (is_string($value) && mb_detect_encoding($value, "UTF-8", true) != "UTF-8") {
|
||||
return utf8_encode($value);
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
private static function _encodeObjects($d)
|
||||
{
|
||||
if ($d instanceof ApiResource) {
|
||||
return self::utf8($d->id);
|
||||
} elseif ($d === true) {
|
||||
return 'true';
|
||||
} elseif ($d === false) {
|
||||
return 'false';
|
||||
} elseif (is_array($d)) {
|
||||
$res = array();
|
||||
foreach ($d as $k => $v) {
|
||||
$res[$k] = self::_encodeObjects($v);
|
||||
}
|
||||
return $res;
|
||||
} else {
|
||||
return self::utf8($d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arr An map of param keys to values.
|
||||
* @param string|null $prefix (It doesn't look like we ever use $prefix...)
|
||||
*
|
||||
* @return string A querystring, essentially.
|
||||
*/
|
||||
public static function encode($arr, $prefix = null)
|
||||
{
|
||||
if (!is_array($arr)) {
|
||||
return $arr;
|
||||
}
|
||||
|
||||
$r = array();
|
||||
foreach ($arr as $k => $v) {
|
||||
if (is_null($v)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($prefix && $k && !is_int($k)) {
|
||||
$k = $prefix."[".$k."]";
|
||||
} elseif ($prefix) {
|
||||
$k = $prefix."[]";
|
||||
}
|
||||
|
||||
if (is_array($v)) {
|
||||
$r[] = self::encode($v, $k, true);
|
||||
} else {
|
||||
$r[] = urlencode($k)."=".urlencode($v);
|
||||
}
|
||||
}
|
||||
|
||||
return implode("&", $r);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array|null $params
|
||||
* @param array|null $headers
|
||||
*
|
||||
* @return array An array whose first element is the response and second
|
||||
* element is the API key used to make the request.
|
||||
*/
|
||||
public function request($method, $url, $params = null, $headers = null)
|
||||
{
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
if (!$headers) {
|
||||
$headers = array();
|
||||
}
|
||||
list($rbody, $rcode, $myApiKey) =
|
||||
$this->_requestRaw($method, $url, $params, $headers);
|
||||
$resp = $this->_interpretResponse($rbody, $rcode);
|
||||
return array($resp, $myApiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $rbody A JSON string.
|
||||
* @param int $rcode
|
||||
* @param array $resp
|
||||
*
|
||||
* @throws Error\InvalidRequest if the error is caused by the user.
|
||||
* @throws Error\Authentication if the error is caused by a lack of
|
||||
* permissions.
|
||||
* @throws Error\Card if the error is the error code is 402 (payment
|
||||
* required)
|
||||
* @throws Error\Api otherwise.
|
||||
*/
|
||||
public function handleApiError($rbody, $rcode, $resp)
|
||||
{
|
||||
if (!is_array($resp) || !isset($resp['error'])) {
|
||||
$msg = "Invalid response object from API: $rbody "
|
||||
. "(HTTP response code was $rcode)";
|
||||
throw new Error\Api($msg, $rcode, $rbody, $resp);
|
||||
}
|
||||
|
||||
$error = $resp['error'];
|
||||
$msg = isset($error['message']) ? $error['message'] : null;
|
||||
$param = isset($error['param']) ? $error['param'] : null;
|
||||
$code = isset($error['code']) ? $error['code'] : null;
|
||||
|
||||
switch ($rcode) {
|
||||
case 400:
|
||||
if ($code == 'rate_limit') {
|
||||
throw new Error\RateLimit($msg, $param, $rcode, $rbody, $resp);
|
||||
}
|
||||
|
||||
// intentional fall-through
|
||||
case 404:
|
||||
throw new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp);
|
||||
case 401:
|
||||
throw new Error\Authentication($msg, $rcode, $rbody, $resp);
|
||||
case 402:
|
||||
throw new Error\Card($msg, $param, $code, $rcode, $rbody, $resp);
|
||||
default:
|
||||
throw new Error\Api($msg, $rcode, $rbody, $resp);
|
||||
}
|
||||
}
|
||||
|
||||
private function _requestRaw($method, $url, $params, $headers)
|
||||
{
|
||||
if (!array_key_exists($this->_apiBase, self::$_preFlight) ||
|
||||
!self::$_preFlight[$this->_apiBase]) {
|
||||
self::$_preFlight[$this->_apiBase] = $this->checkSslCert($this->_apiBase);
|
||||
}
|
||||
|
||||
$myApiKey = $this->_apiKey;
|
||||
if (!$myApiKey) {
|
||||
$myApiKey = Stripe::$apiKey;
|
||||
}
|
||||
|
||||
if (!$myApiKey) {
|
||||
$msg = 'No API key provided. (HINT: set your API key using '
|
||||
. '"Stripe::setApiKey(<API-KEY>)". 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.';
|
||||
throw new Error\Authentication($msg);
|
||||
}
|
||||
|
||||
$absUrl = $this->_apiBase.$url;
|
||||
$params = self::_encodeObjects($params);
|
||||
$langVersion = phpversion();
|
||||
$uname = php_uname();
|
||||
$ua = array(
|
||||
'bindings_version' => Stripe::VERSION,
|
||||
'lang' => 'php',
|
||||
'lang_version' => $langVersion,
|
||||
'publisher' => 'stripe',
|
||||
'uname' => $uname,
|
||||
);
|
||||
$defaultHeaders = array(
|
||||
'X-Stripe-Client-User-Agent' => json_encode($ua),
|
||||
'User-Agent' => 'Stripe/v1 PhpBindings/' . Stripe::VERSION,
|
||||
'Authorization' => 'Bearer ' . $myApiKey,
|
||||
);
|
||||
if (Stripe::$apiVersion) {
|
||||
$defaultHeaders['Stripe-Version'] = Stripe::$apiVersion;
|
||||
}
|
||||
$hasFile = false;
|
||||
$hasCurlFile = class_exists('\CURLFile', false);
|
||||
foreach ($params as $k => $v) {
|
||||
if (is_resource($v)) {
|
||||
$hasFile = true;
|
||||
$params[$k] = self::_processResourceParam($v, $hasCurlFile);
|
||||
} elseif ($hasCurlFile && $v instanceof \CURLFile) {
|
||||
$hasFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasFile) {
|
||||
$defaultHeaders['Content-Type'] = 'multipart/form-data';
|
||||
} else {
|
||||
$defaultHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
|
||||
$combinedHeaders = array_merge($defaultHeaders, $headers);
|
||||
$rawHeaders = array();
|
||||
|
||||
foreach ($combinedHeaders as $header => $value) {
|
||||
$rawHeaders[] = $header . ': ' . $value;
|
||||
}
|
||||
|
||||
list($rbody, $rcode) = $this->_curlRequest(
|
||||
$method,
|
||||
$absUrl,
|
||||
$rawHeaders,
|
||||
$params,
|
||||
$hasFile
|
||||
);
|
||||
return array($rbody, $rcode, $myApiKey);
|
||||
}
|
||||
|
||||
private function _processResourceParam($resource, $hasCurlFile)
|
||||
{
|
||||
if (get_resource_type($resource) !== 'stream') {
|
||||
throw new Error\Api(
|
||||
'Attempted to upload a resource that is not a stream'
|
||||
);
|
||||
}
|
||||
|
||||
$metaData = stream_get_meta_data($resource);
|
||||
if ($metaData['wrapper_type'] !== 'plainfile') {
|
||||
throw new Error\Api(
|
||||
'Only plainfile resource streams are supported'
|
||||
);
|
||||
}
|
||||
|
||||
if ($hasCurlFile) {
|
||||
// We don't have the filename or mimetype, but the API doesn't care
|
||||
return new \CURLFile($metaData['uri']);
|
||||
} else {
|
||||
return '@'.$metaData['uri'];
|
||||
}
|
||||
}
|
||||
|
||||
private function _interpretResponse($rbody, $rcode)
|
||||
{
|
||||
try {
|
||||
$resp = json_decode($rbody, true);
|
||||
} catch (Exception $e) {
|
||||
$msg = "Invalid response body from API: $rbody "
|
||||
. "(HTTP response code was $rcode)";
|
||||
throw new Error\Api($msg, $rcode, $rbody);
|
||||
}
|
||||
|
||||
if ($rcode < 200 || $rcode >= 300) {
|
||||
$this->handleApiError($rbody, $rcode, $resp);
|
||||
}
|
||||
return $resp;
|
||||
}
|
||||
|
||||
private function _curlRequest($method, $absUrl, $headers, $params, $hasFile)
|
||||
{
|
||||
$curl = curl_init();
|
||||
$method = strtolower($method);
|
||||
$opts = array();
|
||||
if ($method == 'get') {
|
||||
if ($hasFile) {
|
||||
throw new Error\Api(
|
||||
"Issuing a GET request with a file parameter"
|
||||
);
|
||||
}
|
||||
$opts[CURLOPT_HTTPGET] = 1;
|
||||
if (count($params) > 0) {
|
||||
$encoded = self::encode($params);
|
||||
$absUrl = "$absUrl?$encoded";
|
||||
}
|
||||
} elseif ($method == 'post') {
|
||||
$opts[CURLOPT_POST] = 1;
|
||||
$opts[CURLOPT_POSTFIELDS] = $hasFile ? $params : self::encode($params);
|
||||
} elseif ($method == 'delete') {
|
||||
$opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
|
||||
if (count($params) > 0) {
|
||||
$encoded = self::encode($params);
|
||||
$absUrl = "$absUrl?$encoded";
|
||||
}
|
||||
} else {
|
||||
throw new Error\Api("Unrecognized method $method");
|
||||
}
|
||||
|
||||
$absUrl = self::utf8($absUrl);
|
||||
$opts[CURLOPT_URL] = $absUrl;
|
||||
$opts[CURLOPT_RETURNTRANSFER] = true;
|
||||
$opts[CURLOPT_CONNECTTIMEOUT] = 30;
|
||||
$opts[CURLOPT_TIMEOUT] = 80;
|
||||
$opts[CURLOPT_RETURNTRANSFER] = true;
|
||||
$opts[CURLOPT_HTTPHEADER] = $headers;
|
||||
if (!Stripe::$verifySslCerts) {
|
||||
$opts[CURLOPT_SSL_VERIFYPEER] = false;
|
||||
}
|
||||
|
||||
curl_setopt_array($curl, $opts);
|
||||
$rbody = curl_exec($curl);
|
||||
|
||||
if (!defined('CURLE_SSL_CACERT_BADFILE')) {
|
||||
define('CURLE_SSL_CACERT_BADFILE', 77); // constant not defined in PHP
|
||||
}
|
||||
|
||||
$errno = curl_errno($curl);
|
||||
if ($errno == CURLE_SSL_CACERT ||
|
||||
$errno == CURLE_SSL_PEER_CERTIFICATE ||
|
||||
$errno == CURLE_SSL_CACERT_BADFILE
|
||||
) {
|
||||
array_push(
|
||||
$headers,
|
||||
'X-Stripe-Client-Info: {"ca":"using Stripe-supplied CA bundle"}'
|
||||
);
|
||||
$cert = $this->caBundle();
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_CAINFO, $cert);
|
||||
$rbody = curl_exec($curl);
|
||||
}
|
||||
|
||||
if ($rbody === false) {
|
||||
$errno = curl_errno($curl);
|
||||
$message = curl_error($curl);
|
||||
curl_close($curl);
|
||||
$this->handleCurlError($errno, $message);
|
||||
}
|
||||
|
||||
$rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
curl_close($curl);
|
||||
return array($rbody, $rcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number $errno
|
||||
* @param string $message
|
||||
* @throws ApiConnectionError
|
||||
*/
|
||||
public function handleCurlError($errno, $message)
|
||||
{
|
||||
$apiBase = $this->_apiBase;
|
||||
switch ($errno) {
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
case CURLE_OPERATION_TIMEOUTED:
|
||||
$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";
|
||||
break;
|
||||
case CURLE_SSL_CACERT:
|
||||
case CURLE_SSL_PEER_CERTIFICATE:
|
||||
$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,";
|
||||
break;
|
||||
default:
|
||||
$msg = "Unexpected error communicating with Stripe. "
|
||||
. "If this problem persists,";
|
||||
}
|
||||
$msg .= " let us know at support@stripe.com.";
|
||||
|
||||
$msg .= "\n\n(Network error [errno $errno]: $message)";
|
||||
throw new Error\ApiConnection($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preflight the SSL certificate presented by the backend. This isn't 100%
|
||||
* bulletproof, in that we're not actually validating the transport used to
|
||||
* communicate with Stripe, merely that the first attempt to does not use a
|
||||
* revoked certificate.
|
||||
*
|
||||
* Unfortunately the interface to OpenSSL doesn't make it easy to check the
|
||||
* certificate before sending potentially sensitive data on the wire. This
|
||||
* approach raises the bar for an attacker significantly.
|
||||
*/
|
||||
private function checkSslCert($url)
|
||||
{
|
||||
if (!function_exists('stream_context_get_params') ||
|
||||
!function_exists('stream_socket_enable_crypto')) {
|
||||
error_log(
|
||||
'Warning: This version of PHP does not support checking SSL ' .
|
||||
'certificates Stripe cannot guarantee that the server has a ' .
|
||||
'certificate which is not blacklisted.'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
$url = parse_url($url);
|
||||
$port = isset($url["port"]) ? $url["port"] : 443;
|
||||
$url = "ssl://{$url["host"]}:{$port}";
|
||||
|
||||
$sslContext = stream_context_create(
|
||||
array('ssl' => array(
|
||||
'capture_peer_cert' => true,
|
||||
'verify_peer' => true,
|
||||
'cafile' => $this->caBundle(),
|
||||
))
|
||||
);
|
||||
$result = stream_socket_client(
|
||||
$url,
|
||||
$errno,
|
||||
$errstr,
|
||||
30,
|
||||
STREAM_CLIENT_CONNECT,
|
||||
$sslContext
|
||||
);
|
||||
if (($errno !== 0 && $errno !== null) || $result === false) {
|
||||
throw new Error\ApiConnection(
|
||||
'Could not connect to Stripe (' . $url . '). Please check your ' .
|
||||
'internet connection and try again. If this problem persists, ' .
|
||||
'you should check Stripe\'s service status at ' .
|
||||
'https://twitter.com/stripestatus. Reason was: ' . $errstr
|
||||
);
|
||||
}
|
||||
|
||||
$params = stream_context_get_params($result);
|
||||
|
||||
$cert = $params['options']['ssl']['peer_certificate'];
|
||||
|
||||
openssl_x509_export($cert, $pemCert);
|
||||
|
||||
if (self::isBlackListed($pemCert)) {
|
||||
throw new Error\ApiConnection(
|
||||
'Invalid server certificate. You tried to connect to a server that ' .
|
||||
'has a revoked SSL certificate, which means we cannot securely send ' .
|
||||
'data to that server. Please email support@stripe.com if you need ' .
|
||||
'help connecting to the correct API server.'
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a valid PEM encoded certificate is blacklisted
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isBlackListed($certificate)
|
||||
{
|
||||
$certificate = trim($certificate);
|
||||
$lines = explode("\n", $certificate);
|
||||
|
||||
// Kludgily remove the PEM padding
|
||||
array_shift($lines);
|
||||
array_pop($lines);
|
||||
|
||||
$derCert = base64_decode(implode("", $lines));
|
||||
$fingerprint = sha1($derCert);
|
||||
return in_array($fingerprint, self::$_blacklistedCerts);
|
||||
}
|
||||
|
||||
private function caBundle()
|
||||
{
|
||||
return dirname(__FILE__) . '/../../../ssl/ca-certificates.crt';
|
||||
}
|
||||
}
|
||||
161
include/library/Stripe/ApiResource.php
Executable file
161
include/library/Stripe/ApiResource.php
Executable file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
abstract class ApiResource extends Object
|
||||
{
|
||||
private static $HEADERS_TO_PERSIST = array('Stripe-Account' => true, 'Stripe-Version' => true);
|
||||
|
||||
public static function baseUrl()
|
||||
{
|
||||
return Stripe::$apiBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApiResource The refreshed resource.
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
$requestor = new ApiRequestor($this->_opts->apiKey, static::baseUrl());
|
||||
$url = $this->instanceUrl();
|
||||
|
||||
list($response, $this->_opts->apiKey) = $requestor->request(
|
||||
'get',
|
||||
$url,
|
||||
$this->_retrieveOptions,
|
||||
$this->_opts->headers
|
||||
);
|
||||
$this->refreshFrom($response, $this->_opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The name of the class, with namespacing and underscores
|
||||
* stripped.
|
||||
*/
|
||||
public static function className()
|
||||
{
|
||||
$class = get_called_class();
|
||||
// Useful for namespaces: Foo\Charge
|
||||
if ($postfixNamespaces = strrchr($class, '\\')) {
|
||||
$class = substr($postfixNamespaces, 1);
|
||||
}
|
||||
// Useful for underscored 'namespaces': Foo_Charge
|
||||
if ($postfixFakeNamespaces = strrchr($class, '')) {
|
||||
$class = $postfixFakeNamespaces;
|
||||
}
|
||||
if (substr($class, 0, strlen('Stripe')) == 'Stripe') {
|
||||
$class = substr($class, strlen('Stripe'));
|
||||
}
|
||||
$class = str_replace('_', '', $class);
|
||||
$name = urlencode($class);
|
||||
$name = strtolower($name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The endpoint URL for the given class.
|
||||
*/
|
||||
public static function classUrl()
|
||||
{
|
||||
$base = static::className();
|
||||
return "/v1/${base}s";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The full API URL for this API resource.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
$id = $this['id'];
|
||||
if ($id === null) {
|
||||
$class = get_called_class();
|
||||
$message = "Could not determine which URL to request: "
|
||||
. "$class instance has invalid ID: $id";
|
||||
throw new Error\InvalidRequest($message, null);
|
||||
}
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$base = static::classUrl();
|
||||
$extn = urlencode($id);
|
||||
return "$base/$extn";
|
||||
}
|
||||
|
||||
private 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);
|
||||
return static::_staticRequest($method, $url, $params, $opts);
|
||||
}
|
||||
|
||||
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);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
protected static function _create($params = null, $options = null)
|
||||
{
|
||||
self::_validateParams($params);
|
||||
$base = static::baseUrl();
|
||||
$url = static::classUrl();
|
||||
|
||||
list($response, $opts) = static::_staticRequest('post', $url, $params, $options);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
53
include/library/Stripe/ApplicationFee.php
Executable file
53
include/library/Stripe/ApplicationFee.php
Executable file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class ApplicationFee extends ApiResource
|
||||
{
|
||||
/**
|
||||
* This is a special case because the application fee endpoint has an
|
||||
* underscore in it. The parent `className` function strips underscores.
|
||||
*
|
||||
* @return string The name of the class.
|
||||
*/
|
||||
public static function className()
|
||||
{
|
||||
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 array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return ApplicationFee[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return ApplicationFee The refunded application fee.
|
||||
*/
|
||||
public function refund($params = null, $opts = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/refund';
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $opts);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
39
include/library/Stripe/ApplicationFeeRefund.php
Executable file
39
include/library/Stripe/ApplicationFeeRefund.php
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class ApplicationFeeRefund extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The API URL for this Stripe refund.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
$id = $this['id'];
|
||||
$fee = $this['fee'];
|
||||
if (!$id) {
|
||||
throw new Error\InvalidRequest(
|
||||
"Could not determine which URL to request: " .
|
||||
"class instance has invalid ID: $id",
|
||||
null
|
||||
);
|
||||
}
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$fee = ApiRequestor::utf8($fee);
|
||||
|
||||
$base = ApplicationFee::classUrl();
|
||||
$feeExtn = urlencode($fee);
|
||||
$extn = urlencode($id);
|
||||
return "$base/$feeExtn/refunds/$extn";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return ApplicationFeeRefund The saved refund.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
25
include/library/Stripe/AttachedObject.php
Executable file
25
include/library/Stripe/AttachedObject.php
Executable file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
// e.g. metadata on Stripe objects.
|
||||
class AttachedObject extends Object
|
||||
{
|
||||
/**
|
||||
* Updates this object.
|
||||
*
|
||||
* @param array $properties A mapping of properties to update on this object.
|
||||
*/
|
||||
public function replaceWith($properties)
|
||||
{
|
||||
$removed = array_diff(array_keys($this->_values), array_keys($properties));
|
||||
// Don't unset, but rather set to null so we send up '' for deletion.
|
||||
foreach ($removed as $k) {
|
||||
$this->$k = null;
|
||||
}
|
||||
|
||||
foreach ($properties as $k => $v) {
|
||||
$this->$k = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
include/library/Stripe/Balance.php
Executable file
16
include/library/Stripe/Balance.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Balance extends SingletonApiResource
|
||||
{
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Balance
|
||||
*/
|
||||
public static function retrieve($opts = null)
|
||||
{
|
||||
return self::_singletonRetrieve($opts);
|
||||
}
|
||||
}
|
||||
37
include/library/Stripe/BalanceTransaction.php
Executable file
37
include/library/Stripe/BalanceTransaction.php
Executable file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class BalanceTransaction extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The class URL for this resource. It needs to be special
|
||||
* cased because it doesn't fit into the standard resource pattern.
|
||||
*/
|
||||
public static function classUrl()
|
||||
{
|
||||
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 array An array of BalanceTransactions.
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
97
include/library/Stripe/BitcoinReceiver.php
Executable file
97
include/library/Stripe/BitcoinReceiver.php
Executable file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class BitcoinReceiver extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The class URL for this resource. It needs to be special
|
||||
* cased because it doesn't fit into the standard resource pattern.
|
||||
*/
|
||||
public static function classUrl()
|
||||
{
|
||||
return "/v1/bitcoin/receivers";
|
||||
}
|
||||
|
||||
/**
|
||||
* @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()
|
||||
{
|
||||
$id = $this['id'];
|
||||
if (!$id) {
|
||||
$class = get_class($this);
|
||||
$msg = "Could not determine which URL to request: $class instance "
|
||||
. "has invalid ID: $id";
|
||||
throw new Error\InvalidRequest($msg, null);
|
||||
}
|
||||
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$extn = urlencode($id);
|
||||
|
||||
if (!$this['customer']) {
|
||||
$base = BitcoinReceiver::classUrl();
|
||||
return "$base/$extn";
|
||||
} else {
|
||||
$base = Customer::classUrl();
|
||||
$parent = ApiRequestor::utf8($this['customer']);
|
||||
$parentExtn = urlencode($parent);
|
||||
return "$base/$parentExtn/sources/$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 BitcoinReceiver[].
|
||||
*/
|
||||
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 $opts
|
||||
*
|
||||
* @return BitcoinReceiver The deleted Bitcoin Receiver item.
|
||||
*/
|
||||
public function delete($params = null, $opts = null)
|
||||
{
|
||||
return $this->_delete($params, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return BitcoinReceiver The saved Bitcoin Receiver item.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
8
include/library/Stripe/BitcoinTransaction.php
Executable file
8
include/library/Stripe/BitcoinTransaction.php
Executable file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class BitcoinTransaction extends ApiResource
|
||||
{
|
||||
|
||||
}
|
||||
46
include/library/Stripe/Bootstrap.php
Normal file
46
include/library/Stripe/Bootstrap.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
/**
|
||||
* Bootstrapper for Stripe does autoloading and resource initialization.
|
||||
*/
|
||||
class Bootstrap
|
||||
{
|
||||
const DIR_SEPARATOR = DIRECTORY_SEPARATOR;
|
||||
const NAMESPACE_SEPARATOR = '\\';
|
||||
|
||||
public static $initialized = false;
|
||||
|
||||
|
||||
public static function init()
|
||||
{
|
||||
spl_autoload_register(array('\Stripe\Bootstrap', 'autoload'));
|
||||
}
|
||||
|
||||
public static function autoload($classname)
|
||||
{
|
||||
self::_autoload(dirname(dirname(__FILE__)), $classname);
|
||||
}
|
||||
|
||||
public static function pharInit()
|
||||
{
|
||||
spl_autoload_register(array('\Stripe\Bootstrap', 'pharAutoload'));
|
||||
}
|
||||
|
||||
public static function pharAutoload($classname)
|
||||
{
|
||||
self::_autoload('phar://Stripe.phar', $classname);
|
||||
}
|
||||
|
||||
private static function _autoload($base, $classname)
|
||||
{
|
||||
$parts = explode(self::NAMESPACE_SEPARATOR, $classname);
|
||||
$path = $base . self::DIR_SEPARATOR. implode(self::DIR_SEPARATOR, $parts) . '.php';
|
||||
if (file_exists($path)) {
|
||||
require_once($path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
59
include/library/Stripe/Card.php
Executable file
59
include/library/Stripe/Card.php
Executable file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Card extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @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()
|
||||
{
|
||||
$id = $this['id'];
|
||||
if (!$id) {
|
||||
$class = get_class($this);
|
||||
$msg = "Could not determine which URL to request: $class instance "
|
||||
. "has invalid ID: $id";
|
||||
throw new Error\InvalidRequest($msg, null);
|
||||
}
|
||||
|
||||
if (isset($this['customer'])) {
|
||||
$parent = $this['customer'];
|
||||
$base = Customer::classUrl();
|
||||
} elseif (isset($this['recipient'])) {
|
||||
$parent = $this['recipient'];
|
||||
$base = Recipient::classUrl();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = ApiRequestor::utf8($parent);
|
||||
$id = ApiRequestor::utf8($id);
|
||||
|
||||
$parentExtn = urlencode($parent);
|
||||
$extn = urlencode($id);
|
||||
return "$base/$parentExtn/cards/$extn";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Card The deleted card.
|
||||
*/
|
||||
public function delete($params = null, $opts = null)
|
||||
{
|
||||
return $this->_delete($params, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Card The saved card.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
132
include/library/Stripe/Charge.php
Executable file
132
include/library/Stripe/Charge.php
Executable file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace 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 array An array 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 array|string|null $options
|
||||
*
|
||||
* @return Charge The saved charge.
|
||||
*/
|
||||
public function save($options = null)
|
||||
{
|
||||
return $this->_save($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $options
|
||||
*
|
||||
* @return Charge The refunded charge.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $options
|
||||
*
|
||||
* @return Charge The captured charge.
|
||||
*/
|
||||
public function capture($params = null, $options = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/capture';
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $options);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $options
|
||||
*
|
||||
* @return array The updated dispute.
|
||||
*/
|
||||
public function updateDispute($params = null, $options = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/dispute';
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $options);
|
||||
$this->refreshFrom(array('dispute' => $response), $opts, true);
|
||||
return $this->dispute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $options
|
||||
*
|
||||
* @return Charge The updated charge.
|
||||
*/
|
||||
public function closeDispute($options = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/dispute/close';
|
||||
list($response, $opts) = $this->_request('post', $url, null, $options);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Charge The updated charge.
|
||||
*/
|
||||
public function markAsFraudulent($opts = null)
|
||||
{
|
||||
$params = array('fraud_details' => array('user_report' => 'fraudulent'));
|
||||
$url = $this->instanceUrl();
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $opts);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Charge The updated charge.
|
||||
*/
|
||||
public function markAsSafe($opts = null)
|
||||
{
|
||||
$params = array('fraud_details' => array('user_report' => 'safe'));
|
||||
$url = $this->instanceUrl();
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $opts);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
56
include/library/Stripe/Collection.php
Executable file
56
include/library/Stripe/Collection.php
Executable file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Collection extends ApiResource
|
||||
{
|
||||
public function all($params = null, $opts = null)
|
||||
{
|
||||
list($url, $params) = $this->extractPathAndUpdateParams($params);
|
||||
|
||||
list($response, $opts) = $this->_request('get', $url, $params, $opts);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
public function create($params = null, $opts = null)
|
||||
{
|
||||
list($url, $params) = $this->extractPathAndUpdateParams($params);
|
||||
|
||||
list($response, $opts) = $this->_request('post', $url, $params, $opts);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
public function retrieve($id, $params = null, $opts = null)
|
||||
{
|
||||
list($url, $params) = $this->extractPathAndUpdateParams($params);
|
||||
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$extn = urlencode($id);
|
||||
list($response, $opts) = $this->_request(
|
||||
'get',
|
||||
"$url/$extn",
|
||||
$params,
|
||||
$opts
|
||||
);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
private function extractPathAndUpdateParams($params)
|
||||
{
|
||||
$url = parse_url($this->url);
|
||||
if (!isset($url['path'])) {
|
||||
throw new Error\Api("Could not parse list url into parts: $url");
|
||||
}
|
||||
|
||||
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();
|
||||
parse_str($url['query'], $query);
|
||||
// PHP 5.2 doesn't support the ?: operator :(
|
||||
$params = array_merge($params ? $params : array(), $query);
|
||||
}
|
||||
|
||||
return array($url['path'], $params);
|
||||
}
|
||||
}
|
||||
60
include/library/Stripe/Coupon.php
Executable file
60
include/library/Stripe/Coupon.php
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace 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 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 Coupon[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
158
include/library/Stripe/Customer.php
Executable file
158
include/library/Stripe/Customer.php
Executable file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
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)
|
||||
{
|
||||
return self::_retrieve($id, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return array An array 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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return InvoiceItem The resulting invoice item.
|
||||
*/
|
||||
public function addInvoiceItem($params = null)
|
||||
{
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
$params['customer'] = $this->id;
|
||||
$ii = InvoiceItem::create($params, $this->_opts);
|
||||
return $ii;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array An array of the customer's Invoices.
|
||||
*/
|
||||
public function invoices($params = null)
|
||||
{
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
$params['customer'] = $this->id;
|
||||
$invoices = Invoice::all($params, $this->_opts);
|
||||
return $invoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array An array of the customer's InvoiceItems.
|
||||
*/
|
||||
public function invoiceItems($params = null)
|
||||
{
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
$params['customer'] = $this->id;
|
||||
$iis = InvoiceItem::all($params, $this->_opts);
|
||||
return $iis;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array An array of the customer's Charges.
|
||||
*/
|
||||
public function charges($params = null)
|
||||
{
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
$params['customer'] = $this->id;
|
||||
$charges = Charge::all($params, $this->_opts);
|
||||
return $charges;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return Subscription The updated subscription.
|
||||
*/
|
||||
public function updateSubscription($params = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/subscription';
|
||||
list($response, $opts) = $this->_request('post', $url, $params);
|
||||
$this->refreshFrom(array('subscription' => $response), $opts, true);
|
||||
return $this->subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return Subscription The cancelled subscription.
|
||||
*/
|
||||
public function cancelSubscription($params = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/subscription';
|
||||
list($response, $opts) = $this->_request('delete', $url, $params);
|
||||
$this->refreshFrom(array('subscription' => $response), $opts, true);
|
||||
return $this->subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return Customer The updated customer.
|
||||
*/
|
||||
public function deleteDiscount()
|
||||
{
|
||||
$url = $this->instanceUrl() . '/discount';
|
||||
list($response, $opts) = $this->_request('delete', $url);
|
||||
$this->refreshFrom(array('discount' => null), $opts, true);
|
||||
}
|
||||
}
|
||||
7
include/library/Stripe/Error/Api.php
Executable file
7
include/library/Stripe/Error/Api.php
Executable file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class Api extends Base
|
||||
{
|
||||
}
|
||||
7
include/library/Stripe/Error/ApiConnection.php
Executable file
7
include/library/Stripe/Error/ApiConnection.php
Executable file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class ApiConnection extends Base
|
||||
{
|
||||
}
|
||||
7
include/library/Stripe/Error/Authentication.php
Executable file
7
include/library/Stripe/Error/Authentication.php
Executable file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class Authentication extends Base
|
||||
{
|
||||
}
|
||||
35
include/library/Stripe/Error/Base.php
Executable file
35
include/library/Stripe/Error/Base.php
Executable file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
use Exception;
|
||||
|
||||
abstract class Base extends Exception
|
||||
{
|
||||
public function __construct(
|
||||
$message,
|
||||
$httpStatus = null,
|
||||
$httpBody = null,
|
||||
$jsonBody = null
|
||||
) {
|
||||
parent::__construct($message);
|
||||
$this->httpStatus = $httpStatus;
|
||||
$this->httpBody = $httpBody;
|
||||
$this->jsonBody = $jsonBody;
|
||||
}
|
||||
|
||||
public function getHttpStatus()
|
||||
{
|
||||
return $this->httpStatus;
|
||||
}
|
||||
|
||||
public function getHttpBody()
|
||||
{
|
||||
return $this->httpBody;
|
||||
}
|
||||
|
||||
public function getJsonBody()
|
||||
{
|
||||
return $this->jsonBody;
|
||||
}
|
||||
}
|
||||
19
include/library/Stripe/Error/Card.php
Executable file
19
include/library/Stripe/Error/Card.php
Executable file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class Card extends Base
|
||||
{
|
||||
public function __construct(
|
||||
$message,
|
||||
$param,
|
||||
$code,
|
||||
$httpStatus,
|
||||
$httpBody,
|
||||
$jsonBody
|
||||
) {
|
||||
parent::__construct($message, $httpStatus, $httpBody, $jsonBody);
|
||||
$this->param = $param;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
||||
17
include/library/Stripe/Error/InvalidRequest.php
Executable file
17
include/library/Stripe/Error/InvalidRequest.php
Executable file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class InvalidRequest extends Base
|
||||
{
|
||||
public function __construct(
|
||||
$message,
|
||||
$param,
|
||||
$httpStatus = null,
|
||||
$httpBody = null,
|
||||
$jsonBody = null
|
||||
) {
|
||||
parent::__construct($message, $httpStatus, $httpBody, $jsonBody);
|
||||
$this->param = $param;
|
||||
}
|
||||
}
|
||||
16
include/library/Stripe/Error/RateLimit.php
Executable file
16
include/library/Stripe/Error/RateLimit.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Error;
|
||||
|
||||
class RateLimit extends InvalidRequest
|
||||
{
|
||||
public function __construct(
|
||||
$message,
|
||||
$param,
|
||||
$httpStatus = null,
|
||||
$httpBody = null,
|
||||
$jsonBody = null
|
||||
) {
|
||||
parent::__construct($message, $httpStatus, $httpBody, $jsonBody);
|
||||
}
|
||||
}
|
||||
28
include/library/Stripe/Event.php
Executable file
28
include/library/Stripe/Event.php
Executable file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Event extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @param string $id The ID of the event to retrieve.
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Event
|
||||
*/
|
||||
public static function retrieve($id, $opts = null)
|
||||
{
|
||||
return self::_retrieve($id, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Event[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
49
include/library/Stripe/FileUpload.php
Executable file
49
include/library/Stripe/FileUpload.php
Executable file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class FileUpload extends ApiResource
|
||||
{
|
||||
public static function baseUrl()
|
||||
{
|
||||
return Stripe::$apiUploadBase;
|
||||
}
|
||||
|
||||
public static function className()
|
||||
{
|
||||
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 FileUpload[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
73
include/library/Stripe/Invoice.php
Executable file
73
include/library/Stripe/Invoice.php
Executable file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace 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 Invoice[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Invoice The upcoming invoice.
|
||||
*/
|
||||
public static function upcoming($params = null, $opts = null)
|
||||
{
|
||||
$url = static::classUrl() . '/upcoming';
|
||||
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
|
||||
return Util\Util::convertToStripeObject($response, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/pay';
|
||||
list($response, $opts) = $this->_request('post', $url, null, $opts);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
60
include/library/Stripe/InvoiceItem.php
Executable file
60
include/library/Stripe/InvoiceItem.php
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace 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 InvoiceItem[]
|
||||
*/
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
247
include/library/Stripe/Object.php
Executable file
247
include/library/Stripe/Object.php
Executable file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
use ArrayAccess;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Object implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @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;
|
||||
|
||||
public static function init()
|
||||
{
|
||||
self::$permanentAttributes = new Util\Set(array('_opts', 'id'));
|
||||
self::$nestedUpdatableAttributes = new Util\Set(array('metadata'));
|
||||
}
|
||||
|
||||
protected $_opts;
|
||||
protected $_values;
|
||||
protected $_unsavedValues;
|
||||
protected $_transientValues;
|
||||
protected $_retrieveOptions;
|
||||
|
||||
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) && 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)
|
||||
{
|
||||
if (array_key_exists($k, $this->_values)) {
|
||||
return $this->_values[$k];
|
||||
} else if ($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 null;
|
||||
} else {
|
||||
$class = get_class($this);
|
||||
error_log("Stripe Notice: Undefined property of $class instance: $k");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 Object 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 $opts
|
||||
* @param boolean $partial Defaults to false.
|
||||
*/
|
||||
public function refreshFrom($values, $opts, $partial = false)
|
||||
{
|
||||
$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) && $this->$property instanceof Object) {
|
||||
$params[$property] = $this->$property->serializeParameters();
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object::init();
|
||||
60
include/library/Stripe/Plan.php
Executable file
60
include/library/Stripe/Plan.php
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
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 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 Plan[]
|
||||
*/
|
||||
public static function all($params = null, $opts = null)
|
||||
{
|
||||
return self::_all($params, $opts);
|
||||
}
|
||||
}
|
||||
75
include/library/Stripe/Recipient.php
Executable file
75
include/library/Stripe/Recipient.php
Executable file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
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 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 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return array An array of the recipient's Transfers.
|
||||
*/
|
||||
public function transfers($params = null)
|
||||
{
|
||||
if ($params === null) {
|
||||
$params = array();
|
||||
}
|
||||
$params['recipient'] = $this->id;
|
||||
$transfers = Transfer::all($params, $this->_opts);
|
||||
return $transfers;
|
||||
}
|
||||
}
|
||||
39
include/library/Stripe/Refund.php
Executable file
39
include/library/Stripe/Refund.php
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Refund extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The API URL for this Stripe refund.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
$id = $this['id'];
|
||||
$charge = $this['charge'];
|
||||
if (!$id) {
|
||||
throw new Error\InvalidRequest(
|
||||
"Could not determine which URL to request: " .
|
||||
"class instance has invalid ID: $id",
|
||||
null
|
||||
);
|
||||
}
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$charge = ApiRequestor::utf8($charge);
|
||||
|
||||
$base = Charge::classUrl();
|
||||
$chargeExtn = urlencode($charge);
|
||||
$extn = urlencode($id);
|
||||
return "$base/$chargeExtn/refunds/$extn";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Refund The saved refund.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
31
include/library/Stripe/SingletonApiResource.php
Executable file
31
include/library/Stripe/SingletonApiResource.php
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
abstract class SingletonApiResource extends ApiResource
|
||||
{
|
||||
protected static function _singletonRetrieve($options = null)
|
||||
{
|
||||
$opts = Util\RequestOptions::parse($options);
|
||||
$instance = new static(null, $opts);
|
||||
$instance->refresh();
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The endpoint associated with this singleton class.
|
||||
*/
|
||||
public static function classUrl()
|
||||
{
|
||||
$base = static::className();
|
||||
return "/v1/${base}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The endpoint associated with this singleton API resource.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
return static::classUrl();
|
||||
}
|
||||
}
|
||||
74
include/library/Stripe/Stripe.php
Executable file
74
include/library/Stripe/Stripe.php
Executable file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Stripe
|
||||
{
|
||||
// @var string The Stripe API key to be used for requests.
|
||||
public static $apiKey;
|
||||
|
||||
// @var string The base URL for the Stripe API.
|
||||
public static $apiBase = 'https://api.stripe.com';
|
||||
|
||||
// @var string The base URL for the Stripe API uploads endpoint.
|
||||
public static $apiUploadBase = 'https://uploads.stripe.com';
|
||||
|
||||
// @var string|null The version of the Stripe API to use for requests.
|
||||
public static $apiVersion = null;
|
||||
|
||||
// @var boolean Defaults to true.
|
||||
public static $verifySslCerts = true;
|
||||
|
||||
const VERSION = '2.1.1';
|
||||
|
||||
/**
|
||||
* @return string The API key used for requests.
|
||||
*/
|
||||
public static function getApiKey()
|
||||
{
|
||||
return self::$apiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the API key to be used for requests.
|
||||
*
|
||||
* @param string $apiKey
|
||||
*/
|
||||
public static function setApiKey($apiKey)
|
||||
{
|
||||
self::$apiKey = $apiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The API version used for requests. null if we're using the
|
||||
* latest version.
|
||||
*/
|
||||
public static function getApiVersion()
|
||||
{
|
||||
return self::$apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $apiVersion The API version to use for requests.
|
||||
*/
|
||||
public static function setApiVersion($apiVersion)
|
||||
{
|
||||
self::$apiVersion = $apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public static function getVerifySslCerts()
|
||||
{
|
||||
return self::$verifySslCerts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $verify
|
||||
*/
|
||||
public static function setVerifySslCerts($verify)
|
||||
{
|
||||
self::$verifySslCerts = $verify;
|
||||
}
|
||||
}
|
||||
59
include/library/Stripe/Subscription.php
Executable file
59
include/library/Stripe/Subscription.php
Executable file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class Subscription extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The API URL for this Stripe subscription.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
$id = $this['id'];
|
||||
$customer = $this['customer'];
|
||||
if (!$id) {
|
||||
throw new Error\InvalidRequest(
|
||||
"Could not determine which URL to request: " .
|
||||
"class instance has invalid ID: $id",
|
||||
null
|
||||
);
|
||||
}
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$customer = ApiRequestor::utf8($customer);
|
||||
|
||||
$base = Customer::classUrl();
|
||||
$customerExtn = urlencode($customer);
|
||||
$extn = urlencode($id);
|
||||
return "$base/$customerExtn/subscriptions/$extn";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
*
|
||||
* @return Subscription The deleted subscription.
|
||||
*/
|
||||
public function cancel($params = null, $opts = null)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
public function deleteDiscount()
|
||||
{
|
||||
$url = $this->instanceUrl() . '/discount';
|
||||
list($response, $opts) = $this->_request('delete', $url);
|
||||
$this->refreshFrom(array('discount' => null), $opts, true);
|
||||
}
|
||||
}
|
||||
28
include/library/Stripe/Token.php
Executable file
28
include/library/Stripe/Token.php
Executable file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
71
include/library/Stripe/Transfer.php
Executable file
71
include/library/Stripe/Transfer.php
Executable file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $params
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Transfer[]
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransferReversal The created transfer reversal.
|
||||
*/
|
||||
public function reverse($params = null, $opts = null)
|
||||
{
|
||||
$url = $this->instanceUrl() . '/reversals';
|
||||
list($response, $opts) = $this->request('post', $url, $params, $options);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Transfer The canceled transfer.
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
$url = $this->instanceUrl() . '/cancel';
|
||||
list($response, $opts) = $this->_request('post', $url);
|
||||
$this->refreshFrom($response, $opts);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return Transfer The saved transfer.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
39
include/library/Stripe/TransferReversal.php
Executable file
39
include/library/Stripe/TransferReversal.php
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe;
|
||||
|
||||
class TransferReversal extends ApiResource
|
||||
{
|
||||
/**
|
||||
* @return string The API URL for this Stripe transfer reversal.
|
||||
*/
|
||||
public function instanceUrl()
|
||||
{
|
||||
$id = $this['id'];
|
||||
$transfer = $this['transfer'];
|
||||
if (!$id) {
|
||||
throw new Error\InvalidRequest(
|
||||
"Could not determine which URL to request: " .
|
||||
"class instance has invalid ID: $id",
|
||||
null
|
||||
);
|
||||
}
|
||||
$id = ApiRequestor::utf8($id);
|
||||
$transfer = ApiRequestor::utf8($transfer);
|
||||
|
||||
$base = Transfer::classUrl();
|
||||
$transferExtn = urlencode($transfer);
|
||||
$extn = urlencode($id);
|
||||
return "$base/$transferExtn/reversals/$extn";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|null $opts
|
||||
*
|
||||
* @return TransferReversal The saved reversal.
|
||||
*/
|
||||
public function save($opts = null)
|
||||
{
|
||||
return $this->_save($opts);
|
||||
}
|
||||
}
|
||||
79
include/library/Stripe/Util/RequestOptions.php
Executable file
79
include/library/Stripe/Util/RequestOptions.php
Executable file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Util;
|
||||
|
||||
use Stripe\Error;
|
||||
|
||||
class RequestOptions
|
||||
{
|
||||
public $headers;
|
||||
public $apiKey;
|
||||
|
||||
public function __construct($key = null, $headers = array())
|
||||
{
|
||||
$this->apiKey = $key;
|
||||
$this->headers = $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks an options array and merges it into the existing RequestOptions
|
||||
* object.
|
||||
* @param array|string|null $options a key => value array
|
||||
*
|
||||
* @return RequestOptions
|
||||
*/
|
||||
public function merge($options)
|
||||
{
|
||||
$other_options = self::parse($options);
|
||||
if ($other_options->apiKey === null) {
|
||||
$other_options->apiKey = $this->apiKey;
|
||||
}
|
||||
$other_options->headers = array_merge($this->headers, $other_options->headers);
|
||||
return $other_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks an options array into an RequestOptions object
|
||||
* @param array|string|null $options a key => value array
|
||||
*
|
||||
* @return RequestOptions
|
||||
*/
|
||||
public static function parse($options)
|
||||
{
|
||||
if ($options instanceof self) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (is_null($options)) {
|
||||
return new RequestOptions(null, array());
|
||||
}
|
||||
|
||||
if (is_string($options)) {
|
||||
return new RequestOptions($options, array());
|
||||
}
|
||||
|
||||
if (is_array($options)) {
|
||||
$headers = array();
|
||||
$key = null;
|
||||
if (array_key_exists('api_key', $options)) {
|
||||
$key = $options['api_key'];
|
||||
}
|
||||
if (array_key_exists('idempotency_key', $options)) {
|
||||
$headers['Idempotency-Key'] = $options['idempotency_key'];
|
||||
}
|
||||
if (array_key_exists('stripe_account', $options)) {
|
||||
$headers['Stripe-Account'] = $options['stripe_account'];
|
||||
}
|
||||
if (array_key_exists('stripe_version', $options)) {
|
||||
$headers['Stripe-Version'] = $options['stripe_version'];
|
||||
}
|
||||
return new RequestOptions($key, $headers);
|
||||
}
|
||||
|
||||
$message = 'The second argument to Stripe API method calls is an '
|
||||
. 'optional per-request apiKey, which must be a string, or '
|
||||
. 'per-request options, which must be an array. (HINT: you can set '
|
||||
. 'a global apiKey by "Stripe::setApiKey(<apiKey>)")';
|
||||
throw new Error\Api($message);
|
||||
}
|
||||
}
|
||||
44
include/library/Stripe/Util/Set.php
Executable file
44
include/library/Stripe/Util/Set.php
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Util;
|
||||
|
||||
use IteratorAggregate;
|
||||
use ArrayIterator;
|
||||
|
||||
class Set implements IteratorAggregate
|
||||
{
|
||||
private $_elts;
|
||||
|
||||
public function __construct($members = array())
|
||||
{
|
||||
$this->_elts = array();
|
||||
foreach ($members as $item) {
|
||||
$this->_elts[$item] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function includes($elt)
|
||||
{
|
||||
return isset($this->_elts[$elt]);
|
||||
}
|
||||
|
||||
public function add($elt)
|
||||
{
|
||||
$this->_elts[$elt] = true;
|
||||
}
|
||||
|
||||
public function discard($elt)
|
||||
{
|
||||
unset($this->_elts[$elt]);
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return array_keys($this->_elts);
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->toArray());
|
||||
}
|
||||
}
|
||||
102
include/library/Stripe/Util/Util.php
Executable file
102
include/library/Stripe/Util/Util.php
Executable file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Stripe\Util;
|
||||
|
||||
use Stripe\Object;
|
||||
|
||||
abstract class Util
|
||||
{
|
||||
/**
|
||||
* Whether the provided array (or other) is a list rather than a dictionary.
|
||||
*
|
||||
* @param array|mixed $array
|
||||
* @return boolean True if the given object is a list.
|
||||
*/
|
||||
public static function isList($array)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: generally incorrect, but it's correct given Stripe's response
|
||||
foreach (array_keys($array) as $k) {
|
||||
if (!is_numeric($k)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively converts the PHP Stripe object to an array.
|
||||
*
|
||||
* @param array $values The PHP Stripe object to convert.
|
||||
* @return array
|
||||
*/
|
||||
public static function convertStripeObjectToArray($values)
|
||||
{
|
||||
$results = array();
|
||||
foreach ($values as $k => $v) {
|
||||
// FIXME: this is an encapsulation violation
|
||||
if ($k[0] == '_') {
|
||||
continue;
|
||||
}
|
||||
if ($v instanceof Object) {
|
||||
$results[$k] = $v->__toArray(true);
|
||||
} elseif (is_array($v)) {
|
||||
$results[$k] = self::convertStripeObjectToArray($v);
|
||||
} else {
|
||||
$results[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a response from the Stripe API to the corresponding PHP object.
|
||||
*
|
||||
* @param array $resp The response from the Stripe API.
|
||||
* @param array $opts
|
||||
* @return Object|array
|
||||
*/
|
||||
public static function convertToStripeObject($resp, $opts)
|
||||
{
|
||||
$types = array(
|
||||
'account' => 'Stripe\\Account',
|
||||
'card' => 'Stripe\\Card',
|
||||
'charge' => 'Stripe\\Charge',
|
||||
'coupon' => 'Stripe\\Coupon',
|
||||
'customer' => 'Stripe\\Customer',
|
||||
'list' => 'Stripe\\Collection',
|
||||
'invoice' => 'Stripe\\Invoice',
|
||||
'invoiceitem' => 'Stripe\\InvoiceItem',
|
||||
'event' => 'Stripe\\Event',
|
||||
'file' => 'Stripe\\FileUpload',
|
||||
'token' => 'Stripe\\Token',
|
||||
'transfer' => 'Stripe\\Transfer',
|
||||
'plan' => 'Stripe\\Plan',
|
||||
'recipient' => 'Stripe\\Recipient',
|
||||
'refund' => 'Stripe\\Refund',
|
||||
'subscription' => 'Stripe\\Subscription',
|
||||
'fee_refund' => 'Stripe\\ApplicationFeeRefund',
|
||||
'bitcoin_receiver' => 'Stripe\\BitcoinReceiver',
|
||||
'bitcoin_transaction' => 'Stripe\\BitcoinTransaction',
|
||||
);
|
||||
if (self::isList($resp)) {
|
||||
$mapped = array();
|
||||
foreach ($resp as $i) {
|
||||
array_push($mapped, self::convertToStripeObject($i, $opts));
|
||||
}
|
||||
return $mapped;
|
||||
} elseif (is_array($resp)) {
|
||||
if (isset($resp['object']) && is_string($resp['object']) && isset($types[$resp['object']])) {
|
||||
$class = $types[$resp['object']];
|
||||
} else {
|
||||
$class = 'Stripe\\Object';
|
||||
}
|
||||
return $class::constructFrom($resp, $opts);
|
||||
} else {
|
||||
return $resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,34 +3,33 @@ console.log('App.tokenizeCard');
|
||||
var processor = ( App.config.processor && App.config.processor.type ) ? App.config.processor.type : false;
|
||||
console.debug('Processor: ', processor);
|
||||
|
||||
var legacy_card = {
|
||||
card_number: card.number,
|
||||
expiration_month: card.expiration_month,
|
||||
expiration_year: card.expiration_year,
|
||||
security_code: null
|
||||
};
|
||||
|
||||
if (App.isPhoneGap) {
|
||||
//card = legacy_card;
|
||||
}
|
||||
|
||||
switch(processor) {
|
||||
case 'stripe':
|
||||
App.tokenizeCard_stripe( legacy_card, complete );
|
||||
App.tokenizeCard_stripe( card, complete );
|
||||
break;
|
||||
case 'balanced':
|
||||
App.tokenizeCard_balanced( card, complete );
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
App.alert('There was an error communicating with our payment processor.');
|
||||
console.log( 'Processor error::', App.config.processor );
|
||||
break;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
App.tokenizeCard_stripe = function( card, complete ) {
|
||||
var res = { status: false };
|
||||
var card = { number: card.card_number, exp_month: card.expiration_month, exp_year: card.expiration_year };
|
||||
var res = {
|
||||
status: false
|
||||
};
|
||||
|
||||
var card = {
|
||||
number: card.number,
|
||||
exp_month: card.expiration_month,
|
||||
exp_year: card.expiration_year
|
||||
};
|
||||
|
||||
Stripe.card.createToken( card , function( status, response ){
|
||||
console.debug('Recieved response from stripe: ', status, response);
|
||||
if ( response.error ) {
|
||||
switch( response.error.code ){
|
||||
case 'incorrect_number':
|
||||
@ -70,7 +69,7 @@ App.tokenizeCard_stripe = function( card, complete ) {
|
||||
id : response.card.id,
|
||||
uri: response.id,
|
||||
lastfour: response.card.last4,
|
||||
card_type: response.card.type,
|
||||
card_type: response.card.brand.toLowerCase(),
|
||||
month: response.card.exp_month,
|
||||
year: response.card.exp_year,
|
||||
status : true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user