v7‰PNG IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ±üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0AºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT braintree.php 0000644 00000120033 15210163246 0007227 0 ustar 00 getPluginUrl(self::ACTION_CC)); $action->cc_id = $invoice->getSecureId($this->getId()); $result->setAction($action); } function getSupportedCurrencies() { return array_keys(Am_Currency::getFullList()); } protected function ccActionValidateSetInvoice(Am_Mvc_Request $request, array $invokeArgs) { $invoiceId = $request->getFiltered('cc_id'); if (!$invoiceId) throw new Am_Exception_InputError("invoice_id is empty - seems you have followed wrong url, please return back to continue"); $invoice = $this->getDi()->invoiceTable->findBySecureId($invoiceId, $this->getId()); if (!$invoice) throw new Am_Exception_InputError('You have used wrong link for payment page, please return back and try again'); if ($invoice->isCompleted()) throw new Am_Exception_InputError(sprintf(___('Payment is already processed, please go to %sMembership page%s'), "", "")); if ($invoice->paysys_id != $this->getId()) throw new Am_Exception_InputError("You have used wrong link for payment page, please return back and try again"); if ($invoice->tm_added < sqlTime('-30 days')) throw new Am_Exception_InputError("Invoice expired - you cannot open invoice after 30 days elapsed"); $this->invoice = $invoice; // set for reference } public function getRecurringType() { return self::REPORTS_CRONREBILL; } function createForm($actionName) { return new Am_Form_CreditCard_Braintree($this, $actionName); } function createController(Am_Mvc_Request $request, Am_Mvc_Response $response, array $invokeArgs) { return new Am_Mvc_Controller_CreditCard_Braintree($request, $response, $invokeArgs); } public function init() { parent::init(); if ($this->isConfigured()) { require_once('lib/Braintree.php'); \Braintree\Configuration::merchantId($this->getConfig('merchant_id')); \Braintree\Configuration::privateKey($this->getConfig('private_key')); \Braintree\Configuration::publicKey($this->getConfig('public_key')); \Braintree\Configuration::environment($this->getConfig('sandbox') ? 'sandbox' : 'production'); if ($this->getConfig('multicurrency')) $this->getDi()->billingPlanTable->customFields() ->add(new Am_CustomFieldText('braintree_merchant_account_id', "BrainTree Merchant Account ID", "please set this up if you sell products in different currencies")); } } public function getConfig($key = null, $default = null) { if (in_array($key, array('merchant_id', 'public_key', 'private_key', 'merchant_account_id'))) return parent::getConfig(($this->getConfig('sandbox') ? 'test_' : '') . $key, $default); else return parent::getConfig($key, $default); } public function isConfigured() { return $this->getConfig('merchant_id') && $this->getConfig('public_key') && $this->getConfig('private_key'); } public function _initSetupForm(Am_Form_Setup $form) { $form->addText('merchant_id')->setLabel('Your BrainTree Merchant ID'); $form->addText('public_key')->setLabel('Your BrainTree Public Key'); $form->addText('private_key')->setLabel('Your BrainTree Private Key'); $form->addText('merchant_account_id')->setLabel('Your BrainTree Merchant Account ID'); $form->addText('test_merchant_id')->setLabel('Your BrainTree SANDBOX Merchant ID'); $form->addText('test_public_key')->setLabel('Your BrainTree SANDBOX Public Key'); $form->addText('test_private_key')->setLabel('Your BrainTree SANDBOX Private Key'); $form->addText('test_merchant_account_id')->setLabel('Your BrainTree SANDBOX Merchant Account ID'); $form->addAdvCheckbox('sandbox')->setLabel('Sandbox testing'); $form->addAdvCheckbox('hosted')->setLabel( "Use 'Hosted Fields'\n " . "SAQ A compliant solution"); $form->addAdvCheckbox('multicurrency')->setLabel("Use different merchant account ID's\n" . 'if you sell products in different currencies you need to setup merchant account ID for each product'); } // We do not store CC info. public function storesCcInfo() { return false; } public function getUpdateCcLink($user) { try { if (!($bid = $user->data()->get(Am_Paysystem_Braintree::CUSTOMER_ID))) return false; if (!($bt_member = \Braintree\Customer::find($bid))) { $this->getDi()->errorLogTable->log('Wrong customer braintree id'); return false; } if (!($token = $bt_member->creditCards[0]->token)) { $this->getDi()->errorLogTable->log('Empty token for credit card'); return false; } return $this->getPluginUrl('update'); } catch (Exception $e) { $this->getDi()->errorLogTable->logException($e); } } function doBill(\Invoice $invoice, $doFirst, \CcRecord $cc = null) { $this->invoice = $invoice; $this->cc = $cc; $result = new Am_Paysystem_Result(); if ($this->getConfig('hosted')) $this->_doBillHosted($invoice, $doFirst, $cc, $result); else $this->_doBill($invoice, $doFirst, $cc, $result); return $result; } public function _doBill(Invoice $invoice, $doFirst, CcRecord $cc, Am_Paysystem_Result $result) { if ($doFirst) { try { // We was redirected from Braintree so need to get result; $res = \Braintree\TransparentRedirect::confirm($_SERVER['QUERY_STRING']); if ($res instanceof \Braintree\Result\Error) { $result->setFailed($res->message); return; } else { $invoice->getUser()->data()->set(self::CUSTOMER_ID, $res->customer->id)->update(); } } catch (\Braintree\Exception\NotFound $e) { } catch (Exception $e) { $result->setFailed($e->getMessage()); return; } } if (!($customer_id = $invoice->getUser()->data()->get(self::CUSTOMER_ID))) { $result->setFailed('Empty customer ID. Please update CC info'); return; } // Now attempt to submit transaction if required; if ($doFirst && !(float) $invoice->first_total) { $transaction = new Am_Paysystem_Transaction_Free($this); $transaction->setInvoice($invoice); $transaction->process(); $result->setSuccess($transaction); } else { $transaction = new Am_Paysystem_Transaction_CreditCard_Braintree_Sale($this, $invoice, null, $doFirst); $transaction->run($result); } } public function _doBillHosted(Invoice $invoice, $doFirst, CcRecord $cc, Am_Paysystem_Result $result) { // Now attempt to submit transaction if required; if ($doFirst) { if (!(float) $invoice->first_total) { // Create Customer here; $transaction = new Am_Paysystem_Transaction_Free($this); $transaction->setInvoice($invoice); $transaction->process(); $result->setSuccess($transaction); } else { $transaction = new Am_Paysystem_Transaction_CreditCard_Braintree_SaleHosted($this, $invoice, null, $doFirst); $transaction->setCC($cc); $transaction->run($result); } } else $this->_doBill($invoice, $doFirst, $cc, $result); } public function processRefund(InvoicePayment $payment, Am_Paysystem_Result $result, $amount) { $trans = new Am_Paysystem_Transaction_CreditCard_Braintree_Refund($this, $payment->getInvoice(), null, null, $payment); $trans->run($result); if (!$result->isSuccess()) { $result->setErrorMessages(null); $trans = new Am_Paysystem_Transaction_CreditCard_Braintree_Void($this, $payment->getInvoice(), null, null, $payment); $trans->run($result); } return $result; } } class Am_Form_CreditCard_Braintree extends Am_Form_CreditCard { public function __construct(Am_Paysystem_CreditCard $plugin, $formType = self::PAYFORM) { $this->plugin = $plugin; $this->formType = $formType; $this->payButtons = array( self::PAYFORM => ___('Subscribe And Pay'), self::ADMIN_UPDATE => ___('Update Credit Card Info'), self::USER_UPDATE => ___('Update Credit Card Info'), self::ADMIN_INSERT => ___('Update Credit Card Info'), ); Am_Form::__construct('cc', array('action' => \Braintree\TransparentRedirect::url())); } public function init() { Am_Form::init(); if ($this->plugin->getConfig('hosted')) $this->createFormHosted(); else $this->createFormRegular(); // if free trial set _TPL_CC_INFO_SUBMIT_BUT2 $buttons = $this->addGroup(); $buttons->addSubmit('_cc_', array('value' => ' ' . $this->payButtons[$this->formType] . ' ')); $this->plugin->onFormInit($this); } function createFormRegular() { if ($this->formType == self::PAYFORM) $fn = 'customer__'; else $fn = ''; $name = $this->addGroup()->setLabel(___("Cardholder Name\n" . 'cardholder first and last name, exactly as on the card')); $name->addRule('required', ___('Please enter credit card holder name')); $name->addText($fn . 'credit_card__cardholder_name', array('size' => 30)) ->addRule('required', ___('Please enter cardholder name exactly as on card')) ->addRule('regex', ___('Please enter credit card holder name'), '|^[a-zA-Z_\' -]+$|'); $this->addText($fn . 'credit_card__number', array('autocomplete' => 'off', 'size' => 22, 'maxlength' => 22)) ->setLabel(___('Credit Card Number'), ___('for example: 1111222233334444')) ->addRule('required', ___('Please enter Credit Card Number')) ->addRule('regex', ___('Invalid Credit Card Number'), '/^[0-9 -]+$/') ->addRule('callback2', 'Invalid CC#', array($this->plugin, 'validateCreditCardNumber')); $gr = $this->addGroup() ->setLabel(___("Card Expire\n" . 'Select card expiration date - month and year')); $gr->addSelect($fn . 'credit_card__expiration_month') ->loadOptions($this->getMonthOptions()); $gr->addSelect($fn . 'credit_card__expiration_year') ->loadOptions($this->getYearOptions()); $this->addPassword($fn . 'credit_card__cvv', array('autocomplete' => 'off', 'size' => 4, 'maxlength' => 4)) ->setLabel(___("Credit Card Code\n" . 'The "Card Code" is a three- or four-digit security code that ' . 'is printed on the back of credit cards in the card\'s ' . 'signature panel (or on the front for American Express cards).')) ->addRule('required', ___('Please enter Credit Card Code')) ->addRule('regex', ___('Please enter Credit Card Code'), '/^\s*\d{3,4}\s*$/'); $fieldSet = $this->addFieldset(___('Address Info')) ->setLabel(___("Address Info\n" . '(must match your credit card statement delivery address)')); $bname = $fieldSet->addGroup()->setLabel(___("Billing Name\n" . 'Billing Address First and Last name')); $bname->addRule('required', ___('Please enter billing name')); $bname->addText($fn . 'credit_card__billing_address__first_name', array('size' => 15)) ->addRule('required', ___('Please enter first name')) ->addRule('regex', ___('Please enter first name'), '|^[a-zA-Z_\' -]+$|'); $bname->addText($fn . 'credit_card__billing_address__last_name', array('size' => 15)) ->addRule('required', ___('Please enter last name')) ->addRule('regex', ___('Please enter last name'), '|^[a-zA-Z_\' -]+$|'); $fieldSet->addText($fn . 'credit_card__billing_address__street_address') ->setLabel(___('Street Address')) ->addRule('required', ___('Please enter Street Address')); $fieldSet->addText($fn . 'credit_card__billing_address__extended_address') ->setLabel(___('Street Address (Second Line)')); $fieldSet->addText($fn . 'credit_card__billing_address__locality') ->setLabel(___('City')); $fieldSet->addText($fn . 'credit_card__billing_address__postal_code') ->setLabel(___('Zipcode')) ->addRule('required', ___('Please enter ZIP code')); $country = $fieldSet->addSelect($fn . 'credit_card__billing_address__country_name')->setLabel(___('Country')) ->setId('f_cc_country') ->loadOptions(Am_Di::getInstance()->countryTable->getOptions(true)); $country->addRule('required', ___('Please enter Country')); $group = $fieldSet->addGroup()->setLabel(___('State')); $group->addRule('required', ___('Please enter State')); $stateSelect = $group->addSelect($fn . 'credit_card__billing_address__region') ->setId('f_cc_state') ->loadOptions($stateOptions = Am_Di::getInstance()->stateTable->getOptions(@$_REQUEST['cc_country'], true)); $stateText = $group->addText($fn . 'credit_card__billing_address__region')->setId('t_cc_state'); $disableObj = $stateOptions ? $stateText : $stateSelect; $disableObj->setAttribute('disabled', 'disabled')->setAttribute('style', 'display: none'); } function createFormHosted() { if ($this->formType == self::PAYFORM) $fn = 'customer__'; else $fn = ''; $this->addHTML() ->setHTML("
") ->setLabel(___('Credit Card Number'), ___('for example: 1111222233334444')); $this->addHTML()->setHTML("") ->setLabel(___("Card Expire\n" . 'Card expiration date - month and year')); $this->addHTML()->setHTML("") ->setLabel(___("Credit Card Code\n" . 'The "Card Code" is a three- or four-digit security code that ' . 'is printed on the back of credit cards in the card\'s ' . 'signature panel (or on the front for American Express cards).')); $this->addHidden('nonce', array('id' => 'nonce')); $fieldSet = $this->addFieldset(___('Address Info')) ->setLabel(___("Address Info\n" . '(must match your credit card statement delivery address)')); $bname = $fieldSet->addGroup()->setLabel(___("Billing Name\n" . 'Billing Address First and Last name')); $bname->addRule('required', ___('Please enter billing name')); $bname->addText($fn . 'credit_card__billing_address__first_name', array('size' => 15)) ->addRule('required', ___('Please enter first name')) ->addRule('regex', ___('Please enter first name'), '|^[a-zA-Z_\' -]+$|'); $bname->addText($fn . 'credit_card__billing_address__last_name', array('size' => 15)) ->addRule('required', ___('Please enter last name')) ->addRule('regex', ___('Please enter last name'), '|^[a-zA-Z_\' -]+$|'); $fieldSet->addText($fn . 'credit_card__billing_address__street_address') ->setLabel(___('Street Address')) ->addRule('required', ___('Please enter Street Address')); $fieldSet->addText($fn . 'credit_card__billing_address__extended_address') ->setLabel(___('Street Address (Second Line)')); $fieldSet->addText($fn . 'credit_card__billing_address__locality') ->setLabel(___('City')); $fieldSet->addText($fn . 'credit_card__billing_address__postal_code') ->setLabel(___('Zipcode')) ->addRule('required', ___('Please enter ZIP code')); $country = $fieldSet->addSelect($fn . 'credit_card__billing_address__country_name')->setLabel(___('Country')) ->setId('f_cc_country') ->loadOptions(Am_Di::getInstance()->countryTable->getOptions(true)); $country->addRule('required', ___('Please enter Country')); $group = $fieldSet->addGroup()->setLabel(___('State')); $group->addRule('required', ___('Please enter State')); $stateSelect = $group->addSelect($fn . 'credit_card__billing_address__region') ->setId('f_cc_state') ->loadOptions($stateOptions = Am_Di::getInstance()->stateTable->getOptions(@$_REQUEST['cc_country'], true)); $stateText = $group->addText($fn . 'credit_card__billing_address__region')->setId('t_cc_state'); $disableObj = $stateOptions ? $stateText : $stateSelect; $disableObj->setAttribute('disabled', 'disabled')->setAttribute('style', 'display: none'); $clientToken = \Braintree\ClientToken::generate(); $this->addScript()->setScript(<<
* $trData = TransparentRedirect::transactionData(array(
* 'redirectUrl' => 'http://example.com/complete_transaction',
* 'transaction' => array('amount' => '100.00'),
* ));
*
*
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*/
class TransparentRedirect
{
// Request Kinds
const CREATE_TRANSACTION = 'create_transaction';
const CREATE_PAYMENT_METHOD = 'create_payment_method';
const UPDATE_PAYMENT_METHOD = 'update_payment_method';
const CREATE_CUSTOMER = 'create_customer';
const UPDATE_CUSTOMER = 'update_customer';
/**
* @ignore
* don't permit an explicit call of the constructor!
* (like $t = new TransparentRedirect())
*/
protected function __construct()
{
}
// static methods redirecting to gateway
public static function confirm($queryString)
{
return Configuration::gateway()->transparentRedirect()->confirm($queryString);
}
public static function createCreditCardData($params)
{
return Configuration::gateway()->transparentRedirect()->createCreditCardData($params);
}
public static function createCustomerData($params)
{
return Configuration::gateway()->transparentRedirect()->createCustomerData($params);
}
public static function url()
{
return Configuration::gateway()->transparentRedirect()->url();
}
public static function transactionData($params)
{
return Configuration::gateway()->transparentRedirect()->transactionData($params);
}
public static function updateCreditCardData($params)
{
return Configuration::gateway()->transparentRedirect()->updateCreditCardData($params);
}
public static function updateCustomerData($params)
{
return Configuration::gateway()->transparentRedirect()->updateCustomerData($params);
}
public static function parseAndValidateQueryString($queryString)
{
return Configuration::gateway()->transparentRedirect()->parseAndValidateQueryString($queryString);
}
}
class_alias('Braintree\TransparentRedirect', 'Braintree_TransparentRedirect');
lib/Braintree/Digest.php 0000644 00000003200 15210163246 0011150 0 ustar 00 disbursementDate);
}
}
class_alias('Braintree\DisbursementDetails', 'Braintree_DisbursementDetails');
lib/Braintree/ResourceCollection.php 0000644 00000006621 15210163246 0013546 0 ustar 00
* $result = Customer::all();
*
* foreach($result as $transaction) {
* print_r($transaction->id);
* }
*
*
* @package Braintree
* @subpackage Utility
* @copyright 2015 Braintree, a division of PayPal, Inc.
*/
class ResourceCollection implements Iterator
{
private $_batchIndex;
private $_ids;
private $_index;
private $_items;
private $_pageSize;
private $_pager;
/**
* set up the resource collection
*
* expects an array of attributes with literal keys
*
* @param array $response
* @param array $pager
*/
public function __construct($response, $pager)
{
$this->_pageSize = $response["searchResults"]["pageSize"];
$this->_ids = $response["searchResults"]["ids"];
$this->_pager = $pager;
}
/**
* returns the current item when iterating with foreach
*/
public function current()
{
return $this->_items[$this->_index];
}
/**
* returns the first item in the collection
*
* @return mixed
*/
public function firstItem()
{
$ids = $this->_ids;
$page = $this->_getPage([$ids[0]]);
return $page[0];
}
public function key()
{
return null;
}
/**
* advances to the next item in the collection when iterating with foreach
*/
public function next()
{
++$this->_index;
}
/**
* rewinds the testIterateOverResults collection to the first item when iterating with foreach
*/
public function rewind()
{
$this->_batchIndex = 0;
$this->_getNextPage();
}
/**
* returns whether the current item is valid when iterating with foreach
*/
public function valid()
{
if ($this->_index == count($this->_items) && $this->_batchIndex < count($this->_ids)) {
$this->_getNextPage();
}
if ($this->_index < count($this->_items)) {
return true;
} else {
return false;
}
}
public function maximumCount()
{
return count($this->_ids);
}
private function _getNextPage()
{
if (empty($this->_ids))
{
$this->_items = [];
}
else
{
$this->_items = $this->_getPage(array_slice($this->_ids, $this->_batchIndex, $this->_pageSize));
$this->_batchIndex += $this->_pageSize;
$this->_index = 0;
}
}
/**
* requests the next page of results for the collection
*
* @return void
*/
private function _getPage($ids)
{
$object = $this->_pager['object'];
$method = $this->_pager['method'];
$methodArgs = [];
foreach ($this->_pager['methodArgs'] as $arg) {
array_push($methodArgs, $arg);
}
array_push($methodArgs, $ids);
return call_user_func_array(
[$object, $method],
$methodArgs
);
}
/**
* returns all IDs in the collection
*
* @return array
*/
public function getIds()
{
return $this->_ids;
}
}
class_alias('Braintree\ResourceCollection', 'Braintree_ResourceCollection');
lib/Braintree/Util.php 0000644 00000035063 15210163246 0010662 0 ustar 00 success) {
return $resultObj->$resultObjName;
} else {
throw new Exception\ValidationsFailed();
}
}
/**
* removes the header from a classname
*
* @param string $name ClassName
* @return camelCased classname minus header
*/
public static function cleanClassName($name)
{
$classNamesToResponseKeys = [
'Braintree\CreditCard' => 'creditCard',
'Braintree_CreditCard' => 'creditCard',
'Braintree\CreditCardGateway' => 'creditCard',
'Braintree_CreditCardGateway' => 'creditCard',
'Braintree\Customer' => 'customer',
'Braintree_Customer' => 'customer',
'Braintree\CustomerGateway' => 'customer',
'Braintree_CustomerGateway' => 'customer',
'Braintree\Subscription' => 'subscription',
'Braintree_Subscription' => 'subscription',
'Braintree\SubscriptionGateway' => 'subscription',
'Braintree_SubscriptionGateway' => 'subscription',
'Braintree\Transaction' => 'transaction',
'Braintree_Transaction' => 'transaction',
'Braintree\TransactionGateway' => 'transaction',
'Braintree_TransactionGateway' => 'transaction',
'Braintree\CreditCardVerification' => 'verification',
'Braintree_CreditCardVerification' => 'verification',
'Braintree\CreditCardVerificationGateway' => 'verification',
'Braintree_CreditCardVerificationGateway' => 'verification',
'Braintree\AddOn' => 'addOn',
'Braintree_AddOn' => 'addOn',
'Braintree\AddOnGateway' => 'addOn',
'Braintree_AddOnGateway' => 'addOn',
'Braintree\Discount' => 'discount',
'Braintree_Discount' => 'discount',
'Braintree\DiscountGateway' => 'discount',
'Braintree_DiscountGateway' => 'discount',
'Braintree\Plan' => 'plan',
'Braintree_Plan' => 'plan',
'Braintree\PlanGateway' => 'plan',
'Braintree_PlanGateway' => 'plan',
'Braintree\Address' => 'address',
'Braintree_Address' => 'address',
'Braintree\AddressGateway' => 'address',
'Braintree_AddressGateway' => 'address',
'Braintree\SettlementBatchSummary' => 'settlementBatchSummary',
'Braintree_SettlementBatchSummary' => 'settlementBatchSummary',
'Braintree\SettlementBatchSummaryGateway' => 'settlementBatchSummary',
'Braintree_SettlementBatchSummaryGateway' => 'settlementBatchSummary',
'Braintree\Merchant' => 'merchant',
'Braintree_Merchant' => 'merchant',
'Braintree\MerchantGateway' => 'merchant',
'Braintree_MerchantGateway' => 'merchant',
'Braintree\MerchantAccount' => 'merchantAccount',
'Braintree_MerchantAccount' => 'merchantAccount',
'Braintree\MerchantAccountGateway' => 'merchantAccount',
'Braintree_MerchantAccountGateway' => 'merchantAccount',
'Braintree\OAuthCredentials' => 'credentials',
'Braintree_OAuthCredentials' => 'credentials',
'Braintree\OAuthResult' => 'result',
'Braintree_OAuthResult' => 'result',
'Braintree\PayPalAccount' => 'paypalAccount',
'Braintree_PayPalAccount' => 'paypalAccount',
'Braintree\PayPalAccountGateway' => 'paypalAccount',
'Braintree_PayPalAccountGateway' => 'paypalAccount',
];
return $classNamesToResponseKeys[$name];
}
/**
*
* @param string $name className
* @return string ClassName
*/
public static function buildClassName($name)
{
$responseKeysToClassNames = [
'creditCard' => 'Braintree\CreditCard',
'customer' => 'Braintree\Customer',
'subscription' => 'Braintree\Subscription',
'transaction' => 'Braintree\Transaction',
'verification' => 'Braintree\CreditCardVerification',
'addOn' => 'Braintree\AddOn',
'discount' => 'Braintree\Discount',
'plan' => 'Braintree\Plan',
'address' => 'Braintree\Address',
'settlementBatchSummary' => 'Braintree\SettlementBatchSummary',
'merchantAccount' => 'Braintree\MerchantAccount',
];
return (string) $responseKeysToClassNames[$name];
}
/**
* convert alpha-beta-gamma to alphaBetaGamma
*
* @access public
* @param string $string
* @param null|string $delimiter
* @return string modified string
*/
public static function delimiterToCamelCase($string, $delimiter = '[\-\_]')
{
// php doesn't garbage collect functions created by create_function()
// so use a static variable to avoid adding a new function to memory
// every time this function is called.
static $callback = null;
if ($callback === null) {
$callback = create_function('$matches', 'return strtoupper($matches[1]);');
}
return preg_replace_callback('/' . $delimiter . '(\w)/', $callback, $string);
}
/**
* convert alpha-beta-gamma to alpha_beta_gamma
*
* @access public
* @param string $string
* @return string modified string
*/
public static function delimiterToUnderscore($string)
{
return preg_replace('/-/', '_', $string);
}
/**
* find capitals and convert to delimiter + lowercase
*
* @access public
* @param string $string
* @param null|string $delimiter
* @return string modified string
*/
public static function camelCaseToDelimiter($string, $delimiter = '-')
{
return strtolower(preg_replace('/([A-Z])/', "$delimiter\\1", $string));
}
public static function delimiterToCamelCaseArray($array, $delimiter = '[\-\_]')
{
$converted = [];
foreach ($array as $key => $value) {
if (is_string($key)) {
$key = self::delimiterToCamelCase($key, $delimiter);
}
if (is_array($value)) {
// Make an exception for custom fields, which must be underscore (can't be
// camelCase).
if ($key === 'customFields') {
$value = self::delimiterToUnderscoreArray($value);
} else {
$value = self::delimiterToCamelCaseArray($value, $delimiter);
}
}
$converted[$key] = $value;
}
return $converted;
}
public static function camelCaseToDelimiterArray($array, $delimiter = '-')
{
$converted = [];
foreach ($array as $key => $value) {
if (is_string($key)) {
$key = self::camelCaseToDelimiter($key, $delimiter);
}
if (is_array($value)) {
$value = self::camelCaseToDelimiterArray($value, $delimiter);
}
$converted[$key] = $value;
}
return $converted;
}
public static function delimiterToUnderscoreArray($array)
{
$converted = [];
foreach ($array as $key => $value) {
$key = self::delimiterToUnderscore($key);
$converted[$key] = $value;
}
return $converted;
}
/**
*
* @param array $array associative array to implode
* @param string $separator (optional, defaults to =)
* @param string $glue (optional, defaults to ', ')
* @return bool
*/
public static function implodeAssociativeArray($array, $separator = '=', $glue = ', ')
{
// build a new array with joined keys and values
$tmpArray = null;
foreach ($array AS $key => $value) {
if ($value instanceof DateTime) {
$value = $value->format('r');
}
$tmpArray[] = $key . $separator . $value;
}
// implode and return the new array
return (is_array($tmpArray)) ? implode($glue, $tmpArray) : false;
}
public static function attributesToString($attributes) {
$printableAttribs = [];
foreach ($attributes AS $key => $value) {
if (is_array($value)) {
$pAttrib = self::attributesToString($value);
} else if ($value instanceof DateTime) {
$pAttrib = $value->format(DateTime::RFC850);
} else {
$pAttrib = $value;
}
$printableAttribs[$key] = sprintf('%s', $pAttrib);
}
return self::implodeAssociativeArray($printableAttribs);
}
/**
* verify user request structure
*
* compares the expected signature of a gateway request
* against the actual structure sent by the user
*
* @param array $signature
* @param array $attributes
*/
public static function verifyKeys($signature, $attributes)
{
$validKeys = self::_flattenArray($signature);
$userKeys = self::_flattenUserKeys($attributes);
$invalidKeys = array_diff($userKeys, $validKeys);
$invalidKeys = self::_removeWildcardKeys($validKeys, $invalidKeys);
if(!empty($invalidKeys)) {
asort($invalidKeys);
$sortedList = join(', ', $invalidKeys);
throw new InvalidArgumentException('invalid keys: ' . $sortedList);
}
}
/**
* flattens a numerically indexed nested array to a single level
* @param array $keys
* @param string $namespace
* @return array
*/
private static function _flattenArray($keys, $namespace = null)
{
$flattenedArray = [];
foreach($keys AS $key) {
if(is_array($key)) {
$theKeys = array_keys($key);
$theValues = array_values($key);
$scope = $theKeys[0];
$fullKey = empty($namespace) ? $scope : $namespace . '[' . $scope . ']';
$flattenedArray = array_merge($flattenedArray, self::_flattenArray($theValues[0], $fullKey));
} else {
$fullKey = empty($namespace) ? $key : $namespace . '[' . $key . ']';
$flattenedArray[] = $fullKey;
}
}
sort($flattenedArray);
return $flattenedArray;
}
private static function _flattenUserKeys($keys, $namespace = null)
{
$flattenedArray = [];
foreach($keys AS $key => $value) {
$fullKey = empty($namespace) ? $key : $namespace;
if (!is_numeric($key) && $namespace != null) {
$fullKey .= '[' . $key . ']';
}
if (is_numeric($key) && is_string($value)) {
$fullKey .= '[' . $value . ']';
}
if(is_array($value)) {
$more = self::_flattenUserKeys($value, $fullKey);
$flattenedArray = array_merge($flattenedArray, $more);
} else {
$flattenedArray[] = $fullKey;
}
}
sort($flattenedArray);
return $flattenedArray;
}
/**
* removes wildcard entries from the invalid keys array
* @param array $validKeys
* @param
* $result = Customer::create(array(
* 'first_name' => 'John',
* 'last_name' => 'Smith',
* 'company' => 'Smith Co.',
* 'email' => 'john@smith.com',
* 'website' => 'www.smithco.com',
* 'fax' => '419-555-1234',
* 'phone' => '614-555-1234'
* ));
* if($result->success) {
* echo 'Created customer ' . $result->customer->id;
* } else {
* echo 'Could not create customer, see result->errors';
* }
*
*
* @access public
* @param array $attribs
* @return Braintree_Result_Successful|Braintree_Result_Error
*/
public function create($attribs = [])
{
Util::verifyKeys(self::createSignature(), $attribs);
return $this->_doCreate('/customers', ['customer' => $attribs]);
}
/**
* attempts the create operation assuming all data will validate
* returns a Customer object instead of a Result
*
* @access public
* @param array $attribs
* @return Customer
* @throws Exception\ValidationError
*/
public function createNoValidate($attribs = [])
{
$result = $this->create($attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
* create a customer from a TransparentRedirect operation
*
* @deprecated since version 2.3.0
* @access public
* @param array $attribs
* @return Customer
*/
public function createFromTransparentRedirect($queryString)
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE);
$params = TransparentRedirect::parseAndValidateQueryString(
$queryString
);
return $this->_doCreate(
'/customers/all/confirm_transparent_redirect_request',
['id' => $params['id']]
);
}
/**
*
* @deprecated since version 2.3.0
* @access public
* @param none
* @return string
*/
public function createCustomerUrl()
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE);
return $this->_config->baseUrl() . $this->_config->merchantPath() .
'/customers/all/create_via_transparent_redirect_request';
}
/**
* creates a full array signature of a valid create request
* @return array gateway create request format
*/
public static function createSignature()
{
$creditCardSignature = CreditCardGateway::createSignature();
unset($creditCardSignature[array_search('customerId', $creditCardSignature)]);
$signature = [
'id', 'company', 'email', 'fax', 'firstName',
'lastName', 'phone', 'website', 'deviceData',
'deviceSessionId', 'fraudMerchantId', 'paymentMethodNonce',
['riskData' =>
['customerBrowser', 'customerIp', 'customer_browser', 'customer_ip']
],
['creditCard' => $creditCardSignature],
['customFields' => ['_anyKey_']],
];
return $signature;
}
/**
* creates a full array signature of a valid update request
* @return array update request format
*/
public static function updateSignature()
{
$creditCardSignature = CreditCardGateway::updateSignature();
foreach($creditCardSignature AS $key => $value) {
if(is_array($value) and array_key_exists('options', $value)) {
array_push($creditCardSignature[$key]['options'], 'updateExistingToken');
}
}
$signature = [
'id', 'company', 'email', 'fax', 'firstName',
'lastName', 'phone', 'website', 'deviceData',
'deviceSessionId', 'fraudMerchantId', 'paymentMethodNonce', 'defaultPaymentMethodToken',
['creditCard' => $creditCardSignature],
['customFields' => ['_anyKey_']],
];
return $signature;
}
/**
* find a customer by id
*
* @access public
* @param string id customer Id
* @return Customer|boolean The customer object or false if the request fails.
* @throws Exception\NotFound
*/
public function find($id)
{
$this->_validateId($id);
try {
$path = $this->_config->merchantPath() . '/customers/' . $id;
$response = $this->_http->get($path);
return Customer::factory($response['customer']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'customer with id ' . $id . ' not found'
);
}
}
/**
* credit a customer for the passed transaction
*
* @access public
* @param int $customerId
* @param array $transactionAttribs
* @return Result\Successful|Result\Error
*/
public function credit($customerId, $transactionAttribs)
{
$this->_validateId($customerId);
return Transaction::credit(
array_merge($transactionAttribs,
['customerId' => $customerId]
)
);
}
/**
* credit a customer, assuming validations will pass
*
* returns a Transaction object on success
*
* @access public
* @param int $customerId
* @param array $transactionAttribs
* @return Transaction
* @throws Exception\ValidationError
*/
public function creditNoValidate($customerId, $transactionAttribs)
{
$result = $this->credit($customerId, $transactionAttribs);
return Util::returnObjectOrThrowException('Braintree\Transaction', $result);
}
/**
* delete a customer by id
*
* @param string $customerId
*/
public function delete($customerId)
{
$this->_validateId($customerId);
$path = $this->_config->merchantPath() . '/customers/' . $customerId;
$this->_http->delete($path);
return new Result\Successful();
}
/**
* create a new sale for a customer
*
* @param string $customerId
* @param array $transactionAttribs
* @return Result\Successful|Result\Error
* @see Transaction::sale()
*/
public function sale($customerId, $transactionAttribs)
{
$this->_validateId($customerId);
return Transaction::sale(
array_merge($transactionAttribs,
['customerId' => $customerId]
)
);
}
/**
* create a new sale for a customer, assuming validations will pass
*
* returns a Transaction object on success
* @access public
* @param string $customerId
* @param array $transactionAttribs
* @return Transaction
* @throws Exception\ValidationsFailed
* @see Transaction::sale()
*/
public function saleNoValidate($customerId, $transactionAttribs)
{
$result = $this->sale($customerId, $transactionAttribs);
return Util::returnObjectOrThrowException('Braintree\Transaction', $result);
}
/**
* Returns a ResourceCollection of customers matching the search query.
*
* If query is a string, the search will be a basic search.
* If query is a hash, the search will be an advanced search.
* For more detailed information and examples, see {@link http://www.braintreepayments.com/gateway/customer-api#searching http://www.braintreepaymentsolutions.com/gateway/customer-api}
*
* @param mixed $query search query
* @return ResourceCollection
* @throws InvalidArgumentException
*/
public function search($query)
{
$criteria = [];
foreach ($query as $term) {
$result = $term->toparam();
if(is_null($result) || empty($result)) {
throw new InvalidArgumentException('Operator must be provided');
}
$criteria[$term->name] = $term->toparam();
}
$path = $this->_config->merchantPath() . '/customers/advanced_search_ids';
$response = $this->_http->post($path, ['search' => $criteria]);
$pager = [
'object' => $this,
'method' => 'fetch',
'methodArgs' => [$query]
];
return new ResourceCollection($response, $pager);
}
/**
* updates the customer record
*
* if calling this method in static context, customerId
* is the 2nd attribute. customerId is not sent in object context.
*
* @access public
* @param string $customerId (optional)
* @param array $attributes
* @return Result\Successful|Result\Error
*/
public function update($customerId, $attributes)
{
Util::verifyKeys(self::updateSignature(), $attributes);
$this->_validateId($customerId);
return $this->_doUpdate(
'put',
'/customers/' . $customerId,
['customer' => $attributes]
);
}
/**
* update a customer record, assuming validations will pass
*
* if calling this method in static context, customerId
* is the 2nd attribute. customerId is not sent in object context.
* returns a Customer object on success
*
* @access public
* @param string $customerId
* @param array $attributes
* @return Customer
* @throws Exception\ValidationsFailed
*/
public function updateNoValidate($customerId, $attributes)
{
$result = $this->update($customerId, $attributes);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
*
* @deprecated since version 2.3.0
* @access public
* @return string
*/
public function updateCustomerUrl()
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE);
return $this->_config->baseUrl() . $this->_config->merchantPath() .
'/customers/all/update_via_transparent_redirect_request';
}
/**
* update a customer from a TransparentRedirect operation
*
* @deprecated since version 2.3.0
* @access public
* @param string $queryString
* @return object
*/
public function updateFromTransparentRedirect($queryString)
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE);
$params = TransparentRedirect::parseAndValidateQueryString(
$queryString
);
return $this->_doUpdate(
'post',
'/customers/all/confirm_transparent_redirect_request',
['id' => $params['id']]
);
}
/* instance methods */
/**
* sets instance properties from an array of values
*
* @ignore
* @access protected
* @param array $customerAttribs array of customer data
* @return void
*/
protected function _initialize($customerAttribs)
{
// set the attributes
$this->_attributes = $customerAttribs;
// map each address into its own object
$addressArray = [];
if (isset($customerAttribs['addresses'])) {
foreach ($customerAttribs['addresses'] AS $address) {
$addressArray[] = Address::factory($address);
}
}
$this->_set('addresses', $addressArray);
// map each creditCard into its own object
$creditCardArray = [];
if (isset($customerAttribs['creditCards'])) {
foreach ($customerAttribs['creditCards'] AS $creditCard) {
$creditCardArray[] = CreditCard::factory($creditCard);
}
}
$this->_set('creditCards', $creditCardArray);
// map each coinbaseAccount into its own object
$coinbaseAccountArray = [];
if (isset($customerAttribs['coinbaseAccounts'])) {
foreach ($customerAttribs['coinbaseAccounts'] AS $coinbaseAccount) {
$coinbaseAccountArray[] = CoinbaseAccount::factory($coinbaseAccount);
}
}
$this->_set('coinbaseAccounts', $coinbaseAccountArray);
// map each paypalAccount into its own object
$paypalAccountArray = [];
if (isset($customerAttribs['paypalAccounts'])) {
foreach ($customerAttribs['paypalAccounts'] AS $paypalAccount) {
$paypalAccountArray[] = PayPalAccount::factory($paypalAccount);
}
}
$this->_set('paypalAccounts', $paypalAccountArray);
// map each applePayCard into its own object
$applePayCardArray = [];
if (isset($customerAttribs['applePayCards'])) {
foreach ($customerAttribs['applePayCards'] AS $applePayCard) {
$applePayCardArray[] = ApplePayCard::factory($applePayCard);
}
}
$this->_set('applePayCards', $applePayCardArray);
// map each androidPayCard into its own object
$androidPayCardArray = [];
if (isset($customerAttribs['androidPayCards'])) {
foreach ($customerAttribs['androidPayCards'] AS $androidPayCard) {
$androidPayCardArray[] = AndroidPayCard::factory($androidPayCard);
}
}
$this->_set('androidPayCards', $androidPayCardArray);
$this->_set('paymentMethods', array_merge($this->creditCards, $this->paypalAccounts, $this->applePayCards, $this->coinbaseAccounts, $this->androidPayCards));
}
/**
* returns a string representation of the customer
* @return string
*/
public function __toString()
{
return __CLASS__ . '[' .
Util::attributesToString($this->_attributes) .']';
}
/**
* returns false if comparing object is not a Customer,
* or is a Customer with a different id
*
* @param object $otherCust customer to compare against
* @return boolean
*/
public function isEqual($otherCust)
{
return !($otherCust instanceof Customer) ? false : $this->id === $otherCust->id;
}
/**
* returns an array containt all of the customer's payment methods
*
* @return array
*/
public function paymentMethods()
{
return $this->paymentMethods;
}
/**
* returns the customer's default payment method
*
* @return CreditCard|PayPalAccount|ApplePayCard|AndroidPayCard
*/
public function defaultPaymentMethod()
{
$defaultPaymentMethods = array_filter($this->paymentMethods, 'Braintree\\Customer::_defaultPaymentMethodFilter');
return current($defaultPaymentMethods);
}
public static function _defaultPaymentMethodFilter($paymentMethod)
{
return $paymentMethod->isDefault();
}
/* private class properties */
/**
* @access protected
* @var array registry of customer data
*/
protected $_attributes = [
'addresses' => '',
'company' => '',
'creditCards' => '',
'email' => '',
'fax' => '',
'firstName' => '',
'id' => '',
'lastName' => '',
'phone' => '',
'createdAt' => '',
'updatedAt' => '',
'website' => '',
];
/**
* sends the create request to the gateway
*
* @ignore
* @param string $subPath
* @param array $params
* @return mixed
*/
public function _doCreate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* verifies that a valid customer id is being used
* @ignore
* @param string customer id
* @throws InvalidArgumentException
*/
private function _validateId($id = null) {
if (is_null($id)) {
throw new InvalidArgumentException(
'expected customer id to be set'
);
}
if (!preg_match('/^[0-9A-Za-z_-]+$/', $id)) {
throw new InvalidArgumentException(
$id . ' is an invalid customer id.'
);
}
}
/* private class methods */
/**
* sends the update request to the gateway
*
* @ignore
* @param string $subPath
* @param array $params
* @return mixed
*/
private function _doUpdate($httpVerb, $subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->$httpVerb($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* generic method for validating incoming gateway responses
*
* creates a new Customer object and encapsulates
* it inside a Result\Successful object, or
* encapsulates a Errors object inside a Result\Error
* alternatively, throws an Unexpected exception if the response is invalid.
*
* @ignore
* @param array $response gateway response values
* @return Result\Successful|Result\Error
* @throws Exception\Unexpected
*/
private function _verifyGatewayResponse($response)
{
if (isset($response['customer'])) {
// return a populated instance of Customer
return new Result\Successful(
Customer::factory($response['customer'])
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else {
throw new Exception\Unexpected(
"Expected customer or apiErrorResponse"
);
}
}
}
class_alias('Braintree\CustomerGateway', 'Braintree_CustomerGateway');
lib/Braintree/AddressGateway.php 0000644 00000021652 15210163246 0012653 0 ustar 00 _gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
/* public class methods */
/**
*
* @access public
* @param array $attribs
* @return Result\Successful|Result\Error
*/
public function create($attribs)
{
Util::verifyKeys(self::createSignature(), $attribs);
$customerId = isset($attribs['customerId']) ?
$attribs['customerId'] :
null;
$this->_validateCustomerId($customerId);
unset($attribs['customerId']);
try {
return $this->_doCreate(
'/customers/' . $customerId . '/addresses',
['address' => $attribs]
);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'Customer ' . $customerId . ' not found.'
);
}
}
/**
* attempts the create operation assuming all data will validate
* returns a Address object instead of a Result
*
* @access public
* @param array $attribs
* @return self
* @throws Exception\ValidationError
*/
public function createNoValidate($attribs)
{
$result = $this->create($attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
* delete an address by id
*
* @param mixed $customerOrId
* @param string $addressId
*/
public function delete($customerOrId = null, $addressId = null)
{
$this->_validateId($addressId);
$customerId = $this->_determineCustomerId($customerOrId);
$path = $this->_config->merchantPath() . '/customers/' . $customerId . '/addresses/' . $addressId;
$this->_http->delete($path);
return new Result\Successful();
}
/**
* find an address by id
*
* Finds the address with the given addressId that is associated
* to the given customerOrId.
* If the address cannot be found, a NotFound exception will be thrown.
*
*
* @access public
* @param mixed $customerOrId
* @param string $addressId
* @return Address
* @throws Exception\NotFound
*/
public function find($customerOrId, $addressId)
{
$customerId = $this->_determineCustomerId($customerOrId);
$this->_validateId($addressId);
try {
$path = $this->_config->merchantPath() . '/customers/' . $customerId . '/addresses/' . $addressId;
$response = $this->_http->get($path);
return Address::factory($response['address']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'address for customer ' . $customerId .
' with id ' . $addressId . ' not found.'
);
}
}
/**
* updates the address record
*
* if calling this method in context,
* customerOrId is the 2nd attribute, addressId 3rd.
* customerOrId & addressId are not sent in object context.
*
*
* @access public
* @param array $attributes
* @param mixed $customerOrId (only used in call)
* @param string $addressId (only used in call)
* @return Result\Successful|Result\Error
*/
public function update($customerOrId, $addressId, $attributes)
{
$this->_validateId($addressId);
$customerId = $this->_determineCustomerId($customerOrId);
Util::verifyKeys(self::updateSignature(), $attributes);
$path = $this->_config->merchantPath() . '/customers/' . $customerId . '/addresses/' . $addressId;
$response = $this->_http->put($path, ['address' => $attributes]);
return $this->_verifyGatewayResponse($response);
}
/**
* update an address record, assuming validations will pass
*
* if calling this method in context,
* customerOrId is the 2nd attribute, addressId 3rd.
* customerOrId & addressId are not sent in object context.
*
* @access public
* @param array $transactionAttribs
* @param string $customerId
* @return Transaction
* @throws Exception\ValidationsFailed
* @see Address::update()
*/
public function updateNoValidate($customerOrId, $addressId, $attributes)
{
$result = $this->update($customerOrId, $addressId, $attributes);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
* creates a full array signature of a valid create request
* @return array gateway create request format
*/
public static function createSignature()
{
return [
'company', 'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',
'countryName', 'customerId', 'extendedAddress', 'firstName',
'lastName', 'locality', 'postalCode', 'region', 'streetAddress'
];
}
/**
* creates a full array signature of a valid update request
* @return array gateway update request format
*/
public static function updateSignature()
{
// TODO: remove customerId from update signature
return self::createSignature();
}
/**
* verifies that a valid address id is being used
* @ignore
* @param string $id address id
* @throws InvalidArgumentException
*/
private function _validateId($id = null)
{
if (empty($id) || trim($id) == "") {
throw new InvalidArgumentException(
'expected address id to be set'
);
}
if (!preg_match('/^[0-9A-Za-z_-]+$/', $id)) {
throw new InvalidArgumentException(
$id . ' is an invalid address id.'
);
}
}
/**
* verifies that a valid customer id is being used
* @ignore
* @param string $id customer id
* @throws InvalidArgumentException
*/
private function _validateCustomerId($id = null)
{
if (empty($id) || trim($id) == "") {
throw new InvalidArgumentException(
'expected customer id to be set'
);
}
if (!preg_match('/^[0-9A-Za-z_-]+$/', $id)) {
throw new InvalidArgumentException(
$id . ' is an invalid customer id.'
);
}
}
/**
* determines if a string id or Customer object was passed
* @ignore
* @param mixed $customerOrId
* @return string customerId
*/
private function _determineCustomerId($customerOrId)
{
$customerId = ($customerOrId instanceof Customer) ? $customerOrId->id : $customerOrId;
$this->_validateCustomerId($customerId);
return $customerId;
}
/* private class methods */
/**
* sends the create request to the gateway
* @ignore
* @param string $subPath
* @param array $params
* @return Result\Successful|Result\Error
*/
private function _doCreate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* generic method for validating incoming gateway responses
*
* creates a new Address object and encapsulates
* it inside a Result\Successful object, or
* encapsulates an Errors object inside a Result\Error
* alternatively, throws an Unexpected exception if the response is invalid
*
* @ignore
* @param array $response gateway response values
* @return Result\Successful|Result\Error
* @throws Exception\Unexpected
*/
private function _verifyGatewayResponse($response)
{
if (isset($response['address'])) {
// return a populated instance of Address
return new Result\Successful(
Address::factory($response['address'])
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else {
throw new Exception\Unexpected(
"Expected address or apiErrorResponse"
);
}
}
}
class_alias('Braintree\AddressGateway', 'Braintree_AddressGateway');
lib/Braintree/CreditCardVerificationSearch.php 0000644 00000002735 15210163246 0015442 0 ustar 00 _attributes = $disputeAttribs;
if (isset($disputeAttribs['transaction'])) {
$this->_set('transactionDetails',
new Dispute\TransactionDetails($disputeAttribs['transaction'])
);
}
}
public static function factory($attributes)
{
$instance = new self();
$instance->_initialize($attributes);
return $instance;
}
public function __toString()
{
$display = [
'amount', 'reason', 'status',
'replyByDate', 'receivedDate', 'currencyIsoCode'
];
$displayAttributes = [];
foreach ($display AS $attrib) {
$displayAttributes[$attrib] = $this->$attrib;
}
return __CLASS__ . '[' .
Util::attributesToString($displayAttributes) .']';
}
}
class_alias('Braintree\Dispute', 'Braintree_Dispute');
lib/Braintree/Result/Successful.php 0000644 00000005107 15210163246 0013336 0 ustar 00 customer like so:
*
*
* $result = Customer::create(array('first_name' => "John"));
* if ($result->success) {
* // Successful
* echo "Created customer {$result->customer->id}";
* } else {
* // Error
* }
*
*
*
* @package Braintree
* @subpackage Result
* @copyright 2015 Braintree, a division of PayPal, Inc.
*/
class Successful extends Instance
{
/**
*
* @var boolean always true
*/
public $success = true;
/**
*
* @var string stores the internal name of the object providing access to
*/
private $_returnObjectNames;
/**
* @ignore
* @param array|null $objsToReturn
* @param array|null $propertyNames
*/
public function __construct($objsToReturn = [], $propertyNames = [])
{
// Sanitize arguments (preserves backwards compatibility)
if (!is_array($objsToReturn)) { $objsToReturn = [$objsToReturn]; }
if (!is_array($propertyNames)) { $propertyNames = [$propertyNames]; }
$objects = $this->_mapPropertyNamesToObjsToReturn($propertyNames, $objsToReturn);
$this->_attributes = [];
$this->_returnObjectNames = [];
foreach ($objects as $propertyName => $objToReturn) {
// save the name for indirect access
array_push($this->_returnObjectNames, $propertyName);
// create the property!
$this->$propertyName = $objToReturn;
}
}
/**
*
* @ignore
* @return string string representation of the object's structure
*/
public function __toString()
{
$objects = [];
foreach ($this->_returnObjectNames as $returnObjectName) {
array_push($objects, $this->$returnObjectName);
}
return __CLASS__ . '[' . implode(', ', $objects) . ']';
}
private function _mapPropertyNamesToObjsToReturn($propertyNames, $objsToReturn) {
if(count($objsToReturn) != count($propertyNames)) {
$propertyNames = [];
foreach ($objsToReturn as $obj) {
array_push($propertyNames, Util::cleanClassName(get_class($obj)));
}
}
return array_combine($propertyNames, $objsToReturn);
}
}
class_alias('Braintree\Result\Successful', 'Braintree_Result_Successful');
lib/Braintree/Result/CreditCardVerification.php 0000644 00000005133 15210163246 0015565 0 ustar 00 _initializeFromArray($attributes);
}
/**
* initializes instance properties from the keys/values of an array
* @ignore
* @access protected
* @param
* $trData = TransparentRedirect::updateCreditCardData(array(
* 'redirectUrl' => 'http://example.com/redirect_here',
* 'paymentMethodToken' => 'token123',
* ));
*
*
* @param array $params
* @return string
*/
public function updateCreditCardData($params)
{
Util::verifyKeys(
self::$_updateCreditCardSignature,
$params
);
if (!isset($params['paymentMethodToken'])) {
throw new InvalidArgumentException(
'expected params to contain paymentMethodToken.'
);
}
$params["kind"] = TransparentRedirect::UPDATE_PAYMENT_METHOD;
return $this->_data($params);
}
/**
* Returns the trData string for updating a customer.
*
* The customerId of the customer to update is required.
*
*
* $trData = TransparentRedirect::updateCustomerData(array(
* 'redirectUrl' => 'http://example.com/redirect_here',
* 'customerId' => 'customer123',
* ));
*
*
* @param array $params
* @return string
*/
public function updateCustomerData($params)
{
Util::verifyKeys(
self::$_updateCustomerSignature,
$params
);
if (!isset($params['customerId'])) {
throw new InvalidArgumentException(
'expected params to contain customerId of customer to update'
);
}
$params["kind"] = TransparentRedirect::UPDATE_CUSTOMER;
return $this->_data($params);
}
public function parseAndValidateQueryString($queryString)
{
// parse the params into an array
parse_str($queryString, $params);
// remove the hash
$queryStringWithoutHash = null;
if (preg_match('/^(.*)&hash=[a-f0-9]+$/', $queryString, $match)) {
$queryStringWithoutHash = $match[1];
}
if($params['http_status'] != '200') {
$message = null;
if(array_key_exists('bt_message', $params)) {
$message = $params['bt_message'];
}
Util::throwStatusCodeException(isset($params['http_status']) ? $params['http_status'] : null, $message);
}
// recreate the hash and compare it
if ($this->_hash($queryStringWithoutHash) == $params['hash']) {
return $params;
} else {
throw new Exception\ForgedQueryString();
}
}
/**
*
* @ignore
*/
private function _data($params)
{
if (!isset($params['redirectUrl'])) {
throw new InvalidArgumentException(
'expected params to contain redirectUrl'
);
}
$params = $this->_underscoreKeys($params);
$now = new DateTime('now', new DateTimeZone('UTC'));
$trDataParams = array_merge($params,
[
'api_version' => Configuration::API_VERSION,
'public_key' => $this->_config->publicKey(),
'time' => $now->format('YmdHis'),
]
);
ksort($trDataParams);
$urlEncodedData = http_build_query($trDataParams, null, "&");
$signatureService = new SignatureService(
$this->_config->privateKey(),
"Braintree\Digest::hexDigestSha1"
);
return $signatureService->sign($urlEncodedData);
}
private function _underscoreKeys($array)
{
foreach($array as $key=>$value)
{
$newKey = Util::camelCaseToDelimiter($key, '_');
unset($array[$key]);
if (is_array($value))
{
$array[$newKey] = $this->_underscoreKeys($value);
}
else
{
$array[$newKey] = $value;
}
}
return $array;
}
/**
* @ignore
*/
private function _hash($string)
{
return Digest::hexDigestSha1($this->_config->privateKey(), $string);
}
}
TransparentRedirectGateway::init();
class_alias('Braintree\TransparentRedirectGateway', 'Braintree_TransparentRedirectGateway');
lib/Braintree/UnknownPaymentMethod.php 0000644 00000003215 15210163246 0014075 0 ustar 00 == More information ==
*
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
* @property-read string $token
* @property-read string $imageUrl
*/
class UnknownPaymentMethod extends Base
{
/**
* factory method: returns an instance of UnknownPaymentMethod
* to the requesting method, with populated properties
*
* @ignore
* @return UnknownPaymentMethod
*/
public static function factory($attributes)
{
$instance = new self();
$values = array_values($attributes);
$instance->_initialize(array_shift($values));
return $instance;
}
/* instance methods */
/**
* returns false if default is null or false
*
* @return boolean
*/
public function isDefault()
{
return $this->default;
}
/**
* sets instance properties from an array of values
*
* @access protected
* @param array $unknownPaymentMethodAttribs array of unknownPaymentMethod data
* @return void
*/
protected function _initialize($unknownPaymentMethodAttribs)
{
// set the attributes
$this->imageUrl = 'https://assets.braintreegateway.com/payment_method_logo/unknown.png';
$this->_attributes = $unknownPaymentMethodAttribs;
}
}
class_alias('Braintree\UnknownPaymentMethod', 'Braintree_UnknownPaymentMethod');
lib/Braintree/Xml/Parser.php 0000644 00000007535 15210163246 0011744 0 ustar 00 loadXML($xml);
$root = $document->documentElement->nodeName;
return Util::delimiterToCamelCaseArray([
$root => self::_nodeToValue($document->childNodes->item(0)),
]);
}
/**
* Converts a node to an array of values or nodes
*
* @param DOMNode @node
* @return mixed
*/
private static function _nodeToArray($node)
{
$type = null;
if ($node instanceof DOMElement) {
$type = $node->getAttribute('type');
}
switch($type) {
case 'array':
$array = [];
foreach ($node->childNodes as $child) {
$value = self::_nodeToValue($child);
if ($value !== null) {
$array[] = $value;
}
}
return $array;
case 'collection':
$collection = [];
foreach ($node->childNodes as $child) {
$value = self::_nodetoValue($child);
if ($value !== null) {
if (!isset($collection[$child->nodeName])) {
$collection[$child->nodeName] = [];
}
$collection[$child->nodeName][] = self::_nodeToValue($child);
}
}
return $collection;
default:
$values = [];
if ($node->childNodes->length === 1 && $node->childNodes->item(0) instanceof DOMText) {
return $node->childNodes->item(0)->nodeValue;
} else {
foreach ($node->childNodes as $child) {
if (!$child instanceof DOMText) {
$values[$child->nodeName] = self::_nodeToValue($child);
}
}
return $values;
}
}
}
/**
* Converts a node to a PHP value
*
* @param DOMNode $node
* @return mixed
*/
private static function _nodeToValue($node)
{
$type = null;
if ($node instanceof DOMElement) {
$type = $node->getAttribute('type');
}
switch($type) {
case 'datetime':
return self::_timestampToUTC((string) $node->nodeValue);
case 'date':
return new DateTime((string) $node->nodeValue);
case 'integer':
return (int) $node->nodeValue;
case 'boolean':
$value = (string) $node->nodeValue;
if(is_numeric($value)) {
return (bool) $value;
} else {
return ($value !== "true") ? false : true;
}
case 'array':
case 'collection':
return self::_nodeToArray($node);
default:
if ($node->hasChildNodes()) {
return self::_nodeToArray($node);
} elseif (trim($node->nodeValue) === '') {
return null;
} else {
return $node->nodeValue;
}
}
}
/**
* Converts XML timestamps into DateTime instances
*
* @param string $timestamp
* @return DateTime
*/
private static function _timestampToUTC($timestamp)
{
$tz = new DateTimeZone('UTC');
$dateTime = new DateTime($timestamp, $tz);
$dateTime->setTimezone($tz);
return $dateTime;
}
}
class_alias('Braintree\Xml\Parser', 'Braintree_Xml_Parser');
lib/Braintree/Xml/Generator.php 0000644 00000011137 15210163246 0012427 0 ustar 00 openMemory();
$writer->setIndent(true);
$writer->setIndentString(' ');
$writer->startDocument('1.0', 'UTF-8');
// get the root element name
$aKeys = array_keys($aData);
$rootElementName = $aKeys[0];
// open the root element
$writer->startElement($rootElementName);
// create the body
self::_createElementsFromArray($writer, $aData[$rootElementName], $rootElementName);
// close the root element and document
$writer->endElement();
$writer->endDocument();
// send the output as string
return $writer->outputMemory();
}
/**
* Construct XML elements with attributes from an associative array.
*
* @access protected
* @static
* @param object $writer XMLWriter object
* @param array $aData contains attributes and values
* @return void
*/
private static function _createElementsFromArray(&$writer, $aData)
{
if (!is_array($aData)) {
if (is_bool($aData)) {
$writer->text($aData ? 'true' : 'false');
} else {
$writer->text($aData);
}
return;
}
foreach ($aData AS $elementName => $element) {
// handle child elements
$writer->startElement($elementName);
if (is_array($element)) {
if (array_key_exists(0, $element) || empty($element)) {
$writer->writeAttribute('type', 'array');
foreach ($element AS $ignored => $itemInArray) {
$writer->startElement('item');
self::_createElementsFromArray($writer, $itemInArray);
$writer->endElement();
}
}
else {
self::_createElementsFromArray($writer, $element);
}
} else {
// generate attributes as needed
$attribute = self::_generateXmlAttribute($element);
if (is_array($attribute)) {
$writer->writeAttribute($attribute[0], $attribute[1]);
$element = $attribute[2];
}
$writer->text($element);
}
$writer->endElement();
}
}
/**
* convert passed data into an array of attributeType, attributeName, and value
* dates sent as DateTime objects will be converted to strings
* @access protected
* @param mixed $value
* @return array attributes and element value
*/
private static function _generateXmlAttribute($value)
{
if ($value instanceof DateTime) {
return ['type', 'datetime', self::_dateTimeToXmlTimestamp($value)];
}
if (is_int($value)) {
return ['type', 'integer', $value];
}
if (is_bool($value)) {
return ['type', 'boolean', ($value ? 'true' : 'false')];
}
if ($value === NULL) {
return ['nil', 'true', $value];
}
}
/**
* converts datetime back to xml schema format
* @access protected
* @param object $dateTime
* @return string XML schema formatted timestamp
*/
private static function _dateTimeToXmlTimestamp($dateTime)
{
$dateTimeForUTC = clone $dateTime;
$dateTimeForUTC->setTimeZone(new DateTimeZone('UTC'));
return ($dateTimeForUTC->format('Y-m-d\TH:i:s') . 'Z');
}
private static function _castDateTime($string)
{
try {
if (empty($string)) {
return false;
}
$dateTime = new DateTime($string);
return self::_dateTimeToXmlTimestamp($dateTime);
} catch (Exception $e) {
// not a datetime
return false;
}
}
}
class_alias('Braintree\Xml\Generator', 'Braintree_Xml_Generator');
lib/Braintree/MerchantAccountGateway.php 0000644 00000011747 15210163246 0014350 0 ustar 00 _gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
public function create($attribs)
{
Util::verifyKeys(self::detectSignature($attribs), $attribs);
return $this->_doCreate('/merchant_accounts/create_via_api', ['merchant_account' => $attribs]);
}
public function find($merchant_account_id)
{
try {
$path = $this->_config->merchantPath() . '/merchant_accounts/' . $merchant_account_id;
$response = $this->_http->get($path);
return MerchantAccount::factory($response['merchantAccount']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound('merchant account with id ' . $merchant_account_id . ' not found');
}
}
public function update($merchant_account_id, $attributes)
{
Util::verifyKeys(self::updateSignature(), $attributes);
return $this->_doUpdate('/merchant_accounts/' . $merchant_account_id . '/update_via_api', ['merchant_account' => $attributes]);
}
public static function detectSignature($attribs)
{
if (isset($attribs['applicantDetails'])) {
trigger_error("DEPRECATED: Passing applicantDetails to create is deprecated. Please use individual, business, and funding", E_USER_NOTICE);
return self::createDeprecatedSignature();
} else {
return self::createSignature();
}
}
public static function updateSignature()
{
$signature = self::createSignature();
unset($signature['tosAccepted']);
return $signature;
}
public function createForCurrency($attribs)
{
$response = $this->_http->post($this->_config->merchantPath() . '/merchant_accounts/create_for_currency', ['merchant_account' => $attribs]);
return $this->_verifyGatewayResponse($response);
}
public static function createSignature()
{
$addressSignature = ['streetAddress', 'postalCode', 'locality', 'region'];
$individualSignature = [
'firstName',
'lastName',
'email',
'phone',
'dateOfBirth',
'ssn',
['address' => $addressSignature]
];
$businessSignature = [
'dbaName',
'legalName',
'taxId',
['address' => $addressSignature]
];
$fundingSignature = [
'routingNumber',
'accountNumber',
'destination',
'email',
'mobilePhone',
'descriptor',
];
return [
'id',
'tosAccepted',
'masterMerchantAccountId',
['individual' => $individualSignature],
['funding' => $fundingSignature],
['business' => $businessSignature]
];
}
public static function createDeprecatedSignature()
{
$applicantDetailsAddressSignature = ['streetAddress', 'postalCode', 'locality', 'region'];
$applicantDetailsSignature = [
'companyName',
'firstName',
'lastName',
'email',
'phone',
'dateOfBirth',
'ssn',
'taxId',
'routingNumber',
'accountNumber',
['address' => $applicantDetailsAddressSignature]
];
return [
['applicantDetails' => $applicantDetailsSignature],
'id',
'tosAccepted',
'masterMerchantAccountId'
];
}
public function _doCreate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
private function _doUpdate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->put($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
private function _verifyGatewayResponse($response)
{
if (isset($response['response'])) {
$response = $response['response'];
}
if (isset($response['merchantAccount'])) {
// return a populated instance of merchantAccount
return new Result\Successful(
MerchantAccount::factory($response['merchantAccount'])
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else {
throw new Exception\Unexpected(
"Expected merchant account or apiErrorResponse"
);
}
}
}
class_alias('Braintree\MerchantAccountGateway', 'Braintree_MerchantAccountGateway');
lib/Braintree/SubscriptionGateway.php 0000644 00000015762 15210163246 0013757 0 ustar 00 == More information ==
*
* For more detailed information on Subscriptions, see {@link http://www.braintreepayments.com/gateway/subscription-api http://www.braintreepaymentsolutions.com/gateway/subscription-api}
*
* PHP Version 5
*
* @package Braintree
* @copyright 2015 Braintree, a division of PayPal, Inc.
*/
class SubscriptionGateway
{
private $_gateway;
private $_config;
private $_http;
public function __construct($gateway)
{
$this->_gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
public function create($attributes)
{
Util::verifyKeys(self::_createSignature(), $attributes);
$path = $this->_config->merchantPath() . '/subscriptions';
$response = $this->_http->post($path, ['subscription' => $attributes]);
return $this->_verifyGatewayResponse($response);
}
public function find($id)
{
$this->_validateId($id);
try {
$path = $this->_config->merchantPath() . '/subscriptions/' . $id;
$response = $this->_http->get($path);
return Subscription::factory($response['subscription']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound('subscription with id ' . $id . ' not found');
}
}
public function search($query)
{
$criteria = [];
foreach ($query as $term) {
$criteria[$term->name] = $term->toparam();
}
$path = $this->_config->merchantPath() . '/subscriptions/advanced_search_ids';
$response = $this->_http->post($path, ['search' => $criteria]);
$pager = [
'object' => $this,
'method' => 'fetch',
'methodArgs' => [$query]
];
return new ResourceCollection($response, $pager);
}
public function fetch($query, $ids)
{
$criteria = [];
foreach ($query as $term) {
$criteria[$term->name] = $term->toparam();
}
$criteria["ids"] = SubscriptionSearch::ids()->in($ids)->toparam();
$path = $this->_config->merchantPath() . '/subscriptions/advanced_search';
$response = $this->_http->post($path, ['search' => $criteria]);
return Util::extractAttributeAsArray(
$response['subscriptions'],
'subscription'
);
}
public function update($subscriptionId, $attributes)
{
Util::verifyKeys(self::_updateSignature(), $attributes);
$path = $this->_config->merchantPath() . '/subscriptions/' . $subscriptionId;
$response = $this->_http->put($path, ['subscription' => $attributes]);
return $this->_verifyGatewayResponse($response);
}
public function retryCharge($subscriptionId, $amount = null)
{
$transaction_params = ['type' => Transaction::SALE,
'subscriptionId' => $subscriptionId];
if (isset($amount)) {
$transaction_params['amount'] = $amount;
}
$path = $this->_config->merchantPath() . '/transactions';
$response = $this->_http->post($path, ['transaction' => $transaction_params]);
return $this->_verifyGatewayResponse($response);
}
public function cancel($subscriptionId)
{
$path = $this->_config->merchantPath() . '/subscriptions/' . $subscriptionId . '/cancel';
$response = $this->_http->put($path);
return $this->_verifyGatewayResponse($response);
}
private static function _createSignature()
{
return array_merge(
[
'billingDayOfMonth',
'firstBillingDate',
'createdAt',
'updatedAt',
'id',
'merchantAccountId',
'neverExpires',
'numberOfBillingCycles',
'paymentMethodToken',
'paymentMethodNonce',
'planId',
'price',
'trialDuration',
'trialDurationUnit',
'trialPeriod',
['descriptor' => ['name', 'phone', 'url']],
['options' => ['doNotInheritAddOnsOrDiscounts', 'startImmediately']],
],
self::_addOnDiscountSignature()
);
}
private static function _updateSignature()
{
return array_merge(
[
'merchantAccountId', 'numberOfBillingCycles', 'paymentMethodToken', 'planId',
'paymentMethodNonce', 'id', 'neverExpires', 'price',
['descriptor' => ['name', 'phone', 'url']],
['options' => ['prorateCharges', 'replaceAllAddOnsAndDiscounts', 'revertSubscriptionOnProrationFailure']],
],
self::_addOnDiscountSignature()
);
}
private static function _addOnDiscountSignature()
{
return [
[
'addOns' => [
['add' => ['amount', 'inheritedFromId', 'neverExpires', 'numberOfBillingCycles', 'quantity']],
['update' => ['amount', 'existingId', 'neverExpires', 'numberOfBillingCycles', 'quantity']],
['remove' => ['_anyKey_']],
]
],
[
'discounts' => [
['add' => ['amount', 'inheritedFromId', 'neverExpires', 'numberOfBillingCycles', 'quantity']],
['update' => ['amount', 'existingId', 'neverExpires', 'numberOfBillingCycles', 'quantity']],
['remove' => ['_anyKey_']],
]
]
];
}
/**
* @ignore
*/
private function _validateId($id = null) {
if (empty($id)) {
throw new InvalidArgumentException(
'expected subscription id to be set'
);
}
if (!preg_match('/^[0-9A-Za-z_-]+$/', $id)) {
throw new InvalidArgumentException(
$id . ' is an invalid subscription id.'
);
}
}
/**
* @ignore
*/
private function _verifyGatewayResponse($response)
{
if (isset($response['subscription'])) {
return new Result\Successful(
Subscription::factory($response['subscription'])
);
} else if (isset($response['transaction'])) {
// return a populated instance of Transaction, for subscription retryCharge
return new Result\Successful(
Transaction::factory($response['transaction'])
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else {
throw new Exception\Unexpected(
"Expected subscription, transaction, or apiErrorResponse"
);
}
}
}
class_alias('Braintree\SubscriptionGateway', 'Braintree_SubscriptionGateway');
lib/Braintree/PaymentMethodNonceGateway.php 0000644 00000003205 15210163246 0015021 0 ustar 00 == More information ==
*
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
*/
class PaymentMethodNonceGateway
{
private $_gateway;
private $_config;
private $_http;
public function __construct($gateway)
{
$this->_gateway = $gateway;
$this->_config = $gateway->config;
$this->_http = new Http($gateway->config);
}
public function create($token)
{
$subPath = '/payment_methods/' . $token . '/nonces';
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath);
return new Result\Successful(
PaymentMethodNonce::factory($response['paymentMethodNonce']),
"paymentMethodNonce"
);
}
/**
* @access public
*
*/
public function find($nonce)
{
try {
$path = $this->_config->merchantPath() . '/payment_method_nonces/' . $nonce;
$response = $this->_http->get($path);
return PaymentMethodNonce::factory($response['paymentMethodNonce']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'payment method nonce with id ' . $nonce . ' not found'
);
}
}
}
class_alias('Braintree\PaymentMethodNonceGateway', 'Braintree_PaymentMethodNonceGateway');
lib/Braintree/Http.php 0000644 00000014246 15210163246 0010664 0 ustar 00 _config = $config;
}
public function delete($path)
{
$response = $this->_doRequest('DELETE', $path);
if($response['status'] === 200) {
return true;
} else {
Util::throwStatusCodeException($response['status']);
}
}
public function get($path)
{
$response = $this->_doRequest('GET', $path);
if ($response['status'] === 200) {
return Xml::buildArrayFromXml($response['body']);
} else {
Util::throwStatusCodeException($response['status']);
}
}
public function post($path, $params = null)
{
$response = $this->_doRequest('POST', $path, $this->_buildXml($params));
$responseCode = $response['status'];
if($responseCode === 200 || $responseCode === 201 || $responseCode === 422 || $responseCode == 400) {
return Xml::buildArrayFromXml($response['body']);
} else {
Util::throwStatusCodeException($responseCode);
}
}
public function put($path, $params = null)
{
$response = $this->_doRequest('PUT', $path, $this->_buildXml($params));
$responseCode = $response['status'];
if($responseCode === 200 || $responseCode === 201 || $responseCode === 422 || $responseCode == 400) {
return Xml::buildArrayFromXml($response['body']);
} else {
Util::throwStatusCodeException($responseCode);
}
}
private function _buildXml($params)
{
return empty($params) ? null : Xml::buildXmlFromArray($params);
}
private function _getHeaders()
{
return [
'Accept: application/xml',
'Content-Type: application/xml',
];
}
private function _getAuthorization()
{
if ($this->_useClientCredentials) {
return [
'user' => $this->_config->getClientId(),
'password' => $this->_config->getClientSecret(),
];
} else if ($this->_config->isAccessToken()) {
return [
'token' => $this->_config->getAccessToken(),
];
} else {
return [
'user' => $this->_config->getPublicKey(),
'password' => $this->_config->getPrivateKey(),
];
}
}
public function useClientCredentials()
{
$this->_useClientCredentials = true;
}
private function _doRequest($httpVerb, $path, $requestBody = null)
{
return $this->_doUrlRequest($httpVerb, $this->_config->baseUrl() . $path, $requestBody);
}
public function _doUrlRequest($httpVerb, $url, $requestBody = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_TIMEOUT, $this->_config->timeout());
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $httpVerb);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
$headers = $this->_getHeaders($curl);
$headers[] = 'User-Agent: Braintree PHP Library ' . Version::get();
$headers[] = 'X-ApiVersion: ' . Configuration::API_VERSION;
$authorization = $this->_getAuthorization();
if (isset($authorization['user'])) {
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $authorization['user'] . ':' . $authorization['password']);
} else if (isset($authorization['token'])) {
$headers[] = 'Authorization: Bearer ' . $authorization['token'];
}
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($curl, CURLOPT_VERBOSE, true);
if ($this->_config->sslOn()) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_CAINFO, $this->getCaFile());
}
if(!empty($requestBody)) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody);
}
if($this->_config->isUsingProxy()) {
$proxyHost = $this->_config->getProxyHost();
$proxyPort = $this->_config->getProxyPort();
$proxyType = $this->_config->getProxyType();
$proxyUser = $this->_config->getProxyUser();
$proxyPwd= $this->_config->getProxyPassword();
curl_setopt($curl, CURLOPT_PROXY, $proxyHost . ':' . $proxyPort);
if(!empty($proxyType)) {
curl_setopt($curl, CURLOPT_PROXYTYPE, $proxyType);
}
if($this->_config->isAuthenticatedProxy()) {
curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyUser . ':' . $proxyPwd);
}
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
$httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error_code = curl_errno($curl);
if ($error_code == 28 && $httpStatus == 0) {
throw new Exception\Timeout();
}
curl_close($curl);
if ($this->_config->sslOn()) {
if ($httpStatus == 0) {
throw new Exception\SSLCertificate();
}
}
return ['status' => $httpStatus, 'body' => $response];
}
private function getCaFile()
{
static $memo;
if ($memo === null) {
$caFile = $this->_config->caFile();
if (substr($caFile, 0, 7) !== 'phar://') {
return $caFile;
}
$extractedCaFile = sys_get_temp_dir() . '/api_braintreegateway_com.ca.crt';
if (!file_exists($extractedCaFile) || sha1_file($extractedCaFile) != sha1_file($caFile)) {
if (!copy($caFile, $extractedCaFile)) {
throw new Exception\SSLCaFileNotFound();
}
}
$memo = $extractedCaFile;
}
return $memo;
}
}
class_alias('Braintree\Http', 'Braintree_Http');
lib/Braintree/OAuthGateway.php 0000644 00000007611 15210163246 0012305 0 ustar 00 _gateway = $gateway;
$this->_config = $gateway->config;
$this->_http = new Http($gateway->config);
$this->_http->useClientCredentials();
$this->_config->assertHasClientCredentials();
}
public function createTokenFromCode($params)
{
$params['grantType'] = "authorization_code";
return $this->_createToken($params);
}
public function createTokenFromRefreshToken($params)
{
$params['grantType'] = "refresh_token";
return $this->_createToken($params);
}
public function revokeAccessToken($accessToken)
{
$params = ['token' => $accessToken];
$response = $this->_http->post('/oauth/revoke_access_token', $params);
return $this->_verifyGatewayResponse($response);
}
private function _createToken($params)
{
$params = ['credentials' => $params];
$response = $this->_http->post('/oauth/access_tokens', $params);
return $this->_verifyGatewayResponse($response);
}
private function _verifyGatewayResponse($response)
{
if (isset($response['credentials'])) {
$result = new Result\Successful(
OAuthCredentials::factory($response['credentials'])
);
return $this->_mapSuccess($result);
} else if (isset($response['result'])) {
$result = new Result\Successful(
OAuthResult::factory($response['result'])
);
return $this->_mapAccessTokenRevokeSuccess($result);
} else if (isset($response['apiErrorResponse'])) {
$result = new Result\Error($response['apiErrorResponse']);
return $this->_mapError($result);
} else {
throw new Exception\Unexpected(
"Expected credentials or apiErrorResponse"
);
}
}
public function _mapError($result)
{
$error = $result->errors->deepAll()[0];
if ($error->code == Error\Codes::OAUTH_INVALID_GRANT) {
$result->error = 'invalid_grant';
} else if ($error->code == Error\Codes::OAUTH_INVALID_CREDENTIALS) {
$result->error = 'invalid_credentials';
} else if ($error->code == Error\Codes::OAUTH_INVALID_SCOPE) {
$result->error = 'invalid_scope';
}
$result->errorDescription = explode(': ', $error->message)[1];
return $result;
}
public function _mapAccessTokenRevokeSuccess($result)
{
$result->revocationResult = $result->success;
return $result;
}
public function _mapSuccess($result)
{
$credentials = $result->credentials;
$result->accessToken = $credentials->accessToken;
$result->refreshToken = $credentials->refreshToken;
$result->tokenType = $credentials->tokenType;
$result->expiresAt = $credentials->expiresAt;
return $result;
}
public function connectUrl($params = [])
{
$query = Util::camelCaseToDelimiterArray($params, '_');
$query['client_id'] = $this->_config->getClientId();
$queryString = preg_replace('/\%5B\d+\%5D/', '%5B%5D', http_build_query($query));
$url = $this->_config->baseUrl() . '/oauth/connect?' . $queryString;
return $url . '&signature=' . $this->computeSignature($url) . '&algorithm=SHA256';
}
public function computeSignature($url)
{
$key = hash('sha256', $this->_config->getClientSecret(), true);
return hash_hmac('sha256', $url, $key);
}
}
class_alias('Braintree\OAuthGateway', 'Braintree_OAuthGateway');
lib/Braintree/PaymentMethodGateway.php 0000644 00000024321 15210163246 0014040 0 ustar 00 == More information ==
*
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
*/
class PaymentMethodGateway
{
private $_gateway;
private $_config;
private $_http;
public function __construct($gateway)
{
$this->_gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
public function create($attribs)
{
Util::verifyKeys(self::createSignature(), $attribs);
return $this->_doCreate('/payment_methods', ['payment_method' => $attribs]);
}
/**
* find a PaymentMethod by token
*
* @param string $token payment method unique id
* @return CreditCard|PayPalAccount
* @throws Exception\NotFound
*/
public function find($token)
{
$this->_validateId($token);
try {
$path = $this->_config->merchantPath() . '/payment_methods/any/' . $token;
$response = $this->_http->get($path);
if (isset($response['creditCard'])) {
return CreditCard::factory($response['creditCard']);
} else if (isset($response['paypalAccount'])) {
return PayPalAccount::factory($response['paypalAccount']);
} else if (isset($response['coinbaseAccount'])) {
return CoinbaseAccount::factory($response['coinbaseAccount']);
} else if (isset($response['applePayCard'])) {
return ApplePayCard::factory($response['applePayCard']);
} else if (isset($response['androidPayCard'])) {
return AndroidPayCard::factory($response['androidPayCard']);
} else if (isset($response['amexExpressCheckoutCard'])) {
return AmexExpressCheckoutCard::factory($response['amexExpressCheckoutCard']);
} else if (isset($response['europeBankAccount'])) {
return EuropeBankAccount::factory($response['europeBankAccount']);
} else if (isset($response['usBankAccount'])) {
return UsBankAccount::factory($response['usBankAccount']);
} else if (isset($response['venmoAccount'])) {
return VenmoAccount::factory($response['venmoAccount']);
} else if (is_array($response)) {
return UnknownPaymentMethod::factory($response);
}
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'payment method with token ' . $token . ' not found'
);
}
}
public function update($token, $attribs)
{
Util::verifyKeys(self::updateSignature(), $attribs);
return $this->_doUpdate('/payment_methods/any/' . $token, ['payment_method' => $attribs]);
}
public function delete($token)
{
$this->_validateId($token);
$path = $this->_config->merchantPath() . '/payment_methods/any/' . $token;
$this->_http->delete($path);
return new Result\Successful();
}
public function grant($sharedPaymentMethodToken, $attribs=[])
{
if (is_bool($attribs) === true) {
$attribs = ['allow_vaulting' => $attribs];
}
$options = [ 'shared_payment_method_token' => $sharedPaymentMethodToken ];
return $this->_doCreate(
'/payment_methods/grant',
[
'payment_method' => array_merge($attribs, $options)
]
);
}
public function revoke($sharedPaymentMethodToken)
{
return $this->_doCreate(
'/payment_methods/revoke',
[
'payment_method' => [
'shared_payment_method_token' => $sharedPaymentMethodToken
]
]
);
}
private static function baseSignature()
{
$billingAddressSignature = AddressGateway::createSignature();
$optionsSignature = [
'failOnDuplicatePaymentMethod',
'makeDefault',
'verificationMerchantAccountId',
'verifyCard',
'verificationAmount'
];
return [
'billingAddressId',
'cardholderName',
'cvv',
'deviceData',
'expirationDate',
'expirationMonth',
'expirationYear',
'number',
'paymentMethodNonce',
'token',
['options' => $optionsSignature],
['billingAddress' => $billingAddressSignature]
];
}
public static function createSignature()
{
$signature = array_merge(self::baseSignature(), ['customerId']);
return $signature;
}
public static function updateSignature()
{
$billingAddressSignature = AddressGateway::updateSignature();
array_push($billingAddressSignature, [
'options' => [
'updateExisting'
]
]);
$signature = array_merge(self::baseSignature(), [
'deviceSessionId',
'venmoSdkPaymentMethodCode',
'fraudMerchantId',
['billingAddress' => $billingAddressSignature]
]);
return $signature;
}
/**
* sends the create request to the gateway
*
* @ignore
* @param string $subPath
* @param array $params
* @return mixed
*/
public function _doCreate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* sends the update request to the gateway
*
* @ignore
* @param string $subPath
* @param array $params
* @return mixed
*/
public function _doUpdate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->put($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* generic method for validating incoming gateway responses
*
* creates a new CreditCard or PayPalAccount object
* and encapsulates it inside a Result\Successful object, or
* encapsulates a Errors object inside a Result\Error
* alternatively, throws an Unexpected exception if the response is invalid.
*
* @ignore
* @param array $response gateway response values
* @return Result\Successful|Result\Error
* @throws Exception\Unexpected
*/
private function _verifyGatewayResponse($response)
{
if (isset($response['creditCard'])) {
return new Result\Successful(
CreditCard::factory($response['creditCard']),
'paymentMethod'
);
} else if (isset($response['paypalAccount'])) {
return new Result\Successful(
PayPalAccount::factory($response['paypalAccount']),
"paymentMethod"
);
} else if (isset($response['coinbaseAccount'])) {
return new Result\Successful(
CoinbaseAccount::factory($response['coinbaseAccount']),
"paymentMethod"
);
} else if (isset($response['applePayCard'])) {
return new Result\Successful(
ApplePayCard::factory($response['applePayCard']),
"paymentMethod"
);
} else if (isset($response['androidPayCard'])) {
return new Result\Successful(
AndroidPayCard::factory($response['androidPayCard']),
"paymentMethod"
);
} else if (isset($response['amexExpressCheckoutCard'])) {
return new Result\Successful(
AmexExpressCheckoutCard::factory($response['amexExpressCheckoutCard']),
"paymentMethod"
);
} else if (isset($response['europeBankAccount'])) {
return new Result\Successful(
EuropeBankAccount::factory($response['europeBankAccount']),
"paymentMethod"
);
} else if (isset($response['usBankAccount'])) {
return new Result\Successful(
UsBankAccount::factory($response['usBankAccount']),
"paymentMethod"
);
} else if (isset($response['venmoAccount'])) {
return new Result\Successful(
VenmoAccount::factory($response['venmoAccount']),
"paymentMethod"
);
} else if (isset($response['paymentMethodNonce'])) {
return new Result\Successful(
PaymentMethodNonce::factory($response['paymentMethodNonce']),
"paymentMethodNonce"
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else if (is_array($response)) {
return new Result\Successful(
UnknownPaymentMethod::factory($response),
"paymentMethod"
);
} else {
throw new Exception\Unexpected(
'Expected payment method or apiErrorResponse'
);
}
}
/**
* verifies that a valid payment method identifier is being used
* @ignore
* @param string $identifier
* @param Optional $string $identifierType type of identifier supplied, default 'token'
* @throws InvalidArgumentException
*/
private function _validateId($identifier = null, $identifierType = 'token')
{
if (empty($identifier)) {
throw new InvalidArgumentException(
'expected payment method id to be set'
);
}
if (!preg_match('/^[0-9A-Za-z_-]+$/', $identifier)) {
throw new InvalidArgumentException(
$identifier . ' is an invalid payment method ' . $identifierType . '.'
);
}
}
}
class_alias('Braintree\PaymentMethodGateway', 'Braintree_PaymentMethodGateway');
lib/Braintree/AddOnGateway.php 0000644 00000001670 15210163246 0012251 0 ustar 00 _gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
/**
*
* @return AddOn[]
*/
public function all()
{
$path = $this->_config->merchantPath() . '/add_ons';
$response = $this->_http->get($path);
$addOns = ["addOn" => $response['addOns']];
return Util::extractAttributeAsArray(
$addOns,
'addOn'
);
}
}
class_alias('Braintree\AddOnGateway', 'Braintree_AddOnGateway');
lib/Braintree/Test/Nonces.php 0000644 00000007327 15210163246 0012113 0 ustar 00 '378734493671000',
'Discover' => '6011000990139424',
'MasterCard' => '5105105105105100',
'Visa' => '4000111111111115',
];
public static $amexPayWithPoints = [
'Success' => "371260714673002",
'IneligibleCard' => "378267515471109",
'InsufficientPoints' => "371544868764018",
];
public static function getAll()
{
return array_merge(
self::$amExes,
self::$discoverCards,
self::$masterCards,
self::$visas
);
}
}
class_alias('Braintree\Test\CreditCardNumbers', 'Braintree_Test_CreditCardNumbers');
lib/Braintree/Test/Transaction.php 0000644 00000003411 15210163246 0013141 0 ustar 00 testing()->settle($transactionId);
}
/**
* settlement confirm a transaction by id in sandbox
*
* @param string $id transaction id
* @param Configuration $config gateway config
* @return Transaction
*/
public static function settlementConfirm($transactionId)
{
return Configuration::gateway()->testing()->settlementConfirm($transactionId);
}
/**
* settlement decline a transaction by id in sandbox
*
* @param string $id transaction id
* @param Configuration $config gateway config
* @return Transaction
*/
public static function settlementDecline($transactionId)
{
return Configuration::gateway()->testing()->settlementDecline($transactionId);
}
/**
* settlement pending a transaction by id in sandbox
*
* @param string $id transaction id
* @param Configuration $config gateway config
* @return Transaction
*/
public static function settlementPending($transactionId)
{
return Configuration::gateway()->testing()->settlementPending($transactionId);
}
}
class_alias('Braintree\Test\Transaction', 'Braintree_Test_Transaction');
lib/Braintree/Test/TransactionAmounts.php 0000644 00000001006 15210163246 0014506 0 ustar 00 _attributes = $attributes;
}
public static function factory($attributes)
{
$instance = new self();
$instance->_initialize($attributes);
return $instance;
}
public function __toString() {
return get_called_class() . '[' . Util::attributesToString($this->_attributes) . ']';
}
}
class_alias('Braintree\Modification', 'Braintree_Modification');
lib/Braintree/Xml.php 0000644 00000001317 15210163246 0010500 0 ustar 00 key = $key;
$this->digest = $digest;
}
public function sign($payload)
{
return $this->hash($payload) . "|" . $payload;
}
public function hash($data)
{
return call_user_func($this->digest, $this->key, $data);
}
}
class_alias('Braintree\SignatureService', 'Braintree_SignatureService');
lib/Braintree/AddOn.php 0000644 00000001046 15210163246 0010724 0 ustar 00 _initialize($attributes);
return $instance;
}
/**
* static methods redirecting to gateway
*
* @return AddOn[]
*/
public static function all()
{
return Configuration::gateway()->addOn()->all();
}
}
class_alias('Braintree\AddOn', 'Braintree_AddOn');
lib/Braintree/Address.php 0000644 00000007714 15210163246 0011334 0 ustar 00 id === $other->id && $this->customerId === $other->customerId);
}
/**
* create a printable representation of the object as:
* ClassName[property=value, property=value]
* @ignore
* @return string
*/
public function __toString()
{
return __CLASS__ . '[' .
Util::attributesToString($this->_attributes) . ']';
}
/**
* sets instance properties from an array of values
*
* @ignore
* @access protected
* @param array $addressAttribs array of address data
* @return void
*/
protected function _initialize($addressAttribs)
{
// set the attributes
$this->_attributes = $addressAttribs;
}
/**
* factory method: returns an instance of Address
* to the requesting method, with populated properties
* @ignore
* @return Address
*/
public static function factory($attributes)
{
$instance = new self();
$instance->_initialize($attributes);
return $instance;
}
// static methods redirecting to gateway
/**
*
* @param array $attribs
* @return Address
*/
public static function create($attribs)
{
return Configuration::gateway()->address()->create($attribs);
}
/**
*
* @param array $attribs
* @return Address
*/
public static function createNoValidate($attribs)
{
return Configuration::gateway()->address()->createNoValidate($attribs);
}
/**
*
* @param Customer|int $customerOrId
* @param int $addressId
* @throws InvalidArgumentException
* @return Result\Successful
*/
public static function delete($customerOrId = null, $addressId = null)
{
return Configuration::gateway()->address()->delete($customerOrId, $addressId);
}
/**
*
* @param Customer|int $customerOrId
* @param int $addressId
* @throws Exception\NotFound
* @return Address
*/
public static function find($customerOrId, $addressId)
{
return Configuration::gateway()->address()->find($customerOrId, $addressId);
}
/**
*
* @param Customer|int $customerOrId
* @param int $addressId
* @param array $attributes
* @throws Exception\Unexpected
* @return Result\Successful|Result\Error
*/
public static function update($customerOrId, $addressId, $attributes)
{
return Configuration::gateway()->address()->update($customerOrId, $addressId, $attributes);
}
public static function updateNoValidate($customerOrId, $addressId, $attributes)
{
return Configuration::gateway()->address()->updateNoValidate($customerOrId, $addressId, $attributes);
}
}
class_alias('Braintree\Address', 'Braintree_Address');
lib/Braintree/AmexExpressCheckoutCard.php 0000644 00000004461 15210163246 0014467 0 ustar 00 == More information ==
*
* See {@link https://developers.braintreepayments.com/javascript+php}82621
* Transaction::saleNoValidate(array(
* 'amount' => '100.00',
* 'creditCard' => array(
* 'number' => '5105105105105100',
* 'expirationDate' => '05/12',
* ),
* ));
*
*
* Full example:
*
* Transaction::saleNoValidate(array(
* 'amount' => '100.00',
* 'orderId' => '123',
* 'channel' => 'MyShoppingCardProvider',
* 'creditCard' => array(
* // if token is omitted, the gateway will generate a token
* 'token' => 'credit_card_123',
* 'number' => '5105105105105100',
* 'expirationDate' => '05/2011',
* 'cvv' => '123',
* ),
* 'customer' => array(
* // if id is omitted, the gateway will generate an id
* 'id' => 'customer_123',
* 'firstName' => 'Dan',
* 'lastName' => 'Smith',
* 'company' => 'Braintree',
* 'email' => 'dan@example.com',
* 'phone' => '419-555-1234',
* 'fax' => '419-555-1235',
* 'website' => 'http://braintreepayments.com'
* ),
* 'billing' => array(
* 'firstName' => 'Carl',
* 'lastName' => 'Jones',
* 'company' => 'Braintree',
* 'streetAddress' => '123 E Main St',
* 'extendedAddress' => 'Suite 403',
* 'locality' => 'Chicago',
* 'region' => 'IL',
* 'postalCode' => '60622',
* 'countryName' => 'United States of America'
* ),
* 'shipping' => array(
* 'firstName' => 'Andrew',
* 'lastName' => 'Mason',
* 'company' => 'Braintree',
* 'streetAddress' => '456 W Main St',
* 'extendedAddress' => 'Apt 2F',
* 'locality' => 'Bartlett',
* 'region' => 'IL',
* 'postalCode' => '60103',
* 'countryName' => 'United States of America'
* ),
* 'customFields' => array(
* 'birthdate' => '11/13/1954'
* )
* )
*
*
* == Storing in the Vault ==
*
* The customer and credit card information used for
* a transaction can be stored in the vault by setting
* transaction[options][storeInVault] to true.
*
* $transaction = Transaction::saleNoValidate(array(
* 'customer' => array(
* 'firstName' => 'Adam',
* 'lastName' => 'Williams'
* ),
* 'creditCard' => array(
* 'number' => '5105105105105100',
* 'expirationDate' => '05/2012'
* ),
* 'options' => array(
* 'storeInVault' => true
* )
* ));
*
* echo $transaction->customerDetails->id
* // '865534'
* echo $transaction->creditCardDetails->token
* // '6b6m'
*
*
* To also store the billing address in the vault, pass the
* addBillingAddressToPaymentMethod option.
*
* Transaction.saleNoValidate(array(
* ...
* 'options' => array(
* 'storeInVault' => true
* 'addBillingAddressToPaymentMethod' => true
* )
* ));
*
*
* == Submitting for Settlement==
*
* This can only be done when the transction's
* status is authorized. If amount is not specified,
* the full authorized amount will be settled. If you would like to settle
* less than the full authorized amount, pass the desired amount.
* You cannot settle more than the authorized amount.
*
* A transaction can be submitted for settlement when created by setting
* $transaction[options][submitForSettlement] to true.
*
*
* $transaction = Transaction::saleNoValidate(array(
* 'amount' => '100.00',
* 'creditCard' => array(
* 'number' => '5105105105105100',
* 'expirationDate' => '05/2012'
* ),
* 'options' => array(
* 'submitForSettlement' => true
* )
* ));
*
*
* == More information ==
*
* For more detailed information on Transactions, see {@link http://www.braintreepayments.com/gateway/transaction-api http://www.braintreepaymentsolutions.com/gateway/transaction-api}
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
*
* @property-read string $avsErrorResponseCode
* @property-read string $avsPostalCodeResponseCode
* @property-read string $avsStreetAddressResponseCode
* @property-read string $cvvResponseCode
* @property-read string $id transaction id
* @property-read string $amount transaction amount
* @property-read Braintree\Transaction\AddressDetails $billingDetails transaction billing address
* @property-read string $createdAt transaction created timestamp
* @property-read Braintree\ApplePayCardDetails $applePayCardDetails transaction Apple Pay card info
* @property-read Braintree\AndroidPayCardDetails $androidPayCardDetails transaction Android Pay card info
* @property-read Braintree\AmexExpressCheckoutCardDetails $amexExpressCheckoutCardDetails transaction Amex Express Checkout card info
* @property-read Braintree\CreditCardDetails $creditCardDetails transaction credit card info
* @property-read Braintree\CoinbaseDetails $coinbaseDetails transaction Coinbase account info
* @property-read Braintree\PayPalDetails $paypalDetails transaction paypal account info
* @property-read Braintree\Transaction\CustomerDetails $customerDetails transaction customer info
* @property-read Braintree\VenmoAccount $venmoAccountDetails transaction Venmo Account info
* @property-read array $customFields custom fields passed with the request
* @property-read string $processorResponseCode gateway response code
* @property-read string $additionalProcessorResponse raw response from processor
* @property-read Braintree\Transaction\AddressDetails $shippingDetails transaction shipping address
* @property-read string $status transaction status
* @property-read array $statusHistory array of StatusDetails objects
* @property-read string $type transaction type
* @property-read string $updatedAt transaction updated timestamp
* @property-read Braintree\Disbursement $disbursementDetails populated when transaction is disbursed
* @property-read Braintree\Dispute $disputes populated when transaction is disputed
*
*/
class Transaction extends Base
{
// Transaction Status
const AUTHORIZATION_EXPIRED = 'authorization_expired';
const AUTHORIZING = 'authorizing';
const AUTHORIZED = 'authorized';
const GATEWAY_REJECTED = 'gateway_rejected';
const FAILED = 'failed';
const PROCESSOR_DECLINED = 'processor_declined';
const SETTLED = 'settled';
const SETTLING = 'settling';
const SUBMITTED_FOR_SETTLEMENT = 'submitted_for_settlement';
const VOIDED = 'voided';
const UNRECOGNIZED = 'unrecognized';
const SETTLEMENT_DECLINED = 'settlement_declined';
const SETTLEMENT_PENDING = 'settlement_pending';
const SETTLEMENT_CONFIRMED = 'settlement_confirmed';
// Transaction Escrow Status
const ESCROW_HOLD_PENDING = 'hold_pending';
const ESCROW_HELD = 'held';
const ESCROW_RELEASE_PENDING = 'release_pending';
const ESCROW_RELEASED = 'released';
const ESCROW_REFUNDED = 'refunded';
// Transaction Types
const SALE = 'sale';
const CREDIT = 'credit';
// Transaction Created Using
const FULL_INFORMATION = 'full_information';
const TOKEN = 'token';
// Transaction Sources
const API = 'api';
const CONTROL_PANEL = 'control_panel';
const RECURRING = 'recurring';
// Gateway Rejection Reason
const AVS = 'avs';
const AVS_AND_CVV = 'avs_and_cvv';
const CVV = 'cvv';
const DUPLICATE = 'duplicate';
const FRAUD = 'fraud';
const THREE_D_SECURE = 'three_d_secure';
const APPLICATION_INCOMPLETE = 'application_incomplete';
// Industry Types
const LODGING_INDUSTRY = 'lodging';
const TRAVEL_AND_CRUISE_INDUSTRY = 'travel_cruise';
/**
* sets instance properties from an array of values
*
* @ignore
* @access protected
* @param array $transactionAttribs array of transaction data
* @return void
*/
protected function _initialize($transactionAttribs)
{
$this->_attributes = $transactionAttribs;
if (isset($transactionAttribs['applePay'])) {
$this->_set('applePayCardDetails',
new Transaction\ApplePayCardDetails(
$transactionAttribs['applePay']
)
);
}
if (isset($transactionAttribs['androidPayCard'])) {
$this->_set('androidPayCardDetails',
new Transaction\AndroidPayCardDetails(
$transactionAttribs['androidPayCard']
)
);
}
if (isset($transactionAttribs['amexExpressCheckoutCard'])) {
$this->_set('amexExpressCheckoutCardDetails',
new Transaction\AmexExpressCheckoutCardDetails(
$transactionAttribs['amexExpressCheckoutCard']
)
);
}
if (isset($transactionAttribs['venmoAccount'])) {
$this->_set('venmoAccountDetails',
new Transaction\VenmoAccountDetails(
$transactionAttribs['venmoAccount']
)
);
}
if (isset($transactionAttribs['creditCard'])) {
$this->_set('creditCardDetails',
new Transaction\CreditCardDetails(
$transactionAttribs['creditCard']
)
);
}
if (isset($transactionAttribs['coinbaseAccount'])) {
$this->_set('coinbaseDetails',
new Transaction\CoinbaseDetails(
$transactionAttribs['coinbaseAccount']
)
);
}
if (isset($transactionAttribs['europeBankAccount'])) {
$this->_set('europeBankAccount',
new Transaction\EuropeBankAccountDetails(
$transactionAttribs['europeBankAccount']
)
);
}
if (isset($transactionAttribs['usBankAccount'])) {
$this->_set('usBankAccount',
new Transaction\UsBankAccountDetails(
$transactionAttribs['usBankAccount']
)
);
}
if (isset($transactionAttribs['paypal'])) {
$this->_set('paypalDetails',
new Transaction\PayPalDetails(
$transactionAttribs['paypal']
)
);
}
if (isset($transactionAttribs['customer'])) {
$this->_set('customerDetails',
new Transaction\CustomerDetails(
$transactionAttribs['customer']
)
);
}
if (isset($transactionAttribs['billing'])) {
$this->_set('billingDetails',
new Transaction\AddressDetails(
$transactionAttribs['billing']
)
);
}
if (isset($transactionAttribs['shipping'])) {
$this->_set('shippingDetails',
new Transaction\AddressDetails(
$transactionAttribs['shipping']
)
);
}
if (isset($transactionAttribs['subscription'])) {
$this->_set('subscriptionDetails',
new Transaction\SubscriptionDetails(
$transactionAttribs['subscription']
)
);
}
if (isset($transactionAttribs['descriptor'])) {
$this->_set('descriptor',
new Descriptor(
$transactionAttribs['descriptor']
)
);
}
if (isset($transactionAttribs['disbursementDetails'])) {
$this->_set('disbursementDetails',
new DisbursementDetails($transactionAttribs['disbursementDetails'])
);
}
$disputes = [];
if (isset($transactionAttribs['disputes'])) {
foreach ($transactionAttribs['disputes'] AS $dispute) {
$disputes[] = Dispute::factory($dispute);
}
}
$this->_set('disputes', $disputes);
$statusHistory = [];
if (isset($transactionAttribs['statusHistory'])) {
foreach ($transactionAttribs['statusHistory'] AS $history) {
$statusHistory[] = new Transaction\StatusDetails($history);
}
}
$this->_set('statusHistory', $statusHistory);
$addOnArray = [];
if (isset($transactionAttribs['addOns'])) {
foreach ($transactionAttribs['addOns'] AS $addOn) {
$addOnArray[] = AddOn::factory($addOn);
}
}
$this->_set('addOns', $addOnArray);
$discountArray = [];
if (isset($transactionAttribs['discounts'])) {
foreach ($transactionAttribs['discounts'] AS $discount) {
$discountArray[] = Discount::factory($discount);
}
}
$this->_set('discounts', $discountArray);
if(isset($transactionAttribs['riskData'])) {
$this->_set('riskData', RiskData::factory($transactionAttribs['riskData']));
}
if(isset($transactionAttribs['threeDSecureInfo'])) {
$this->_set('threeDSecureInfo', ThreeDSecureInfo::factory($transactionAttribs['threeDSecureInfo']));
}
if(isset($transactionAttribs['facilitatorDetails'])) {
$this->_set('facilitatorDetails', FacilitatorDetails::factory($transactionAttribs['facilitatorDetails']));
}
}
/**
* returns a string representation of the transaction
* @return string
*/
public function __toString()
{
// array of attributes to print
$display = [
'id', 'type', 'amount', 'status',
'createdAt', 'creditCardDetails', 'customerDetails'
];
$displayAttributes = [];
foreach ($display AS $attrib) {
$displayAttributes[$attrib] = $this->$attrib;
}
return __CLASS__ . '[' .
Util::attributesToString($displayAttributes) .']';
}
public function isEqual($otherTx)
{
return $this->id === $otherTx->id;
}
public function vaultCreditCard()
{
$token = $this->creditCardDetails->token;
if (empty($token)) {
return null;
}
else {
return CreditCard::find($token);
}
}
/** @return void|Braintree\Customer */
public function vaultCustomer()
{
$customerId = $this->customerDetails->id;
if (empty($customerId)) {
return null;
}
else {
return Customer::find($customerId);
}
}
/** @return bool */
public function isDisbursed() {
return $this->disbursementDetails->isValid();
}
/**
* factory method: returns an instance of Transaction
* to the requesting method, with populated properties
*
* @ignore
* @return Transaction
*/
public static function factory($attributes)
{
$instance = new self();
$instance->_initialize($attributes);
return $instance;
}
// static methods redirecting to gateway
public static function cloneTransaction($transactionId, $attribs)
{
return Configuration::gateway()->transaction()->cloneTransaction($transactionId, $attribs);
}
public static function createFromTransparentRedirect($queryString)
{
return Configuration::gateway()->transaction()->createFromTransparentRedirect($queryString);
}
public static function createTransactionUrl()
{
return Configuration::gateway()->transaction()->createTransactionUrl();
}
public static function credit($attribs)
{
return Configuration::gateway()->transaction()->credit($attribs);
}
public static function creditNoValidate($attribs)
{
return Configuration::gateway()->transaction()->creditNoValidate($attribs);
}
public static function find($id)
{
return Configuration::gateway()->transaction()->find($id);
}
public static function sale($attribs)
{
return Configuration::gateway()->transaction()->sale($attribs);
}
public static function saleNoValidate($attribs)
{
return Configuration::gateway()->transaction()->saleNoValidate($attribs);
}
public static function search($query)
{
return Configuration::gateway()->transaction()->search($query);
}
public static function fetch($query, $ids)
{
return Configuration::gateway()->transaction()->fetch($query, $ids);
}
public static function void($transactionId)
{
return Configuration::gateway()->transaction()->void($transactionId);
}
public static function voidNoValidate($transactionId)
{
return Configuration::gateway()->transaction()->voidNoValidate($transactionId);
}
public static function submitForSettlement($transactionId, $amount = null, $attribs = [])
{
return Configuration::gateway()->transaction()->submitForSettlement($transactionId, $amount, $attribs);
}
public static function submitForSettlementNoValidate($transactionId, $amount = null, $attribs = [])
{
return Configuration::gateway()->transaction()->submitForSettlementNoValidate($transactionId, $amount, $attribs);
}
public static function updateDetails($transactionId, $attribs = [])
{
return Configuration::gateway()->transaction()->updateDetails($transactionId, $attribs);
}
public static function submitForPartialSettlement($transactionId, $amount, $attribs = [])
{
return Configuration::gateway()->transaction()->submitForPartialSettlement($transactionId, $amount, $attribs);
}
public static function holdInEscrow($transactionId)
{
return Configuration::gateway()->transaction()->holdInEscrow($transactionId);
}
public static function releaseFromEscrow($transactionId)
{
return Configuration::gateway()->transaction()->releaseFromEscrow($transactionId);
}
public static function cancelRelease($transactionId)
{
return Configuration::gateway()->transaction()->cancelRelease($transactionId);
}
public static function refund($transactionId, $amount = null)
{
return Configuration::gateway()->transaction()->refund($transactionId, $amount);
}
}
class_alias('Braintree\Transaction', 'Braintree_Transaction');
lib/Braintree/WebhookNotification.php 0000644 00000012516 15210163246 0013710 0 ustar 00 _initialize($attributes);
return $instance;
}
private static function _matchingSignature($signaturePairs)
{
foreach ($signaturePairs as $pair)
{
$components = preg_split("/\|/", $pair);
if ($components[0] == Configuration::publicKey()) {
return $components[1];
}
}
return null;
}
private static function _payloadMatches($signature, $payload)
{
$payloadSignature = Digest::hexDigestSha1(Configuration::privateKey(), $payload);
return Digest::secureCompare($signature, $payloadSignature);
}
private static function _validateSignature($signatureString, $payload)
{
$signaturePairs = preg_split("/&/", $signatureString);
$signature = self::_matchingSignature($signaturePairs);
if (!$signature) {
throw new Exception\InvalidSignature("no matching public key");
}
if (!(self::_payloadMatches($signature, $payload) || self::_payloadMatches($signature, $payload . "\n"))) {
throw new Exception\InvalidSignature("signature does not match payload - one has been modified");
}
}
protected function _initialize($attributes)
{
$this->_attributes = $attributes;
if (isset($attributes['subject']['apiErrorResponse'])) {
$wrapperNode = $attributes['subject']['apiErrorResponse'];
} else {
$wrapperNode = $attributes['subject'];
}
if (isset($wrapperNode['subscription'])) {
$this->_set('subscription', Subscription::factory($attributes['subject']['subscription']));
}
if (isset($wrapperNode['merchantAccount'])) {
$this->_set('merchantAccount', MerchantAccount::factory($wrapperNode['merchantAccount']));
}
if (isset($wrapperNode['transaction'])) {
$this->_set('transaction', Transaction::factory($wrapperNode['transaction']));
}
if (isset($wrapperNode['disbursement'])) {
$this->_set('disbursement', Disbursement::factory($wrapperNode['disbursement']));
}
if (isset($wrapperNode['partnerMerchant'])) {
$this->_set('partnerMerchant', PartnerMerchant::factory($wrapperNode['partnerMerchant']));
}
if (isset($wrapperNode['dispute'])) {
$this->_set('dispute', Dispute::factory($wrapperNode['dispute']));
}
if (isset($wrapperNode['accountUpdaterDailyReport'])) {
$this->_set('accountUpdaterDailyReport', AccountUpdaterDailyReport::factory($wrapperNode['accountUpdaterDailyReport']));
}
if (isset($wrapperNode['errors'])) {
$this->_set('errors', new Error\ValidationErrorCollection($wrapperNode['errors']));
$this->_set('message', $wrapperNode['message']);
}
}
}
class_alias('Braintree\WebhookNotification', 'Braintree_WebhookNotification');
lib/Braintree/Instance.php 0000644 00000003514 15210163246 0011505 0 ustar 00 _initializeFromArray($attributes);
}
}
/**
* returns private/nonexistent instance properties
* @access public
* @param string $name property name
* @return mixed contents of instance properties
*/
public function __get($name)
{
if (array_key_exists($name, $this->_attributes)) {
return $this->_attributes[$name];
} else {
trigger_error('Undefined property on ' . get_class($this) . ': ' . $name, E_USER_NOTICE);
return null;
}
}
/**
* used by isset() and empty()
* @access public
* @param string $name property name
* @return boolean
*/
public function __isset($name)
{
return array_key_exists($name, $this->_attributes);
}
/**
* create a printable representation of the object as:
* ClassName[property=value, property=value]
* @return string
*/
public function __toString()
{
$objOutput = Util::implodeAssociativeArray($this->_attributes);
return get_class($this) .'[' . $objOutput . ']';
}
/**
* initializes instance properties from the keys/values of an array
* @ignore
* @access protected
* @param
* $result = Customer::create(...);
* $customerErrors = $result->errors->forKey('customer')->shallowAll();
*
*/
public function shallowAll()
{
return $this->_errors->shallowAll();
}
/**
*
* @ignore
*/
public function __get($name)
{
$varName = "_$name";
return isset($this->$varName) ? $this->$varName : null;
}
/**
*
* @ignore
*/
public function __toString()
{
return sprintf('%s', $this->_errors);
}
}
class_alias('Braintree\Error\ErrorCollection', 'Braintree_Error_ErrorCollection');
lib/Braintree/Error/Codes.php 0000644 00000124544 15210163246 0012076 0 ustar 00 == More information ==
*
* For more detailed information on Validation errors, see {@link http://www.braintreepayments.com/gateway/validation-errors http://www.braintreepaymentsolutions.com/gateway/validation-errors}
*
* @package Braintree
* @subpackage Error
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
* @property-read array $errors
* @property-read array $nested
*/
class ValidationErrorCollection extends Collection
{
private $_errors = [];
private $_nested = [];
/**
* @ignore
*/
public function __construct($data)
{
foreach($data AS $key => $errorData)
// map errors to new collections recursively
if ($key == 'errors') {
foreach ($errorData AS $error) {
$this->_errors[] = new Validation($error);
}
} else {
$this->_nested[$key] = new ValidationErrorCollection($errorData);
}
}
public function deepAll()
{
$validationErrors = array_merge([], $this->_errors);
foreach($this->_nested as $nestedErrors)
{
$validationErrors = array_merge($validationErrors, $nestedErrors->deepAll());
}
return $validationErrors;
}
public function deepSize()
{
$total = sizeof($this->_errors);
foreach($this->_nested as $_nestedErrors)
{
$total = $total + $_nestedErrors->deepSize();
}
return $total;
}
public function forIndex($index)
{
return $this->forKey("index" . $index);
}
public function forKey($key)
{
return isset($this->_nested[$key]) ? $this->_nested[$key] : null;
}
public function onAttribute($attribute)
{
$matches = [];
foreach ($this->_errors AS $key => $error) {
if($error->attribute == $attribute) {
$matches[] = $error;
}
}
return $matches;
}
public function shallowAll()
{
return $this->_errors;
}
/**
*
* @ignore
*/
public function __get($name)
{
$varName = "_$name";
return isset($this->$varName) ? $this->$varName : null;
}
/**
* @ignore
*/
public function __toString()
{
$output = [];
// TODO: implement scope
if (!empty($this->_errors)) {
$output[] = $this->_inspect($this->_errors);
}
if (!empty($this->_nested)) {
foreach ($this->_nested AS $key => $values) {
$output[] = $this->_inspect($this->_nested);
}
}
return join(', ', $output);
}
/**
* @ignore
*/
private function _inspect($errors, $scope = null)
{
$eOutput = '[' . __CLASS__ . '/errors:[';
foreach($errors AS $error => $errorObj) {
$outputErrs[] = "({$errorObj->error['code']} {$errorObj->error['message']})";
}
$eOutput .= join(', ', $outputErrs) . ']]';
return $eOutput;
}
}
class_alias('Braintree\Error\ValidationErrorCollection', 'Braintree_Error_ValidationErrorCollection');
lib/Braintree/Error/Validation.php 0000644 00000003101 15210163246 0013114 0 ustar 00 == More information ==
*
* For more detailed information on Validation errors, see {@link http://www.braintreepayments.com/gateway/validation-errors http://www.braintreepaymentsolutions.com/gateway/validation-errors}
*
* @package Braintree
* @subpackage Error
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
* @property-read string $attribute
* @property-read string $code
* @property-read string $message
*/
class Validation
{
private $_attribute;
private $_code;
private $_message;
/**
* @ignore
* @param array $attributes
*/
public function __construct($attributes)
{
$this->_initializeFromArray($attributes);
}
/**
* initializes instance properties from the keys/values of an array
* @ignore
* @access protected
* @param array $attributes array of properties to set - single level
* @return void
*/
private function _initializeFromArray($attributes)
{
foreach($attributes AS $name => $value) {
$varName = "_$name";
$this->$varName = Util::delimiterToCamelCase($value, '_');
}
}
/**
*
* @ignore
*/
public function __get($name)
{
$varName = "_$name";
return isset($this->$varName) ? $this->$varName : null;
}
}
class_alias('Braintree\Error\Validation', 'Braintree_Error_Validation');
lib/Braintree/EqualityNode.php 0000644 00000000367 15210163246 0012347 0 ustar 00 searchTerms['is_not'] = strval($value);
return $this;
}
}
class_alias('Braintree\EqualityNode', 'Braintree_EqualityNode');
lib/Braintree/Dispute/TransactionDetails.php 0000644 00000001050 15210163246 0015142 0 ustar 00 == More information ==
*
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*
*/
class PaymentMethodNonce extends Base
{
// static methods redirecting to gateway
public static function create($token)
{
return Configuration::gateway()->paymentMethodNonce()->create($token);
}
public static function find($nonce)
{
return Configuration::gateway()->paymentMethodNonce()->find($nonce);
}
public static function factory($attributes)
{
$instance = new self();
$instance->_initialize($attributes);
return $instance;
}
protected function _initialize($nonceAttributes)
{
$this->_attributes = $nonceAttributes;
$this->_set('nonce', $nonceAttributes['nonce']);
$this->_set('type', $nonceAttributes['type']);
if(isset($nonceAttributes['threeDSecureInfo'])) {
$this->_set('threeDSecureInfo', ThreeDSecureInfo::factory($nonceAttributes['threeDSecureInfo']));
}
}
}
class_alias('Braintree\PaymentMethodNonce', 'Braintree_PaymentMethodNonce');
lib/Braintree/TransactionGateway.php 0000644 00000041711 15210163246 0013551 0 ustar 00 == More information ==
*
* For more detailed information on Transactions, see {@link http://www.braintreepayments.com/gateway/transaction-api http://www.braintreepaymentsolutions.com/gateway/transaction-api}
*
* @package Braintree
* @category Resources
* @copyright 2015 Braintree, a division of PayPal, Inc.
*/
class TransactionGateway
{
private $_gateway;
private $_config;
private $_http;
public function __construct($gateway)
{
$this->_gateway = $gateway;
$this->_config = $gateway->config;
$this->_config->assertHasAccessTokenOrKeys();
$this->_http = new Http($gateway->config);
}
public function cloneTransaction($transactionId, $attribs)
{
Util::verifyKeys(self::cloneSignature(), $attribs);
return $this->_doCreate('/transactions/' . $transactionId . '/clone', ['transactionClone' => $attribs]);
}
/**
* @ignore
* @access private
* @param array $attribs
* @return object
*/
private function create($attribs)
{
Util::verifyKeys(self::createSignature(), $attribs);
return $this->_doCreate('/transactions', ['transaction' => $attribs]);
}
/**
* @ignore
* @access private
* @param array $attribs
* @return object
* @throws Exception\ValidationError
*/
private function createNoValidate($attribs)
{
$result = $this->create($attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
*
* @deprecated since version 2.3.0
* @access public
* @param array $attribs
* @return object
*/
public function createFromTransparentRedirect($queryString)
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::confirm", E_USER_NOTICE);
$params = TransparentRedirect::parseAndValidateQueryString(
$queryString
);
return $this->_doCreate(
'/transactions/all/confirm_transparent_redirect_request',
['id' => $params['id']]
);
}
/**
*
* @deprecated since version 2.3.0
* @access public
* @param none
* @return string
*/
public function createTransactionUrl()
{
trigger_error("DEPRECATED: Please use TransparentRedirectRequest::url", E_USER_NOTICE);
return $this->_config->baseUrl() . $this->_config->merchantPath() .
'/transactions/all/create_via_transparent_redirect_request';
}
public static function cloneSignature()
{
return ['amount', 'channel', ['options' => ['submitForSettlement']]];
}
/**
* creates a full array signature of a valid gateway request
* @return array gateway request signature format
*/
public static function createSignature()
{
return [
'amount',
'billingAddressId',
'channel',
'customerId',
'deviceData',
'deviceSessionId',
'fraudMerchantId',
'merchantAccountId',
'orderId',
'paymentMethodNonce',
'paymentMethodToken',
'purchaseOrderNumber',
'recurring',
'serviceFeeAmount',
'sharedPaymentMethodToken',
'sharedCustomerId',
'sharedShippingAddressId',
'sharedBillingAddressId',
'shippingAddressId',
'taxAmount',
'taxExempt',
'threeDSecureToken',
'transactionSource',
'type',
'venmoSdkPaymentMethodCode',
['riskData' =>
['customerBrowser', 'customerIp', 'customer_browser', 'customer_ip']
],
['creditCard' =>
['token', 'cardholderName', 'cvv', 'expirationDate', 'expirationMonth', 'expirationYear', 'number'],
],
['customer' =>
[
'id', 'company', 'email', 'fax', 'firstName',
'lastName', 'phone', 'website'],
],
['billing' =>
[
'firstName', 'lastName', 'company', 'countryName',
'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',
'extendedAddress', 'locality', 'postalCode', 'region',
'streetAddress'],
],
['shipping' =>
[
'firstName', 'lastName', 'company', 'countryName',
'countryCodeAlpha2', 'countryCodeAlpha3', 'countryCodeNumeric',
'extendedAddress', 'locality', 'postalCode', 'region',
'streetAddress'],
],
['threeDSecurePassThru' =>
[
'eciFlag',
'cavv',
'xid'],
],
['options' =>
[
'holdInEscrow',
'storeInVault',
'storeInVaultOnSuccess',
'submitForSettlement',
'addBillingAddressToPaymentMethod',
'venmoSdkSession',
'storeShippingAddressInVault',
'payeeEmail',
['threeDSecure' =>
['required']
],
['paypal' =>
[
'payeeEmail',
'customField',
'description',
['supplementaryData' => ['_anyKey_']],
]
],
['amexRewards' =>
[
'requestId',
'points',
'currencyAmount',
'currencyIsoCode'
]
]
],
],
['customFields' => ['_anyKey_']],
['descriptor' => ['name', 'phone', 'url']],
['paypalAccount' => ['payeeEmail']],
['apple_pay_card' => ['number', 'cardholder_name', 'cryptogram', 'expiration_month', 'expiration_year']], #backwards compatibility
['applePayCard' => ['number', 'cardholderName', 'cryptogram', 'expirationMonth', 'expirationYear']],
['industry' =>
['industryType',
['data' =>
[
'folioNumber',
'checkInDate',
'checkOutDate',
'travelPackage',
'departureDate',
'lodgingCheckInDate',
'lodgingCheckOutDate',
'lodgingName',
'roomRate'
]
]
]
]
];
}
public static function submitForSettlementSignature()
{
return ['orderId', ['descriptor' => ['name', 'phone', 'url']]];
}
public static function updateDetailsSignature()
{
return ['amount', 'orderId', ['descriptor' => ['name', 'phone', 'url']]];
}
public static function refundSignature()
{
return ['amount', 'orderId'];
}
/**
*
* @access public
* @param array $attribs
* @return Result\Successful|Result\Error
*/
public function credit($attribs)
{
return $this->create(array_merge($attribs, ['type' => Transaction::CREDIT]));
}
/**
*
* @access public
* @param array $attribs
* @return Result\Successful|Result\Error
* @throws Exception\ValidationError
*/
public function creditNoValidate($attribs)
{
$result = $this->credit($attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
* @access public
* @param string id
* @return Transaction
*/
public function find($id)
{
$this->_validateId($id);
try {
$path = $this->_config->merchantPath() . '/transactions/' . $id;
$response = $this->_http->get($path);
return Transaction::factory($response['transaction']);
} catch (Exception\NotFound $e) {
throw new Exception\NotFound(
'transaction with id ' . $id . ' not found'
);
}
}
/**
* new sale
* @param array $attribs
* @return array
*/
public function sale($attribs)
{
return $this->create(array_merge(['type' => Transaction::SALE], $attribs));
}
/**
* roughly equivalent to the ruby bang method
* @access public
* @param array $attribs
* @return array
* @throws Exception\ValidationsFailed
*/
public function saleNoValidate($attribs)
{
$result = $this->sale($attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
/**
* Returns a ResourceCollection of transactions matching the search query.
*
* If query is a string, the search will be a basic search.
* If query is a hash, the search will be an advanced search.
* For more detailed information and examples, see {@link http://www.braintreepayments.com/gateway/transaction-api#searching http://www.braintreepaymentsolutions.com/gateway/transaction-api}
*
* @param mixed $query search query
* @param array $options options such as page number
* @return ResourceCollection
* @throws InvalidArgumentException
*/
public function search($query)
{
$criteria = [];
foreach ($query as $term) {
$criteria[$term->name] = $term->toparam();
}
$path = $this->_config->merchantPath() . '/transactions/advanced_search_ids';
$response = $this->_http->post($path, ['search' => $criteria]);
if (array_key_exists('searchResults', $response)) {
$pager = [
'object' => $this,
'method' => 'fetch',
'methodArgs' => [$query]
];
return new ResourceCollection($response, $pager);
} else {
throw new Exception\DownForMaintenance();
}
}
public function fetch($query, $ids)
{
$criteria = [];
foreach ($query as $term) {
$criteria[$term->name] = $term->toparam();
}
$criteria["ids"] = TransactionSearch::ids()->in($ids)->toparam();
$path = $this->_config->merchantPath() . '/transactions/advanced_search';
$response = $this->_http->post($path, ['search' => $criteria]);
if (array_key_exists('creditCardTransactions', $response)) {
return Util::extractattributeasarray(
$response['creditCardTransactions'],
'transaction'
);
} else {
throw new Exception\DownForMaintenance();
}
}
/**
* void a transaction by id
*
* @param string $id transaction id
* @return Result\Successful|Result\Error
*/
public function void($transactionId)
{
$this->_validateId($transactionId);
$path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/void';
$response = $this->_http->put($path);
return $this->_verifyGatewayResponse($response);
}
/**
*
*/
public function voidNoValidate($transactionId)
{
$result = $this->void($transactionId);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
public function submitForSettlement($transactionId, $amount = null, $attribs = [])
{
$this->_validateId($transactionId);
Util::verifyKeys(self::submitForSettlementSignature(), $attribs);
$attribs['amount'] = $amount;
$path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/submit_for_settlement';
$response = $this->_http->put($path, ['transaction' => $attribs]);
return $this->_verifyGatewayResponse($response);
}
public function submitForSettlementNoValidate($transactionId, $amount = null, $attribs = [])
{
$result = $this->submitForSettlement($transactionId, $amount, $attribs);
return Util::returnObjectOrThrowException(__CLASS__, $result);
}
public function updateDetails($transactionId, $attribs = [])
{
$this->_validateId($transactionId);
Util::verifyKeys(self::updateDetailsSignature(), $attribs);
$path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/update_details';
$response = $this->_http->put($path, ['transaction' => $attribs]);
return $this->_verifyGatewayResponse($response);
}
public function submitForPartialSettlement($transactionId, $amount, $attribs = [])
{
$this->_validateId($transactionId);
Util::verifyKeys(self::submitForSettlementSignature(), $attribs);
$attribs['amount'] = $amount;
$path = $this->_config->merchantPath() . '/transactions/'. $transactionId . '/submit_for_partial_settlement';
$response = $this->_http->post($path, ['transaction' => $attribs]);
return $this->_verifyGatewayResponse($response);
}
public function holdInEscrow($transactionId)
{
$this->_validateId($transactionId);
$path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/hold_in_escrow';
$response = $this->_http->put($path, []);
return $this->_verifyGatewayResponse($response);
}
public function releaseFromEscrow($transactionId)
{
$this->_validateId($transactionId);
$path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/release_from_escrow';
$response = $this->_http->put($path, []);
return $this->_verifyGatewayResponse($response);
}
public function cancelRelease($transactionId)
{
$this->_validateId($transactionId);
$path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/cancel_release';
$response = $this->_http->put($path, []);
return $this->_verifyGatewayResponse($response);
}
public function refund($transactionId, $amount_or_options = null)
{
self::_validateId($transactionId);
if(gettype($amount_or_options) == "array") {
$options = $amount_or_options;
} else {
$options = [
"amount" => $amount_or_options
];
}
Util::verifyKeys(self::refundSignature(), $options);
$params = ['transaction' => $options];
$path = $this->_config->merchantPath() . '/transactions/' . $transactionId . '/refund';
$response = $this->_http->post($path, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* sends the create request to the gateway
*
* @ignore
* @param var $subPath
* @param array $params
* @return mixed
*/
public function _doCreate($subPath, $params)
{
$fullPath = $this->_config->merchantPath() . $subPath;
$response = $this->_http->post($fullPath, $params);
return $this->_verifyGatewayResponse($response);
}
/**
* verifies that a valid transaction id is being used
* @ignore
* @param string transaction id
* @throws InvalidArgumentException
*/
private function _validateId($id = null) {
if (empty($id)) {
throw new InvalidArgumentException(
'expected transaction id to be set'
);
}
if (!preg_match('/^[0-9a-z]+$/', $id)) {
throw new InvalidArgumentException(
$id . ' is an invalid transaction id.'
);
}
}
/**
* generic method for validating incoming gateway responses
*
* creates a new Transaction object and encapsulates
* it inside a Result\Successful object, or
* encapsulates a Errors object inside a Result\Error
* alternatively, throws an Unexpected exception if the response is invalid.
*
* @ignore
* @param array $response gateway response values
* @return Result\Successful|Result\Error
* @throws Exception\Unexpected
*/
private function _verifyGatewayResponse($response)
{
if (isset($response['transaction'])) {
// return a populated instance of Transaction
return new Result\Successful(
Transaction::factory($response['transaction'])
);
} else if (isset($response['apiErrorResponse'])) {
return new Result\Error($response['apiErrorResponse']);
} else {
throw new Exception\Unexpected(
"Expected transaction or apiErrorResponse"
);
}
}
}
class_alias('Braintree\TransactionGateway', 'Braintree_TransactionGateway');
lib/ssl/sandbox_braintreegateway_com.ca.crt 0000644 00000002321 15210163246 0015116 0 ustar 00 Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
-----BEGIN CERTIFICATE-----
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
-----END CERTIFICATE-----
lib/ssl/www_braintreegateway_com.ca.crt 0000644 00000027415 15210163246 0014317 0 ustar 00 Subject: O=Entrust.net, OU=www.entrust.net/GCCA_CPS incorp. by ref. (limits liab.), OU=(c) 2000 Entrust.net Limited, CN=Entrust.net Client Certification Authority
-----BEGIN CERTIFICATE-----
MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UE
ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NB
X0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
HChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAy
MDcxNjE2NDBaFw0yMDAyMDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0
Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29y
cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg
RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xp
ZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7NySpj10InJrWPNTTVRaoTU
rcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0iJBeAZfv6lOm3fzB
3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn5JVn1j+SgF7y
NH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHdBgNVHR8E
gdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUAw
PgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy
ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0
Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
IoAPMjAwMDAyMDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQD
AgEGMB8GA1UdIwQYMBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQW
BBSEi3T9xY3A/ydtIDdFfP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2
fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWA
O9GK9Q6nIMstZVXQkvTnhLUGJoMShAusO7JE7r3PQNsgDrpuFOow4DtifH+L
a3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/GpsKkMWr2tGzhtQvJFJcem3G8v7l
TRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKdzmVml64mXg==
-----END CERTIFICATE-----
Subject: O=Entrust.net, OU=www.entrust.net/SSL_CPS incorp. by ref. (limits liab.), OU=(c) 2000 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
-----BEGIN CERTIFICATE-----
MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UE
ChMLRW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xf
Q1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
KGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVz
dC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
Fw0wMDAyMDQxNzIwMDBaFw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtF
bnRydXN0Lm5ldDE/MD0GA1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMg
aW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg
MjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5l
dCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO8GCGD9JYf9Mzly0XonUw
tZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaBbL3+qPZ1V1eMkGxK
wz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2dWcTC5/oVzbI
XQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4QgEBBAQD
AgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoTC0Vu
dHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAy
MDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0
IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNV
BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIw
NDE3NTAwMFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc
/vuLkpyw8m4iMB0GA1UdDgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNV
HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkq
hkiG9w0BAQQFAAOBgQBi24GRzsiad0Iv7L0no1MPUBvqTpLwqa+poLpIYcvv
yQbvH9X07t9WLebKahlzqlO+krNQAraFJnJj2HVQYnUUt7NQGj/KEQALhUVp
bbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1UyrrJzOCE98g+EZfTYAkYvAX/
bIkz8OwVDw==
-----END CERTIFICATE-----
Subject: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
-----BEGIN CERTIFICATE-----
MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UE
ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNf
MjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
HChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEy
MjQxNzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0
Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29y
cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkg
RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4
QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/EC
DNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuXMlBvPci6Zgzj
/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzWnLLP
KQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZd
enoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB
0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJ
FrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFh
fGPjK50xA3B20qMooPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVU
KcgF7bISKo30Axv/55IQh7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaoho
wXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2
+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof888
6ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
-----END CERTIFICATE-----
Subject: C=US, O=Entrust.net, OU=www.entrust.net/Client_CA_Info/CPS incorp. by ref. limits liab., OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Client Certification Authority
-----BEGIN CERTIFICATE-----
MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE
BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50
cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs
aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp
bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0
aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa
MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV
BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw
LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50
cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL
ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv
x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV
iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173
iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw
ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50
cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff
SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE
CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50
cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD
VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D
bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx
MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW
/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG
A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ
OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU
ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE
PHayXOw=
-----END CERTIFICATE-----
Subject: C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
-----BEGIN CERTIFICATE-----
MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UE
BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50
cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UE
AxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQsw
CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3
dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlh
Yi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTow
OAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
b24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0
VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHIN
iC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3wkrYKZImZNHk
mGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcwggHT
MBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHY
pIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChs
aW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBM
aW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNo
dHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAi
gA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMC
AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYE
FPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9
B0EABAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKn
CqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2Zcgx
xufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd2cNgQ4xYDiKWL2KjLB+6
rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
-----END CERTIFICATE-----
Subject: C=US, O=SecureTrust Corporation, CN=SecureTrust CA
-----BEGIN CERTIFICATE-----
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
-----END CERTIFICATE-----
Subject: C=US, O=SecureTrust Corporation, CN=Secure Global CA
-----BEGIN CERTIFICATE-----
MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
-----END CERTIFICATE-----
lib/ssl/api_braintreegateway_com.ca.crt 0000644 00000026607 15210163246 0014246 0 ustar 00 -----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
lib/autoload.php 0000644 00000001113 15210163246 0007627 0 ustar 00 = 5.4.0 required');
}
function requireDependencies() {
$requiredExtensions = ['xmlwriter', 'openssl', 'dom', 'hash', 'curl'];
foreach ($requiredExtensions AS $ext) {
if (!extension_loaded($ext)) {
throw new Braintree_Exception('The Braintree library requires the ' . $ext . ' extension.');
}
}
}
requireDependencies();