diff --git a/lib/PayPal/Api/FuturePayment.php b/lib/PayPal/Api/FuturePayment.php index 5883a63..f96d4fa 100644 --- a/lib/PayPal/Api/FuturePayment.php +++ b/lib/PayPal/Api/FuturePayment.php @@ -21,7 +21,8 @@ class FuturePayment extends Payment * @param $correlationId * @return $this */ - public function create($apiContext = null, $correlationId = null) { + public function create($apiContext = null, $correlationId = null) + { if ($apiContext == null) { $apiContext = new ApiContext(self::$credential); } @@ -45,4 +46,31 @@ class FuturePayment extends Payment return $this; } + + /** + * Get a Refresh Token from Authorization Code + * + * @param $authorizationCode + * @param ApiContext $apiContext + * @return string|null refresh token + */ + public static function getRefreshToken($authorizationCode, $apiContext = null) + { + $apiContext = $apiContext ? $apiContext : new ApiContext(self::$credential); + $credential = $apiContext->getCredential(); + return $credential->getRefreshToken($apiContext->getConfig(), $authorizationCode); + } + + /** + * Updates Access Token using long lived refresh token + * + * @param string|null $refreshToken + * @param ApiContext $apiContext + * @return void + */ + public function updateAccessToken($refreshToken, $apiContext) + { + $apiContext = $apiContext ? $apiContext : new ApiContext(self::$credential); + $apiContext->getCredential()->updateAccessToken($apiContext->getConfig(), $refreshToken); + } } diff --git a/lib/PayPal/Auth/OAuthTokenCredential.php b/lib/PayPal/Auth/OAuthTokenCredential.php index 302f675..b27b097 100644 --- a/lib/PayPal/Auth/OAuthTokenCredential.php +++ b/lib/PayPal/Auth/OAuthTokenCredential.php @@ -1,236 +1,271 @@ -clientId = $clientId; - $this->clientSecret = $clientSecret; - $this->logger = PPLoggingManager::getInstance(__CLASS__); - } - - /** - * Get AccessToken - * - * @param $config - * - * @return null|string - */ - public function getAccessToken($config) - { - // Check if Access Token is not null and has not expired. - // The API returns expiry time as a relative time unit - // We use a buffer time when checking for token expiry to account - // for API call delays and any delay between the time the token is - // retrieved and subsequently used - if ( - $this->accessToken != null && - (time() - $this->tokenCreateTime) > ($this->tokenExpiresIn - self::$expiryBufferTime) - ) { - $this->accessToken = null; - } - - // If accessToken is Null, obtain a new token - if ($this->accessToken == null) { - $this->updateAccessToken($config); - } - - return $this->accessToken; - } - - /** - * Get a Refresh Token from Authorization Code - * - * @param $config - * @param $authorizationCode - * @return string|null - */ - public function getRefreshToken($config, $authorizationCode) //Which comes from Mobile. - { - $payload = - "grant_type=authorization_code&code=". - $authorizationCode. - "&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=token"; - $jsonResponse = $this->getToken($config, $payload); - - if ($jsonResponse != null && isset($jsonResponse["refresh_token"])) { - return $jsonResponse['refresh_token']; - } - } - - /** - * Updates Access Token based on given input - * - * @param $config - * @param string|null $refreshToken - * @return string - */ - public function updateAccessToken($config, $refreshToken = null) - { - $this->generateAccessToken($config, $refreshToken); - return $this->accessToken; - } - - /** - * Retrieves the token based on the input configuration - * - * @param array $config - * @param string $payload - * @return mixed - * @throws PPConfigurationException - * @throws \PayPal\Exception\PPConnectionException - */ - private function getToken($config, $payload) - { - $base64ClientID = base64_encode($this->clientId . ":" . $this->clientSecret); - $headers = array( - "User-Agent" => PPUserAgent::getValue(RestHandler::$sdkName, RestHandler::$sdkVersion), - "Authorization" => "Basic " . $base64ClientID, - "Accept" => "*/*" - ); - - $httpConfiguration = $this->getOAuthHttpConfiguration($config); - $httpConfiguration->setHeaders($headers); - - $connection = new PPHttpConnection($httpConfiguration, $config); - $res = $connection->execute($payload); - $jsonResponse = json_decode($res, true); - - if ($jsonResponse == null || !isset($jsonResponse["access_token"]) || !isset($jsonResponse["expires_in"])) { - $this->accessToken = null; - $this->tokenExpiresIn = null; - $this->logger->warning( - "Could not generate new Access token. Invalid response from server: " . $jsonResponse - ); - } else { - $this->accessToken = $jsonResponse["access_token"]; - $this->tokenExpiresIn = $jsonResponse["expires_in"]; - } - $this->tokenCreateTime = time(); - return $jsonResponse; - } - - - /** - * Generates a new access token - * - * @param array $config - * @return null - */ - private function generateAccessToken($config, $refreshToken = null) - { - $payload = "grant_type=client_credentials"; - if ($refreshToken != null) { - // If the refresh token is provided, it would get access token using refresh token - // Used for Future Payments - $payload = "grant_type=refresh_token&refresh_token=$refreshToken"; - } - $this->getToken($config, $payload); - - return $this->accessToken; - } - - /** - * Get HttpConfiguration object for OAuth API - * - * @param array $config - * - * @return PPHttpConfig - * @throws \PayPal\Exception\PPConfigurationException - */ - private function getOAuthHttpConfiguration($config) - { - if (isset($config['oauth.EndPoint'])) { - $baseEndpoint = $config['oauth.EndPoint']; - } else if (isset($config['service.EndPoint'])) { - $baseEndpoint = $config['service.EndPoint']; - } else if (isset($config['mode'])) { - switch (strtoupper($config['mode'])) { - case 'SANDBOX': - $baseEndpoint = PPConstants::REST_SANDBOX_ENDPOINT; - break; - case 'LIVE': - $baseEndpoint = PPConstants::REST_LIVE_ENDPOINT; - break; - default: - throw new PPConfigurationException('The mode config parameter must be set to either sandbox/live'); - } - } else { - throw new PPConfigurationException( - 'You must set one of service.endpoint or mode parameters in your configuration' - ); - } - - $baseEndpoint = rtrim(trim($baseEndpoint), '/'); - - return new PPHttpConfig($baseEndpoint . "/v1/oauth2/token", "POST"); - } -} +clientId = $clientId; + $this->clientSecret = $clientSecret; + $this->logger = PPLoggingManager::getInstance(__CLASS__); + } + + /** + * Get Client ID + * + * @return string + */ + public function getClientId() + { + return $this->clientId; + } + + /** + * Get Client Secret + * + * @return string + */ + public function getClientSecret() + { + return $this->clientSecret; + } + + /** + * Get AccessToken + * + * @param $config + * + * @return null|string + */ + public function getAccessToken($config) + { + // Check if Access Token is not null and has not expired. + // The API returns expiry time as a relative time unit + // We use a buffer time when checking for token expiry to account + // for API call delays and any delay between the time the token is + // retrieved and subsequently used + if ( + $this->accessToken != null && + (time() - $this->tokenCreateTime) > ($this->tokenExpiresIn - self::$expiryBufferTime) + ) { + $this->accessToken = null; + } + + // If accessToken is Null, obtain a new token + if ($this->accessToken == null) { + $this->updateAccessToken($config); + } + + return $this->accessToken; + } + + /** + * Get a Refresh Token from Authorization Code + * + * @param $config + * @param $authorizationCode + * @param array $params optional arrays to override defaults + * @return string|null + */ + public function getRefreshToken($config, $authorizationCode = null, $params = array()) + { + static $allowedParams = array( + 'grant_type' => 'authorization_code', + 'code' => 1, + 'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob', + 'response_type' => 'token' + ); + + $params = is_array($params) ? $params : array(); + if ($authorizationCode) { + //Override the authorizationCode if value is explicitly set + $params['code'] = $authorizationCode; + } + $payload = http_build_query(array_merge($allowedParams, array_intersect_key($params, $allowedParams))); + + $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload); + + if ($response != null && isset($response["refresh_token"])) { + return $response['refresh_token']; + } + } + + /** + * Updates Access Token based on given input + * + * @param $config + * @param string|null $refreshToken + * @return string + */ + public function updateAccessToken($config, $refreshToken = null) + { + $this->generateAccessToken($config, $refreshToken); + return $this->accessToken; + } + + /** + * Retrieves the token based on the input configuration + * + * @param array $config + * @param string $payload + * @return mixed + * @throws PPConfigurationException + * @throws \PayPal\Exception\PPConnectionException + */ + private function getToken($config, $clientId, $clientSecret, $payload) + { + $base64ClientID = base64_encode($clientId . ":" . $clientSecret); + $headers = array( + "User-Agent" => PPUserAgent::getValue(RestHandler::$sdkName, RestHandler::$sdkVersion), + "Authorization" => "Basic " . $base64ClientID, + "Accept" => "*/*" + ); + + $httpConfiguration = self::getOAuthHttpConfiguration($config); + $httpConfiguration->setHeaders($headers); + + $connection = new PPHttpConnection($httpConfiguration, $config); + $res = $connection->execute($payload); + $response = json_decode($res, true); + + return $response; + } + + + /** + * Generates a new access token + * + * @param array $config + * @return null + */ + private function generateAccessToken($config, $refreshToken = null) + { + $params = array('grant_type' => 'client_credentials'); + if ($refreshToken != null) { + // If the refresh token is provided, it would get access token using refresh token + // Used for Future Payments + $params['grant_type'] = 'refresh_token'; + $params['refresh_token'] = $refreshToken; + } + $payload = http_build_query($params); + $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload); + + if ($response == null || !isset($response["access_token"]) || !isset($response["expires_in"])) { + $this->accessToken = null; + $this->tokenExpiresIn = null; + $this->logger->warning( + "Could not generate new Access token. Invalid response from server: " . $response + ); + } else { + $this->accessToken = $response["access_token"]; + $this->tokenExpiresIn = $response["expires_in"]; + } + $this->tokenCreateTime = time(); + + return $this->accessToken; + } + + /** + * Get HttpConfiguration object for OAuth API + * + * @param array $config + * + * @return PPHttpConfig + * @throws \PayPal\Exception\PPConfigurationException + */ + private static function getOAuthHttpConfiguration($config) + { + if (isset($config['oauth.EndPoint'])) { + $baseEndpoint = $config['oauth.EndPoint']; + } else if (isset($config['service.EndPoint'])) { + $baseEndpoint = $config['service.EndPoint']; + } else if (isset($config['mode'])) { + switch (strtoupper($config['mode'])) { + case 'SANDBOX': + $baseEndpoint = PPConstants::REST_SANDBOX_ENDPOINT; + break; + case 'LIVE': + $baseEndpoint = PPConstants::REST_LIVE_ENDPOINT; + break; + default: + throw new PPConfigurationException('The mode config parameter must be set to either sandbox/live'); + } + } else { + throw new PPConfigurationException( + 'You must set one of service.endpoint or mode parameters in your configuration' + ); + } + + $baseEndpoint = rtrim(trim($baseEndpoint), '/'); + + return new PPHttpConfig($baseEndpoint . "/v1/oauth2/token", "POST"); + } +} diff --git a/lib/PayPal/Auth/Openid/PPOpenIdSession.php b/lib/PayPal/Auth/Openid/PPOpenIdSession.php index 598ca73..1331294 100644 --- a/lib/PayPal/Auth/Openid/PPOpenIdSession.php +++ b/lib/PayPal/Auth/Openid/PPOpenIdSession.php @@ -28,6 +28,9 @@ class PPOpenIdSession if ($apiContext->get($clientId)) { $clientId = $apiContext->get($clientId); } + + $clientId = $clientId ? $clientId : $apiContext->getCredential()->getClientId(); + $scope = count($scope) != 0 ? $scope : array('openid', 'profile', 'address', 'email', 'phone', 'https://uri.paypal.com/services/paypalattributes', 'https://uri.paypal.com/services/expresscheckout'); if (!in_array('openid', $scope)) { diff --git a/lib/PayPal/Auth/Openid/PPOpenIdTokeninfo.php b/lib/PayPal/Auth/Openid/PPOpenIdTokeninfo.php index 8940259..85d6c26 100644 --- a/lib/PayPal/Auth/Openid/PPOpenIdTokeninfo.php +++ b/lib/PayPal/Auth/Openid/PPOpenIdTokeninfo.php @@ -164,6 +164,7 @@ class PPOpenIdTokeninfo extends ResourceModel if (!array_key_exists('grant_type', $params)) { $params['grant_type'] = 'authorization_code'; } + $apiContext = $apiContext ? $apiContext : new ApiContext(self::$credential); if (sizeof($apiContext->get($clientId)) > 0) { $clientId = $apiContext->get($clientId); @@ -172,6 +173,10 @@ class PPOpenIdTokeninfo extends ResourceModel if (sizeof($apiContext->get($clientSecret)) > 0) { $clientSecret = $apiContext->get($clientSecret); } + + $clientId = $clientId ? $clientId : $apiContext->getCredential()->getClientId(); + $clientSecret = $clientSecret ? $clientSecret : $apiContext->getCredential()->getClientSecret(); + $json = self::executeCall( "/v1/identity/openidconnect/tokenservice", "POST", @@ -205,6 +210,7 @@ class PPOpenIdTokeninfo extends ResourceModel public function createFromRefreshToken($params, $apiContext = null) { static $allowedParams = array('grant_type' => 1, 'refresh_token' => 1, 'scope' => 1); + $apiContext = $apiContext ? $apiContext : new ApiContext(self::$credential); if (!array_key_exists('grant_type', $params)) { $params['grant_type'] = 'refresh_token'; @@ -213,13 +219,16 @@ class PPOpenIdTokeninfo extends ResourceModel $params['refresh_token'] = $this->getRefreshToken(); } + $clientId = isset($params['client_id']) ? $params['client_id'] : $apiContext->getCredential()->getClientId(); + $clientSecret = isset($params['client_secret']) ? $params['client_secret'] : $apiContext->getCredential()->getClientSecret(); + $json = self::executeCall( "/v1/identity/openidconnect/tokenservice", "POST", http_build_query(array_intersect_key($params, $allowedParams)), array( 'Content-Type' => 'application/x-www-form-urlencoded', - 'Authorization' => 'Basic ' . base64_encode($params['client_id'] . ":" . $params['client_secret']) + 'Authorization' => 'Basic ' . base64_encode($clientId . ":" . $clientSecret) ), $apiContext ); diff --git a/lib/PayPal/Auth/Openid/PPOpenIdUserinfo.php b/lib/PayPal/Auth/Openid/PPOpenIdUserinfo.php index e7d0544..f49d343 100644 --- a/lib/PayPal/Auth/Openid/PPOpenIdUserinfo.php +++ b/lib/PayPal/Auth/Openid/PPOpenIdUserinfo.php @@ -466,6 +466,8 @@ class PPOpenIdUserinfo extends ResourceModel { static $allowedParams = array('schema' => 1); + $params = is_array($params) ? $params : array(); + if (!array_key_exists('schema', $params)) { $params['schema'] = 'openid'; } diff --git a/lib/PayPal/Core/PPHttpConnection.php b/lib/PayPal/Core/PPHttpConnection.php index f520642..8f0e8e9 100644 --- a/lib/PayPal/Core/PPHttpConnection.php +++ b/lib/PayPal/Core/PPHttpConnection.php @@ -79,8 +79,7 @@ class PPHttpConnection public function execute($data) { //Initialize the logger - $this->logger->fine("Connecting to " . $this->httpConfig->getUrl()); - $this->logger->fine("Payload " . $data); + $this->logger->info($this->httpConfig->getMethod() . ' ' . $this->httpConfig->getUrl()); //Initialize Curl Options $ch = curl_init($this->httpConfig->getUrl()); @@ -100,18 +99,19 @@ class PPHttpConnection //Default Option if Method not of given types in switch case if ($this->httpConfig->getMethod() != NULL) { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->httpConfig->getMethod()); - $this->logger->info("Method : " . $this->httpConfig->getMethod()); } //Logging Each Headers for debugging purposes foreach ($this->getHttpHeaders() as $header) { //TODO: Strip out credentials and other secure info when logging. - $this->logger->info("Adding header $header"); + $this->logger->fine($header); } + $this->logger->fine("Payload : " . $data . "\n"); //Execute Curl Request $result = curl_exec($ch); + //Retry if Certificate Exception if (curl_errno($ch) == 60) { $this->logger->info("Invalid or no certificate authority found - Retrying using bundled CA certs file"); @@ -151,6 +151,7 @@ class PPHttpConnection "Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}. " . "Retried $retries times." ); + $this->logger->fine("Response : " . $result . "\n\n"); $ex->setData($result); throw $ex; } else if ($httpStatus < 200 || $httpStatus >= 300) { @@ -159,10 +160,13 @@ class PPHttpConnection "Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}.", $httpStatus ); + $this->logger->fine("Response : " . $result . "\n\n"); $ex->setData($result); throw $ex; } + $this->logger->fine("Response : " . $result . "\n\n"); + //Return result object return $result; } diff --git a/lib/PayPal/Core/PPLoggingManager.php b/lib/PayPal/Core/PPLoggingManager.php index 29e162b..a2eda13 100644 --- a/lib/PayPal/Core/PPLoggingManager.php +++ b/lib/PayPal/Core/PPLoggingManager.php @@ -70,6 +70,11 @@ class PPLoggingManager */ public function __construct() { + // To suppress the warning during the date() invocation in logs, we would default the timezone to GMT. + if (!ini_get('date.timezone')) { + date_default_timezone_set('GMT'); + } + $config = PPConfigManager::getInstance()->getConfigHashmap(); $this->isLoggingEnabled = (array_key_exists('log.LogEnabled', $config) && $config['log.LogEnabled'] == '1'); @@ -93,7 +98,7 @@ class PPLoggingManager private function log($message, $level = PPLoggingLevel::INFO) { if ($this->isLoggingEnabled && ($level <= $this->loggingLevel)) { - error_log($this->loggerName . ": $message\n", 3, $this->loggerFile); + error_log("[" . date('d-m-Y h:i:s') . "] " . $this->loggerName . ": $message\n", 3, $this->loggerFile); } } diff --git a/lib/PayPal/Transport/PPRestCall.php b/lib/PayPal/Transport/PPRestCall.php index ab9b12a..cf3ad8b 100644 --- a/lib/PayPal/Transport/PPRestCall.php +++ b/lib/PayPal/Transport/PPRestCall.php @@ -72,7 +72,6 @@ class PPRestCall } $connection = new PPHttpConnection($httpConfig, $config); $response = $connection->execute($data); - $this->logger->fine($response . PHP_EOL); return $response; } diff --git a/sample/bootstrap.php b/sample/bootstrap.php index 87728bb..abed4b9 100644 --- a/sample/bootstrap.php +++ b/sample/bootstrap.php @@ -23,6 +23,7 @@ use PayPal\Rest\ApiContext; use PayPal\Auth\OAuthTokenCredential; error_reporting(E_ALL); +ini_set('display_errors', '1'); // Replace these values by entering your own ClientId and Secret by visiting https://developer.paypal.com/webapps/developer/applications/myapps $clientId = 'AYSq3RDGsmBLJE-otTkBtM-jBRd1TCQwFf9RGfwddNXWz0uFU9ztymylOhRS'; diff --git a/sample/doc/assets/behavior.js b/sample/doc/assets/behavior.js index 291e9f0..1188e5c 100644 --- a/sample/doc/assets/behavior.js +++ b/sample/doc/assets/behavior.js @@ -343,6 +343,132 @@ f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3 ] } ] + }, { + "type": "folder", + "data": { + "path": "lipp", + "title": "lipp" + }, + "depth": 1, + "children": [ + { + "type": "file", + "data": { + "language": { + "nameMatchers": [{}, ".fbp"], + "pygmentsLexer": "php", + "singleLineComment": ["//"], + "ignorePrefix": "}", + "foldPrefix": "^", + "name": "PHP" + }, + "sourcePath": "/Users/japatel/Documents/workspace/Server-SDK/rest-api-sdk-php/sample/lipp/GenerateAccessTokenFromRefreshToken.php", + "projectPath": "lipp/GenerateAccessTokenFromRefreshToken.php", + "targetPath": "lipp/GenerateAccessTokenFromRefreshToken", + "pageTitle": "lipp/GenerateAccessTokenFromRefreshToken", + "title": "GenerateAccessTokenFromRefreshToken" + }, + "depth": 2, + "outline": [ + { + "type": "heading", + "data": { + "level": 3, + "title": "Obtain Access Token From Refresh Token", + "slug": "obtain-access-token-from-refresh-token" + }, + "depth": 3 + } + ] + }, { + "type": "file", + "data": { + "language": { + "nameMatchers": [{}, ".fbp"], + "pygmentsLexer": "php", + "singleLineComment": ["//"], + "ignorePrefix": "}", + "foldPrefix": "^", + "name": "PHP" + }, + "sourcePath": "/Users/japatel/Documents/workspace/Server-SDK/rest-api-sdk-php/sample/lipp/GetUserInfo.php", + "projectPath": "lipp/GetUserInfo.php", + "targetPath": "lipp/GetUserInfo", + "pageTitle": "lipp/GetUserInfo", + "title": "GetUserInfo" + }, + "depth": 2, + "outline": [ + { + "type": "heading", + "data": { + "level": 3, + "title": "Obtain Access Token From Refresh Token", + "slug": "obtain-access-token-from-refresh-token" + }, + "depth": 3 + } + ] + }, { + "type": "file", + "data": { + "language": { + "nameMatchers": [{}, ".fbp"], + "pygmentsLexer": "php", + "singleLineComment": ["//"], + "ignorePrefix": "}", + "foldPrefix": "^", + "name": "PHP" + }, + "sourcePath": "/Users/japatel/Documents/workspace/Server-SDK/rest-api-sdk-php/sample/lipp/ObtainUserConsent.php", + "projectPath": "lipp/ObtainUserConsent.php", + "targetPath": "lipp/ObtainUserConsent", + "pageTitle": "lipp/ObtainUserConsent", + "title": "ObtainUserConsent" + }, + "depth": 2, + "outline": [ + { + "type": "heading", + "data": { + "level": 3, + "title": "Get User Consent URL", + "slug": "get-user-consent-url" + }, + "depth": 3 + } + ] + }, { + "type": "file", + "data": { + "language": { + "nameMatchers": [{}, ".fbp"], + "pygmentsLexer": "php", + "singleLineComment": ["//"], + "ignorePrefix": "}", + "foldPrefix": "^", + "name": "PHP" + }, + "sourcePath": "/Users/japatel/Documents/workspace/Server-SDK/rest-api-sdk-php/sample/lipp/UserConsentRedirect.php", + "projectPath": "lipp/UserConsentRedirect.php", + "targetPath": "lipp/UserConsentRedirect", + "pageTitle": "lipp/UserConsentRedirect", + "title": "UserConsentRedirect" + }, + "depth": 2, + "outline": [ + { + "type": "heading", + "data": { + "level": 3, + "title": "User Consent Response", + "slug": "user-consent-response" + }, + "depth": 3 + } + ] + } + ] }, { "type": "folder", "data": { diff --git a/sample/doc/invoice/CreateInvoice.html b/sample/doc/invoice/CreateInvoice.html index 4f80c2f..1c43f39 100644 --- a/sample/doc/invoice/CreateInvoice.html +++ b/sample/doc/invoice/CreateInvoice.html @@ -22,7 +22,7 @@ required for invoice APIs
Retrieve the invoice object by calling the
static get method
on the Invoice class by passing a valid
diff --git a/sample/doc/invoice/RemindInvoice.html b/sample/doc/invoice/RemindInvoice.html
index 3789b92..fc2a4ae 100644
--- a/sample/doc/invoice/RemindInvoice.html
+++ b/sample/doc/invoice/RemindInvoice.html
@@ -10,7 +10,7 @@ an invoice to the payer
ApiContext)ApiContext)This would send a notification to both merchant as well the payer. The information of merchant and payer is retrieved from the invoice details
ApiContext)Send a legitimate invoice to the payer
with a valid ApiContext (See bootstrap.php for more on ApiContext)
You can retrieve the refresh token by executing ObtainUserConsent.php and store the refresh token
To obtain User Info, you have to follow three steps in general. +First, you need to obtain user's consent to retrieve the information you want. +This is explained in the example "ObtainUserConsent.php".
Once you get the user's consent, the end result would be long lived refresh token. +This refresh token should be stored in a permanent storage for later use.
Lastly, when you need to retrieve the user information, you need to generate the short lived access token +to retreive the information. The short lived access token can be retrieved using the example shown in +"GenerateAccessTokenFromRefreshToken.php", or as shown below
You can retrieve the refresh token by executing ObtainUserConsent.php and store the refresh token
The clientId is stored in the bootstrap file
PayPal would redirect the user to the redirect_uri mentioned when creating the consent URL. +The user would then able to retrieve the access token by getting the code, which is returned as a GET parameter.
Obtain Authorization Code from Code, Client ID and Client Secret
A Payment Resource; create one using -the above types and intent set to 'sale'
You need to get a permanent refresh token from the authorization code, retrieved from the mobile sdk.
authorization code from mobile sdk
correlation id from mobile sdk
You need to get a permanent refresh token from the authorization code, retrieved from the mobile sdk.
authorization code from mobile sdk
correlation id from mobile sdk
Exchange authorization_code for long living refresh token. You should store -it in a database for later use
Update the access token in apiContext
Update the access token in apiContext
Create a payment by calling the 'create' method
passing it a valid apiContext.
(See bootstrap.php for more on ApiContext)
The return object contains the state and the
url to which the buyer must be redirected to
for payment approval
-Please note that currently future payments works only with Paypal as a funding instrument.
Saved credit card id from a previous call to CreateCreditCard.php
A resource representing a Payer's funding instrument. For stored credit card payments, set the CreditCardToken field on this object.
(See bootstrap.php for more on ApiContext)
Merchant Info
A resource representing merchant information that can be used to identify merchant