[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/externals/wepay/ -> wepay.php (source)

   1  <?php
   2  
   3  class WePay {
   4  
   5      /**
   6       * Version number - sent in user agent string
   7       */
   8      const VERSION = '0.1.4';
   9  
  10      /**
  11       * Scope fields
  12       * Passed into Wepay::getAuthorizationUri as array
  13       */
  14      const SCOPE_MANAGE_ACCOUNTS     = 'manage_accounts';     // Open and interact with accounts
  15      const SCOPE_VIEW_BALANCE        = 'view_balance';        // View account balances
  16      const SCOPE_COLLECT_PAYMENTS    = 'collect_payments';    // Create and interact with checkouts
  17      const SCOPE_VIEW_USER           = 'view_user';           // Get details about authenticated user
  18      const SCOPE_PREAPPROVE_PAYMENTS = 'preapprove_payments'; // Create and interact with preapprovals
  19      const SCOPE_SEND_MONEY          = 'send_money';          // For withdrawals
  20  
  21      /**
  22       * Application's client ID
  23       */
  24      private static $client_id;
  25  
  26      /**
  27       * Application's client secret
  28       */
  29      private static $client_secret;
  30  
  31      /**
  32       * @deprecated Use WePay::getAllScopes() instead.
  33       */
  34      public static $all_scopes = array(
  35          self::SCOPE_MANAGE_ACCOUNTS,
  36          self::SCOPE_VIEW_BALANCE,
  37          self::SCOPE_COLLECT_PAYMENTS,
  38          self::SCOPE_PREAPPROVE_PAYMENTS,
  39          self::SCOPE_VIEW_USER,
  40          self::SCOPE_SEND_MONEY,
  41      );
  42  
  43      /**
  44       * Determines whether to use WePay's staging or production servers
  45       */
  46      private static $production = null;
  47  
  48      /**
  49       * cURL handle
  50       */
  51      private static $ch = NULL;
  52  
  53      /**
  54       * Authenticated user's access token
  55       */
  56      private $token;
  57  
  58      /**
  59       * Pass WePay::getAllScopes() into getAuthorizationUri if your application desires full access
  60       */
  61  	public static function getAllScopes() {
  62          return array(
  63              self::SCOPE_MANAGE_ACCOUNTS,
  64              self::SCOPE_VIEW_BALANCE,
  65              self::SCOPE_COLLECT_PAYMENTS,
  66              self::SCOPE_PREAPPROVE_PAYMENTS,
  67              self::SCOPE_VIEW_USER,
  68              self::SCOPE_SEND_MONEY,
  69          );
  70      }
  71  
  72      /**
  73       * Generate URI used during oAuth authorization
  74       * Redirect your user to this URI where they can grant your application
  75       * permission to make API calls
  76       * @link https://www.wepay.com/developer/reference/oauth2
  77       * @param array  $scope             List of scope fields for which your application wants access
  78       * @param string $redirect_uri      Where user goes after logging in at WePay (domain must match application settings)
  79       * @param array  $options optional  user_name,user_email which will be pre-filled on login form, state to be returned in querystring of redirect_uri
  80       * @return string URI to which you must redirect your user to grant access to your application
  81       */
  82  	public static function getAuthorizationUri(array $scope, $redirect_uri, array $options = array()) {
  83          // This does not use WePay::getDomain() because the user authentication
  84          // domain is different than the API call domain
  85          if (self::$production === null) {
  86              throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
  87          }
  88          $domain = self::$production ? 'https://www.wepay.com' : 'https://stage.wepay.com';
  89          $uri = $domain . '/v2/oauth2/authorize?';
  90          $uri .= http_build_query(array(
  91              'client_id'    => self::$client_id,
  92              'redirect_uri' => $redirect_uri,
  93              'scope'        => implode(',', $scope),
  94              'state'        => empty($options['state'])      ? '' : $options['state'],
  95              'user_name'    => empty($options['user_name'])  ? '' : $options['user_name'],
  96              'user_email'   => empty($options['user_email']) ? '' : $options['user_email'],
  97          ), '', '&');
  98          return $uri;
  99      }
 100  
 101  	private static function getDomain() {
 102          if (self::$production === true) {
 103              return 'https://wepayapi.com/v2/';
 104          }
 105          elseif (self::$production === false) {
 106              return 'https://stage.wepayapi.com/v2/';
 107          }
 108          else {
 109              throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
 110          }
 111      }
 112  
 113      /**
 114       * Exchange a temporary access code for a (semi-)permanent access token
 115       * @param string $code          'code' field from query string passed to your redirect_uri page
 116       * @param string $redirect_uri  Where user went after logging in at WePay (must match value from getAuthorizationUri)
 117       * @return StdClass|false
 118       *  user_id
 119       *  access_token
 120       *  token_type
 121       */
 122  	public static function getToken($code, $redirect_uri) {
 123          $params = (array(
 124              'client_id'     => self::$client_id,
 125              'client_secret' => self::$client_secret,
 126              'redirect_uri'  => $redirect_uri,
 127              'code'          => $code,
 128              'state'         => '', // do not hardcode
 129          ));
 130          $result = self::make_request('oauth2/token', $params);
 131          return $result;
 132      }
 133  
 134      /**
 135       * Configure SDK to run against WePay's production servers
 136       * @param string $client_id      Your application's client id
 137       * @param string $client_secret  Your application's client secret
 138       * @return void
 139       * @throws RuntimeException
 140       */
 141  	public static function useProduction($client_id, $client_secret) {
 142          if (self::$production !== null) {
 143              throw new RuntimeException('API mode has already been set.');
 144          }
 145          self::$production    = true;
 146          self::$client_id     = $client_id;
 147          self::$client_secret = $client_secret;
 148      }
 149  
 150      /**
 151       * Configure SDK to run against WePay's staging servers
 152       * @param string $client_id      Your application's client id
 153       * @param string $client_secret  Your application's client secret
 154       * @return void
 155       * @throws RuntimeException
 156       */
 157  	public static function useStaging($client_id, $client_secret) {
 158          if (self::$production !== null) {
 159              throw new RuntimeException('API mode has already been set.');
 160          }
 161          self::$production    = false;
 162          self::$client_id     = $client_id;
 163          self::$client_secret = $client_secret;
 164      }
 165  
 166      /**
 167       * Create a new API session
 168       * @param string $token - access_token returned from WePay::getToken
 169       */
 170  	public function __construct($token) {
 171          if ($token && !is_string($token)) {
 172              throw new InvalidArgumentException('$token must be a string, ' . gettype($token) . ' provided');
 173          }
 174          $this->token = $token;
 175      }
 176  
 177      /**
 178       * Clean up cURL handle
 179       */
 180  	public function __destruct() {
 181          if (self::$ch) {
 182              curl_close(self::$ch);
 183              self::$ch = NULL;
 184          }
 185      }
 186      
 187      /**
 188       * create the cURL request and execute it
 189       */
 190  	private static function make_request($endpoint, $values, $headers = array())
 191      {
 192          self::$ch = curl_init();
 193          $headers = array_merge(array("Content-Type: application/json"), $headers); // always pass the correct Content-Type header
 194          curl_setopt(self::$ch, CURLOPT_USERAGENT, 'WePay v2 PHP SDK v' . self::VERSION);
 195          curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, true);
 196          curl_setopt(self::$ch, CURLOPT_HTTPHEADER, $headers);
 197          curl_setopt(self::$ch, CURLOPT_TIMEOUT, 30); // 30-second timeout, adjust to taste
 198          curl_setopt(self::$ch, CURLOPT_POST, !empty($values)); // WePay's API is not strictly RESTful, so all requests are sent as POST unless there are no request values
 199          
 200          $uri = self::getDomain() . $endpoint;
 201          curl_setopt(self::$ch, CURLOPT_URL, $uri);
 202          
 203          if (!empty($values)) {
 204              curl_setopt(self::$ch, CURLOPT_POSTFIELDS, json_encode($values));
 205          }
 206          
 207          $raw = curl_exec(self::$ch);
 208          if ($errno = curl_errno(self::$ch)) {
 209              // Set up special handling for request timeouts
 210              if ($errno == CURLE_OPERATION_TIMEOUTED) {
 211                  throw new WePayServerException("Timeout occurred while trying to connect to WePay");
 212              }
 213              throw new Exception('cURL error while making API call to WePay: ' . curl_error(self::$ch), $errno);
 214          }
 215          $result = json_decode($raw);
 216          $httpCode = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
 217          if ($httpCode >= 400) {
 218              if (!isset($result->error_code)) {
 219                  throw new WePayServerException("WePay returned an error response with no error_code, please alert [email protected]. Original message: $result->error_description", $httpCode, $result, 0);
 220              }
 221              if ($httpCode >= 500) {
 222                  throw new WePayServerException($result->error_description, $httpCode, $result, $result->error_code);
 223              }
 224              switch ($result->error) {
 225                  case 'invalid_request':
 226                      throw new WePayRequestException($result->error_description, $httpCode, $result, $result->error_code);
 227                  case 'access_denied':
 228                  default:
 229                      throw new WePayPermissionException($result->error_description, $httpCode, $result, $result->error_code);
 230              }
 231          }
 232          
 233          return $result;
 234      }
 235  
 236      /**
 237       * Make API calls against authenticated user
 238       * @param string $endpoint - API call to make (ex. 'user', 'account/find')
 239       * @param array  $values   - Associative array of values to send in API call
 240       * @return StdClass
 241       * @throws WePayException on failure
 242       * @throws Exception on catastrophic failure (non-WePay-specific cURL errors)
 243       */
 244  	public function request($endpoint, array $values = array()) {
 245          $headers = array();
 246          
 247          if ($this->token) { // if we have an access_token, add it to the Authorization header
 248              $headers[] = "Authorization: Bearer $this->token";
 249          }
 250          
 251          $result = self::make_request($endpoint, $values, $headers);
 252          
 253          return $result;
 254      }
 255  }
 256  
 257  /**
 258   * Different problems will have different exception types so you can
 259   * catch and handle them differently.
 260   *
 261   * WePayServerException indicates some sort of 500-level error code and
 262   * was unavoidable from your perspective. You may need to re-run the
 263   * call, or check whether it was received (use a "find" call with your
 264   * reference_id and make a decision based on the response)
 265   *
 266   * WePayRequestException indicates a development error - invalid endpoint,
 267   * erroneous parameter, etc.
 268   *
 269   * WePayPermissionException indicates your authorization token has expired,
 270   * was revoked, or is lacking in scope for the call you made
 271   */
 272  class WePayException extends Exception {
 273  	public function __construct($description = '', $http_code = FALSE, $response = FALSE, $code = 0, $previous = NULL)
 274      {
 275          $this->response = $response;
 276  
 277          if (!defined('PHP_VERSION_ID')) {
 278              $version = explode('.', PHP_VERSION);
 279              define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
 280          }
 281  
 282          if (PHP_VERSION_ID < 50300) {
 283              parent::__construct($description, $code);
 284          } else {
 285              parent::__construct($description, $code, $previous);
 286          }
 287      }
 288  }
 289  class WePayRequestException extends WePayException {}
 290  class WePayPermissionException extends WePayException {}
 291  class WePayServerException extends WePayException {}


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1