Overview
  • Namespace
  • Class

Namespaces

  • PayPal
    • Api
    • Auth
    • Cache
    • Common
    • Converter
    • Core
    • Exception
    • Handler
    • Log
    • Rest
    • Security
    • Transport
    • Validation

Classes

  • PayPal\Api\Address
  • PayPal\Api\Agreement
  • PayPal\Api\AgreementDetails
  • PayPal\Api\AgreementStateDescriptor
  • PayPal\Api\AgreementTransaction
  • PayPal\Api\AgreementTransactions
  • PayPal\Api\AlternatePayment
  • PayPal\Api\Amount
  • PayPal\Api\Authorization
  • PayPal\Api\BankAccount
  • PayPal\Api\BankAccountsList
  • PayPal\Api\BankToken
  • PayPal\Api\BaseAddress
  • PayPal\Api\Billing
  • PayPal\Api\BillingAgreementToken
  • PayPal\Api\BillingInfo
  • PayPal\Api\CancelNotification
  • PayPal\Api\Capture
  • PayPal\Api\CarrierAccount
  • PayPal\Api\CarrierAccountToken
  • PayPal\Api\CartBase
  • PayPal\Api\ChargeModel
  • PayPal\Api\Cost
  • PayPal\Api\CountryCode
  • PayPal\Api\CreateProfileResponse
  • PayPal\Api\Credit
  • PayPal\Api\CreditCard
  • PayPal\Api\CreditCardHistory
  • PayPal\Api\CreditCardList
  • PayPal\Api\CreditCardToken
  • PayPal\Api\CreditFinancingOffered
  • PayPal\Api\Currency
  • PayPal\Api\CurrencyConversion
  • PayPal\Api\CustomAmount
  • PayPal\Api\DetailedRefund
  • PayPal\Api\Details
  • PayPal\Api\Error
  • PayPal\Api\ErrorDetails
  • PayPal\Api\ExtendedBankAccount
  • PayPal\Api\ExternalFunding
  • PayPal\Api\FileAttachment
  • PayPal\Api\FlowConfig
  • PayPal\Api\FmfDetails
  • PayPal\Api\FundingDetail
  • PayPal\Api\FundingInstrument
  • PayPal\Api\FundingOption
  • PayPal\Api\FundingSource
  • PayPal\Api\FuturePayment
  • PayPal\Api\HyperSchema
  • PayPal\Api\Image
  • PayPal\Api\Incentive
  • PayPal\Api\InputFields
  • PayPal\Api\InstallmentInfo
  • PayPal\Api\InstallmentOption
  • PayPal\Api\Invoice
  • PayPal\Api\InvoiceAddress
  • PayPal\Api\InvoiceItem
  • PayPal\Api\InvoiceNumber
  • PayPal\Api\InvoiceSearchResponse
  • PayPal\Api\Item
  • PayPal\Api\ItemList
  • PayPal\Api\Links
  • PayPal\Api\Measurement
  • PayPal\Api\MerchantInfo
  • PayPal\Api\MerchantPreferences
  • PayPal\Api\Metadata
  • PayPal\Api\NameValuePair
  • PayPal\Api\Notification
  • PayPal\Api\OpenIdAddress
  • PayPal\Api\OpenIdError
  • PayPal\Api\OpenIdSession
  • PayPal\Api\OpenIdTokeninfo
  • PayPal\Api\OpenIdUserinfo
  • PayPal\Api\Order
  • PayPal\Api\OverrideChargeModel
  • PayPal\Api\Participant
  • PayPal\Api\Patch
  • PayPal\Api\PatchRequest
  • PayPal\Api\Payee
  • PayPal\Api\Payer
  • PayPal\Api\PayerInfo
  • PayPal\Api\Payment
  • PayPal\Api\PaymentCard
  • PayPal\Api\PaymentCardToken
  • PayPal\Api\PaymentDefinition
  • PayPal\Api\PaymentDetail
  • PayPal\Api\PaymentExecution
  • PayPal\Api\PaymentHistory
  • PayPal\Api\PaymentInstruction
  • PayPal\Api\PaymentOptions
  • PayPal\Api\PaymentSummary
  • PayPal\Api\PaymentTerm
  • PayPal\Api\Payout
  • PayPal\Api\PayoutBatch
  • PayPal\Api\PayoutBatchHeader
  • PayPal\Api\PayoutItem
  • PayPal\Api\PayoutItemDetails
  • PayPal\Api\PayoutSenderBatchHeader
  • PayPal\Api\Phone
  • PayPal\Api\Plan
  • PayPal\Api\PlanList
  • PayPal\Api\PotentialPayerInfo
  • PayPal\Api\Presentation
  • PayPal\Api\PrivateLabelCard
  • PayPal\Api\ProcessorResponse
  • PayPal\Api\RecipientBankingInstruction
  • PayPal\Api\RedirectUrls
  • PayPal\Api\Refund
  • PayPal\Api\RefundDetail
  • PayPal\Api\RefundRequest
  • PayPal\Api\RelatedResources
  • PayPal\Api\Sale
  • PayPal\Api\Search
  • PayPal\Api\ShippingAddress
  • PayPal\Api\ShippingCost
  • PayPal\Api\ShippingInfo
  • PayPal\Api\Tax
  • PayPal\Api\Template
  • PayPal\Api\TemplateData
  • PayPal\Api\Templates
  • PayPal\Api\TemplateSettings
  • PayPal\Api\TemplateSettingsMetadata
  • PayPal\Api\Terms
  • PayPal\Api\Transaction
  • PayPal\Api\TransactionBase
  • PayPal\Api\Transactions
  • PayPal\Api\VerifyWebhookSignature
  • PayPal\Api\VerifyWebhookSignatureResponse
  • PayPal\Api\Webhook
  • PayPal\Api\WebhookEvent
  • PayPal\Api\WebhookEventList
  • PayPal\Api\WebhookEventType
  • PayPal\Api\WebhookEventTypeList
  • PayPal\Api\WebhookList
  • PayPal\Api\WebProfile
  • PayPal\Auth\OAuthTokenCredential
  • PayPal\Cache\AuthorizationCache
  • PayPal\Common\ArrayUtil
  • PayPal\Common\PayPalModel
  • PayPal\Common\PayPalResourceModel
  • PayPal\Common\PayPalUserAgent
  • PayPal\Common\ReflectionUtil
  • PayPal\Converter\FormatConverter
  • PayPal\Core\PayPalConfigManager
  • PayPal\Core\PayPalConstants
  • PayPal\Core\PayPalCredentialManager
  • PayPal\Core\PayPalHttpConfig
  • PayPal\Core\PayPalHttpConnection
  • PayPal\Core\PayPalLoggingManager
  • PayPal\Handler\OauthHandler
  • PayPal\Handler\RestHandler
  • PayPal\Log\PayPalDefaultLogFactory
  • PayPal\Log\PayPalLogger
  • PayPal\Rest\ApiContext
  • PayPal\Security\Cipher
  • PayPal\Transport\PayPalRestCall
  • PayPal\Validation\ArgumentValidator
  • PayPal\Validation\JsonValidator
  • PayPal\Validation\NumericValidator
  • PayPal\Validation\UrlValidator

Interfaces

  • PayPal\Handler\IPayPalHandler
  • PayPal\Log\PayPalLogFactory
  • PayPal\Rest\IResource

Exceptions

  • PayPal\Exception\PayPalConfigurationException
  • PayPal\Exception\PayPalConnectionException
  • PayPal\Exception\PayPalInvalidCredentialException
  • PayPal\Exception\PayPalMissingCredentialException
  1 <?php
  2 
  3 namespace PayPal\Auth;
  4 
  5 use PayPal\Cache\AuthorizationCache;
  6 use PayPal\Common\PayPalResourceModel;
  7 use PayPal\Core\PayPalHttpConfig;
  8 use PayPal\Core\PayPalHttpConnection;
  9 use PayPal\Core\PayPalLoggingManager;
 10 use PayPal\Exception\PayPalConfigurationException;
 11 use PayPal\Exception\PayPalConnectionException;
 12 use PayPal\Handler\IPayPalHandler;
 13 use PayPal\Rest\ApiContext;
 14 use PayPal\Security\Cipher;
 15 
 16 /**
 17  * Class OAuthTokenCredential
 18  */
 19 class OAuthTokenCredential extends PayPalResourceModel
 20 {
 21 
 22     public static $CACHE_PATH = '/../../../var/auth.cache';
 23 
 24     /**
 25      * @var string Default Auth Handler
 26      */
 27     public static $AUTH_HANDLER = 'PayPal\Handler\OauthHandler';
 28 
 29     /**
 30      * Private Variable
 31      *
 32      * @var int $expiryBufferTime
 33      */
 34     public static $expiryBufferTime = 120;
 35 
 36     /**
 37      * Client ID as obtained from the developer portal
 38      *
 39      * @var string $clientId
 40      */
 41     private $clientId;
 42 
 43     /**
 44      * Client secret as obtained from the developer portal
 45      *
 46      * @var string $clientSecret
 47      */
 48     private $clientSecret;
 49 
 50     /**
 51      * Generated Access Token
 52      *
 53      * @var string $accessToken
 54      */
 55     private $accessToken;
 56 
 57     /**
 58      * Seconds for with access token is valid
 59      *
 60      * @var $tokenExpiresIn
 61      */
 62     private $tokenExpiresIn;
 63 
 64     /**
 65      * Last time (in milliseconds) when access token was generated
 66      *
 67      * @var $tokenCreateTime
 68      */
 69     private $tokenCreateTime;
 70 
 71     /**
 72      * Instance of cipher used to encrypt/decrypt data while storing in cache.
 73      *
 74      * @var Cipher
 75      */
 76     private $cipher;
 77 
 78     /**
 79      * Construct
 80      *
 81      * @param string $clientId     client id obtained from the developer portal
 82      * @param string $clientSecret client secret obtained from the developer portal
 83      */
 84     public function __construct($clientId, $clientSecret)
 85     {
 86         $this->clientId = $clientId;
 87         $this->clientSecret = $clientSecret;
 88         $this->cipher = new Cipher($this->clientSecret);
 89     }
 90 
 91     /**
 92      * Get Client ID
 93      *
 94      * @return string
 95      */
 96     public function getClientId()
 97     {
 98         return $this->clientId;
 99     }
100 
101     /**
102      * Get Client Secret
103      *
104      * @return string
105      */
106     public function getClientSecret()
107     {
108         return $this->clientSecret;
109     }
110 
111     /**
112      * Get AccessToken
113      *
114      * @param $config
115      *
116      * @return null|string
117      */
118     public function getAccessToken($config)
119     {
120         // Check if we already have accessToken in Cache
121         if ($this->accessToken && (time() - $this->tokenCreateTime) < ($this->tokenExpiresIn - self::$expiryBufferTime)) {
122             return $this->accessToken;
123         }
124         // Check for persisted data first
125         $token = AuthorizationCache::pull($config, $this->clientId);
126         if ($token) {
127             // We found it
128             // This code block is for backward compatibility only.
129             if (array_key_exists('accessToken', $token)) {
130                 $this->accessToken = $token['accessToken'];
131             }
132 
133             $this->tokenCreateTime = $token['tokenCreateTime'];
134             $this->tokenExpiresIn = $token['tokenExpiresIn'];
135 
136             // Case where we have an old unencrypted cache file
137             if (!array_key_exists('accessTokenEncrypted', $token)) {
138                 AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn);
139             } else {
140                 $this->accessToken = $this->decrypt($token['accessTokenEncrypted']);
141             }
142         }
143 
144         // Check if Access Token is not null and has not expired.
145         // The API returns expiry time as a relative time unit
146         // We use a buffer time when checking for token expiry to account
147         // for API call delays and any delay between the time the token is
148         // retrieved and subsequently used
149         if (
150             $this->accessToken != null &&
151             (time() - $this->tokenCreateTime) > ($this->tokenExpiresIn - self::$expiryBufferTime)
152         ) {
153             $this->accessToken = null;
154         }
155 
156 
157         // If accessToken is Null, obtain a new token
158         if ($this->accessToken == null) {
159             // Get a new one by making calls to API
160             $this->updateAccessToken($config);
161             AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn);
162         }
163 
164         return $this->accessToken;
165     }
166 
167 
168     /**
169      * Get a Refresh Token from Authorization Code
170      *
171      * @param $config
172      * @param $authorizationCode
173      * @param array $params optional arrays to override defaults
174      * @return string|null
175      */
176     public function getRefreshToken($config, $authorizationCode = null, $params = array())
177     {
178         static $allowedParams = array(
179             'grant_type' => 'authorization_code',
180             'code' => 1,
181             'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
182             'response_type' => 'token'
183         );
184 
185         $params = is_array($params) ? $params : array();
186         if ($authorizationCode) {
187             //Override the authorizationCode if value is explicitly set
188             $params['code'] = $authorizationCode;
189         }
190         $payload = http_build_query(array_merge($allowedParams, array_intersect_key($params, $allowedParams)));
191 
192         $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload);
193 
194         if ($response != null && isset($response["refresh_token"])) {
195             return $response['refresh_token'];
196         }
197 
198         return null;
199     }
200 
201     /**
202      * Updates Access Token based on given input
203      *
204      * @param array $config
205      * @param string|null $refreshToken
206      * @return string
207      */
208     public function updateAccessToken($config, $refreshToken = null)
209     {
210         $this->generateAccessToken($config, $refreshToken);
211         return $this->accessToken;
212     }
213 
214     /**
215      * Retrieves the token based on the input configuration
216      *
217      * @param array $config
218      * @param string $clientId
219      * @param string $clientSecret
220      * @param string $payload
221      * @return mixed
222      * @throws PayPalConfigurationException
223      * @throws \PayPal\Exception\PayPalConnectionException
224      */
225     protected function getToken($config, $clientId, $clientSecret, $payload)
226     {
227         $httpConfig = new PayPalHttpConfig(null, 'POST', $config);
228 
229         // if proxy set via config, add it
230         if (!empty($config['http.Proxy'])) {
231             $httpConfig->setHttpProxy($config['http.Proxy']);
232         }
233 
234         $handlers = array(self::$AUTH_HANDLER);
235 
236         /** @var IPayPalHandler $handler */
237         foreach ($handlers as $handler) {
238             if (!is_object($handler)) {
239                 $fullHandler = "\\" . (string)$handler;
240                 $handler = new $fullHandler(new ApiContext($this));
241             }
242             $handler->handle($httpConfig, $payload, array('clientId' => $clientId, 'clientSecret' => $clientSecret));
243         }
244 
245         $connection = new PayPalHttpConnection($httpConfig, $config);
246         $res = $connection->execute($payload);
247         $response = json_decode($res, true);
248 
249         return $response;
250     }
251 
252 
253     /**
254      * Generates a new access token
255      *
256      * @param array $config
257      * @param null|string $refreshToken
258      * @return null
259      * @throws PayPalConnectionException
260      */
261     private function generateAccessToken($config, $refreshToken = null)
262     {
263         $params = array('grant_type' => 'client_credentials');
264         if ($refreshToken != null) {
265             // If the refresh token is provided, it would get access token using refresh token
266             // Used for Future Payments
267             $params['grant_type'] = 'refresh_token';
268             $params['refresh_token'] = $refreshToken;
269         }
270         $payload = http_build_query($params);
271         $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload);
272 
273         if ($response == null || !isset($response["access_token"]) || !isset($response["expires_in"])) {
274             $this->accessToken = null;
275             $this->tokenExpiresIn = null;
276             PayPalLoggingManager::getInstance(__CLASS__)->warning("Could not generate new Access token. Invalid response from server: ");
277             throw new PayPalConnectionException(null, "Could not generate new Access token. Invalid response from server: ");
278         } else {
279             $this->accessToken = $response["access_token"];
280             $this->tokenExpiresIn = $response["expires_in"];
281         }
282         $this->tokenCreateTime = time();
283 
284         return $this->accessToken;
285     }
286 
287     /**
288      * Helper method to encrypt data using clientSecret as key
289      *
290      * @param $data
291      * @return string
292      */
293     public function encrypt($data)
294     {
295         return $this->cipher->encrypt($data);
296     }
297 
298     /**
299      * Helper method to decrypt data using clientSecret as key
300      *
301      * @param $data
302      * @return string
303      */
304     public function decrypt($data)
305     {
306         return $this->cipher->decrypt($data);
307     }
308 }
309 
API documentation generated by ApiGen