Razorpay for WooCommerce - Version 1.4.1

Version Description

Download this release

Release Info

Developer razorpay
Plugin Icon 128x128 Razorpay for WooCommerce
Version 1.4.1
Comparing to
See all releases

Code changes from version 1.4.0 to 1.4.1

razorpay-sdk/src/Api.php CHANGED
@@ -4,41 +4,64 @@ namespace Razorpay\Api;
4
 
5
  class Api
6
  {
7
- public static $baseUrl = "https://api.razorpay.com/v1/";
8
 
9
- public static $key = null;
10
 
11
- public static $secret = null;
12
 
13
- const VERSION = '1.2.8';
 
 
 
 
 
 
14
 
15
  /**
16
  * @param string $key
17
  * @param string $secret
18
  */
19
- function __construct($key, $secret)
20
  {
21
  self::$key = $key;
22
  self::$secret = $secret;
23
-
24
- // Add the version to all HTTP Requests
25
- Request::addHeader('User-Agent', "Razorpay-PHP/".self::VERSION);
26
  }
27
 
28
  /*
29
  * Set Headers
30
  *
31
  */
32
- function setHeader($header, $value)
33
  {
34
  Request::addHeader($header, $value);
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * @param string $name
39
  * @return mixed
40
  */
41
- function __get($name)
42
  {
43
  $className = __NAMESPACE__.'\\'.ucwords($name);
44
 
@@ -46,4 +69,24 @@ class Api
46
 
47
  return $entity;
48
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
4
 
5
  class Api
6
  {
7
+ protected static $baseUrl = 'https://api.razorpay.com/v1/';
8
 
9
+ protected static $key = null;
10
 
11
+ protected static $secret = null;
12
 
13
+ /*
14
+ * App info is to store the Plugin/integration
15
+ * information
16
+ */
17
+ public static $appsDetails = array();
18
+
19
+ const VERSION = '1.2.9';
20
 
21
  /**
22
  * @param string $key
23
  * @param string $secret
24
  */
25
+ public function __construct($key, $secret)
26
  {
27
  self::$key = $key;
28
  self::$secret = $secret;
 
 
 
29
  }
30
 
31
  /*
32
  * Set Headers
33
  *
34
  */
35
+ public function setHeader($header, $value)
36
  {
37
  Request::addHeader($header, $value);
38
  }
39
 
40
+ public function setAppDetails($title, $version = null)
41
+ {
42
+ $app = array(
43
+ 'title' => $title,
44
+ 'version' => $version
45
+ );
46
+
47
+ array_push(self::$appsDetails, $app);
48
+ }
49
+
50
+ public function getAppsDetails()
51
+ {
52
+ return self::$appsDetails;
53
+ }
54
+
55
+ public function setBaseUrl($baseUrl)
56
+ {
57
+ self::$baseUrl = $baseUrl;
58
+ }
59
+
60
  /**
61
  * @param string $name
62
  * @return mixed
63
  */
64
+ public function __get($name)
65
  {
66
  $className = __NAMESPACE__.'\\'.ucwords($name);
67
 
69
 
70
  return $entity;
71
  }
72
+
73
+ public static function getBaseUrl()
74
+ {
75
+ return self::$baseUrl;
76
+ }
77
+
78
+ public static function getKey()
79
+ {
80
+ return self::$key;
81
+ }
82
+
83
+ public static function getSecret()
84
+ {
85
+ return self::$secret;
86
+ }
87
+
88
+ public static function getFullUrl($relativeUrl)
89
+ {
90
+ return self::getBaseUrl() . $relativeUrl;
91
+ }
92
  }
razorpay-sdk/src/Card.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Razorpay\Api;
4
+
5
+ class Card extends Entity
6
+ {
7
+ /**
8
+ * @param $id Card id
9
+ */
10
+ public function fetch($id)
11
+ {
12
+ return parent::fetch($id);
13
+ }
14
+ }
razorpay-sdk/src/Entity.php CHANGED
@@ -67,15 +67,21 @@ class Entity extends Resource implements ArrayableInterface
67
  }
68
  else
69
  {
70
- return static::buildEntity($response);
71
  }
72
  }
73
 
74
- protected static function buildEntity($data)
75
  {
76
  $entities = static::getDefinedEntitiesArray();
77
 
78
- if (isset($data['entity']))
 
 
 
 
 
 
79
  {
80
  if (in_array($data['entity'], $entities))
81
  {
@@ -84,19 +90,28 @@ class Entity extends Resource implements ArrayableInterface
84
  }
85
  else
86
  {
87
- $entity = new static;
88
  }
 
 
89
  }
90
  else
91
  {
92
- $entity = new static;
93
- }
94
 
95
- $entity->fill($data);
 
96
 
97
  return $entity;
98
  }
99
 
 
 
 
 
 
 
 
100
  protected static function getDefinedEntitiesArray()
101
  {
102
  return array(
@@ -130,29 +145,7 @@ class Entity extends Resource implements ArrayableInterface
130
  {
131
  if (is_array($value))
132
  {
133
- if (static::isAssocArray($value) === false)
134
- {
135
- $collection = array();
136
-
137
- foreach ($value as $v)
138
- {
139
- if (is_array($v))
140
- {
141
- $entity = static::buildEntity($v);
142
- array_push($collection, $entity);
143
- }
144
- else
145
- {
146
- array_push($collection, $v);
147
- }
148
- }
149
-
150
- $value = $collection;
151
- }
152
- else
153
- {
154
- $value = static::buildEntity($value);
155
- }
156
  }
157
 
158
  $attributes[$key] = $value;
@@ -161,6 +154,40 @@ class Entity extends Resource implements ArrayableInterface
161
  $this->attributes = $attributes;
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  public static function isAssocArray($arr)
165
  {
166
  return array_keys($arr) !== range(0, count($arr) - 1);
67
  }
68
  else
69
  {
70
+ return static::buildEntity(null, $response);
71
  }
72
  }
73
 
74
+ protected static function buildEntity($key, $data)
75
  {
76
  $entities = static::getDefinedEntitiesArray();
77
 
78
+ $arrayableAttributes = static::getArrayableAttributes();
79
+
80
+ if (in_array($key, $arrayableAttributes))
81
+ {
82
+ $entity = $data;
83
+ }
84
+ else if (isset($data['entity']))
85
  {
86
  if (in_array($data['entity'], $entities))
87
  {
90
  }
91
  else
92
  {
93
+ $entity = new self;
94
  }
95
+
96
+ $entity->fill($data);
97
  }
98
  else
99
  {
100
+ $entity = new self;
 
101
 
102
+ $entity->fill($data);
103
+ }
104
 
105
  return $entity;
106
  }
107
 
108
+ protected static function getArrayableAttributes()
109
+ {
110
+ return array(
111
+ 'notes'
112
+ );
113
+ }
114
+
115
  protected static function getDefinedEntitiesArray()
116
  {
117
  return array(
145
  {
146
  if (is_array($value))
147
  {
148
+ $value = self::getArrayValue($key, $value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
  $attributes[$key] = $value;
154
  $this->attributes = $attributes;
155
  }
156
 
157
+ protected static function getArrayValue($key, $value)
158
+ {
159
+ if (static::isAssocArray($value) === false)
160
+ {
161
+ $value = self::getAssocArrayValue($key, $value);
162
+ }
163
+ else
164
+ {
165
+ $value = static::buildEntity($key, $value);
166
+ }
167
+
168
+ return $value;
169
+ }
170
+
171
+ protected static function getAssocArrayValue($key, $value)
172
+ {
173
+ $collection = array();
174
+
175
+ foreach ($value as $v)
176
+ {
177
+ if (is_array($v))
178
+ {
179
+ $entity = static::buildEntity($key, $v);
180
+ array_push($collection, $entity);
181
+ }
182
+ else
183
+ {
184
+ array_push($collection, $v);
185
+ }
186
+ }
187
+
188
+ return $collection;
189
+ }
190
+
191
  public static function isAssocArray($arr)
192
  {
193
  return array_keys($arr) !== range(0, count($arr) - 1);
razorpay-sdk/src/Errors/ErrorCode.php CHANGED
@@ -10,6 +10,8 @@ class ErrorCode
10
 
11
  public static function exists($code)
12
  {
13
- return defined(get_class().'::'.$code);
 
 
14
  }
15
  }
10
 
11
  public static function exists($code)
12
  {
13
+ $code = strtoupper($code);
14
+
15
+ return defined(get_class() . '::' . $code);
16
  }
17
  }
razorpay-sdk/src/Errors/SignatureVerificationError.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Razorpay\Api\Errors;
4
+
5
+ use Exception;
6
+
7
+ class SignatureVerificationError extends Exception
8
+ {
9
+ }
razorpay-sdk/src/Invoice.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Razorpay\Api;
4
+
5
+ class Invoice extends Entity
6
+ {
7
+ /**
8
+ * @param $id Invoice id
9
+ */
10
+ public function fetch($id)
11
+ {
12
+ return parent::fetch($id);
13
+ }
14
+
15
+ public function create($attributes = array())
16
+ {
17
+ return parent::create($attributes);
18
+ }
19
+
20
+ public function all($options = array())
21
+ {
22
+ return parent::all($options);
23
+ }
24
+ }
razorpay-sdk/src/Order.php CHANGED
@@ -5,9 +5,8 @@ namespace Razorpay\Api;
5
  class Order extends Entity
6
  {
7
  /**
8
- * @param $id Order id description
9
  */
10
-
11
  public function create($attributes = array())
12
  {
13
  return parent::create($attributes);
5
  class Order extends Entity
6
  {
7
  /**
8
+ * @param $id Order id description
9
  */
 
10
  public function create($attributes = array())
11
  {
12
  return parent::create($attributes);
razorpay-sdk/src/Payment.php CHANGED
@@ -22,9 +22,11 @@ class Payment extends Entity
22
  */
23
  public function refund($attributes = array())
24
  {
25
- $relativeUrl = $this->getEntityUrl() . $this->id . '/refund';
26
 
27
- return $this->request('POST', $relativeUrl, $attributes);
 
 
28
  }
29
 
30
  /**
@@ -39,10 +41,10 @@ class Payment extends Entity
39
 
40
  public function refunds()
41
  {
42
- $refund = new Refund();
43
 
44
- $refund['payment_id'] = $this->id;
45
 
46
- return $refund;
47
  }
48
  }
22
  */
23
  public function refund($attributes = array())
24
  {
25
+ $refund = new Refund;
26
 
27
+ $attributes = array_merge($attributes, array('payment_id' => $this->id));
28
+
29
+ return $refund->create($attributes);
30
  }
31
 
32
  /**
41
 
42
  public function refunds()
43
  {
44
+ $refund = new Refund;
45
 
46
+ $options = array('payment_id' => $this->id);
47
 
48
+ return $refund->all($options);
49
  }
50
  }
razorpay-sdk/src/Refund.php CHANGED
@@ -5,19 +5,20 @@ namespace Razorpay\Api;
5
  class Refund extends Entity
6
  {
7
  /**
8
- * @param $id Payment id
9
  */
10
  public function fetch($id)
11
  {
12
- $relativeUrl = 'payments/'.$this->payment_id.'/'.$this->getEntityUrl().$id;
 
13
 
14
- return $this->request('GET', $relativeUrl);
 
 
15
  }
16
 
17
  public function all($options = array())
18
  {
19
- $relativeUrl = 'payments/'.$this->payment_id.'/'.$this->getEntityUrl();
20
-
21
- return $this->request('GET', $relativeUrl, $options);
22
  }
23
- }
5
  class Refund extends Entity
6
  {
7
  /**
8
+ * @param $id Refund id
9
  */
10
  public function fetch($id)
11
  {
12
+ return parent::fetch($id);
13
+ }
14
 
15
+ public function create($attributes = array())
16
+ {
17
+ return parent::create($attributes);
18
  }
19
 
20
  public function all($options = array())
21
  {
22
+ return parent::all($options);
 
 
23
  }
24
+ }
razorpay-sdk/src/Request.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace Razorpay\Api;
4
 
 
5
  use Exception;
6
  use Razorpay\Api\Errors;
7
  use Razorpay\Api\Errors\ErrorCode;
@@ -11,7 +12,6 @@ use Razorpay\Api\Errors\ErrorCode;
11
  */
12
  class Request
13
  {
14
-
15
  /**
16
  * Headers to be sent with every http request to the API
17
  * @var array
@@ -28,19 +28,18 @@ class Request
28
  * @return array Response data in array format. Not meant
29
  * to be used directly
30
  */
31
- public function request($method, $url, $data = null)
32
  {
33
- $url = Api::$baseUrl . $url;
34
-
35
- if ($data === null)
36
- $data = array();
37
 
38
  $options = array(
39
- 'auth'=> array(Api::$key, Api::$secret),
40
  'timeout' => 60
41
  );
42
 
43
- $response = \Requests::request($url, self::$headers, $data, $method, $options);
 
 
44
 
45
  $this->checkErrors($response);
46
 
@@ -85,7 +84,8 @@ class Request
85
  $this->throwServerError($body, $httpStatusCode);
86
  }
87
 
88
- if ($httpStatusCode !== 200)
 
89
  {
90
  $this->processError($body, $httpStatusCode, $response);
91
  }
@@ -93,24 +93,10 @@ class Request
93
 
94
  protected function processError($body, $httpStatusCode, $response)
95
  {
96
- if (is_array($body) === false)
97
- {
98
- $this->throwServerError($body, $httpStatusCode);
99
- }
100
-
101
- if ((isset($body['error']) === false) or
102
- (isset($body['error']['code']) === false))
103
- {
104
- $this->throwServerError($body, $httpStatusCode);
105
- }
106
 
107
  $code = $body['error']['code'];
108
 
109
- if (Errors\ErrorCode::exists($code) === false)
110
- {
111
- $this->throwServerError($body, $httpStatusCode);
112
- }
113
-
114
  // We are basically converting the error code to the Error class name
115
  // Replace underscores with space
116
  // Lowercase the words, capitalize first letter of each word
@@ -147,4 +133,77 @@ class Request
147
  ErrorCode::SERVER_ERROR,
148
  $httpStatusCode);
149
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  }
2
 
3
  namespace Razorpay\Api;
4
 
5
+ use Requests;
6
  use Exception;
7
  use Razorpay\Api\Errors;
8
  use Razorpay\Api\Errors\ErrorCode;
12
  */
13
  class Request
14
  {
 
15
  /**
16
  * Headers to be sent with every http request to the API
17
  * @var array
28
  * @return array Response data in array format. Not meant
29
  * to be used directly
30
  */
31
+ public function request($method, $url, $data = array())
32
  {
33
+ $url = Api::getFullUrl($url);
 
 
 
34
 
35
  $options = array(
36
+ 'auth' => array(Api::getKey(), Api::getSecret()),
37
  'timeout' => 60
38
  );
39
 
40
+ $headers = $this->getRequestHeaders();
41
+
42
+ $response = Requests::request($url, $headers, $data, $method, $options);
43
 
44
  $this->checkErrors($response);
45
 
84
  $this->throwServerError($body, $httpStatusCode);
85
  }
86
 
87
+ if (($httpStatusCode < 200) or
88
+ ($httpStatusCode >= 300))
89
  {
90
  $this->processError($body, $httpStatusCode, $response);
91
  }
93
 
94
  protected function processError($body, $httpStatusCode, $response)
95
  {
96
+ $this->verifyErrorFormat($body, $httpStatusCode);
 
 
 
 
 
 
 
 
 
97
 
98
  $code = $body['error']['code'];
99
 
 
 
 
 
 
100
  // We are basically converting the error code to the Error class name
101
  // Replace underscores with space
102
  // Lowercase the words, capitalize first letter of each word
133
  ErrorCode::SERVER_ERROR,
134
  $httpStatusCode);
135
  }
136
+
137
+ protected function getRequestHeaders()
138
+ {
139
+ $uaHeader = array(
140
+ 'User-Agent' => $this->constructUa()
141
+ );
142
+
143
+ $headers = array_merge(self::$headers, $uaHeader);
144
+
145
+ return $headers;
146
+ }
147
+
148
+ protected function constructUa()
149
+ {
150
+ $ua = 'Razorpay/v1 PHPSDK/' . Api::VERSION . ' PHP/' . phpversion();
151
+
152
+ $ua .= ' ' . $this->getAppDetailsUa();
153
+
154
+ return $ua;
155
+ }
156
+
157
+ protected function getAppDetailsUa()
158
+ {
159
+ $appsDetails = Api::$appsDetails;
160
+
161
+ $appsDetailsUa = '';
162
+
163
+ foreach ($appsDetails as $app)
164
+ {
165
+ if ((isset($app['title'])) and (is_string($app['title'])))
166
+ {
167
+ $appUa = $app['title'];
168
+
169
+ if ((isset($app['version'])) and (is_scalar($app['version'])))
170
+ {
171
+ $appUa .= '/' . $app['version'];
172
+ }
173
+
174
+ $appsDetailsUa .= $appUa . ' ';
175
+ }
176
+ }
177
+
178
+ return $appsDetailsUa;
179
+ }
180
+
181
+ /**
182
+ * Verifies error is in proper format. If not then
183
+ * throws ServerErrorException
184
+ *
185
+ * @param array $body
186
+ * @param int $httpStatusCode
187
+ * @return void
188
+ */
189
+ protected function verifyErrorFormat($body, $httpStatusCode)
190
+ {
191
+ if (is_array($body) === false)
192
+ {
193
+ $this->throwServerError($body, $httpStatusCode);
194
+ }
195
+
196
+ if ((isset($body['error']) === false) or
197
+ (isset($body['error']['code']) === false))
198
+ {
199
+ $this->throwServerError($body, $httpStatusCode);
200
+ }
201
+
202
+ $code = $body['error']['code'];
203
+
204
+ if (Errors\ErrorCode::exists($code) === false)
205
+ {
206
+ $this->throwServerError($body, $httpStatusCode);
207
+ }
208
+ }
209
  }
razorpay-sdk/src/Utility.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Razorpay\Api;
4
+
5
+ class Utility
6
+ {
7
+ const SHA256 = 'sha256';
8
+
9
+ public function verifyPaymentSignature($attributes)
10
+ {
11
+ $expectedSignature = $attributes['razorpay_signature'];
12
+ $orderId = $attributes['razorpay_order_id'];
13
+ $paymentId = $attributes['razorpay_payment_id'];
14
+
15
+ $payload = $orderId . '|' . $paymentId;
16
+
17
+ return self::verifySignature($payload, $expectedSignature);
18
+ }
19
+
20
+ public function verifyWebhookSignature($payload, $expectedSignature)
21
+ {
22
+ return self::verifySignature($payload, $expectedSignature);
23
+ }
24
+
25
+ public function verifySignature($payload, $expectedSignature)
26
+ {
27
+ $actualSignature = hash_hmac(self::SHA256, $payload, Api::getSecret());
28
+
29
+ // Use lang's built-in hash_equals if exists to mitigate timing attacks
30
+ if (function_exists('hash_equals'))
31
+ {
32
+ $verified = hash_equals($actualSignature, $expectedSignature);
33
+ }
34
+ else
35
+ {
36
+ $verified = $this->hashEquals($actualSignature, $expectedSignature);
37
+ }
38
+
39
+ if ($verified === false)
40
+ {
41
+ throw new Errors\SignatureVerificationError(
42
+ 'Invalid signature passed');
43
+ }
44
+ }
45
+
46
+ private function hashEquals($actualSignature, $expectedSignature)
47
+ {
48
+ if (strlen($expectedSignature) === strlen($actualSignature))
49
+ {
50
+ $res = $expectedSignature ^ $actualSignature;
51
+ $return = 0;
52
+
53
+ for ($i = strlen($res) - 1; $i >= 0; $i--)
54
+ {
55
+ $return |= ord($res[$i]);
56
+ }
57
+
58
+ return ($return === 0);
59
+ }
60
+
61
+ return false;
62
+ }
63
+ }
readme.txt CHANGED
@@ -37,11 +37,11 @@ This is compatible with WooCommerce>=2.4, including the new 3.0 release.
37
  == Changelog ==
38
 
39
  = 1.4.0 =
40
- * Added Support for WooCommerce 3.x (https://github.com/razorpay/razorpay-woocommerce/pull/35)
41
  * Fixes around discount coupon handling (Order Amount mismatch)
42
  * Updates Razorpay SDK
43
- * Improves Javascript Caching (https://github.com/razorpay/razorpay-woocommerce/pull/39)
44
- * Adds support for mobile browsers (https://github.com/razorpay/razorpay-woocommerce/pull/37):
45
  * Chrome on iOS
46
  * Facebook Browser
47
  * Internet Explorer Mobile
@@ -53,7 +53,7 @@ This is compatible with WooCommerce>=2.4, including the new 3.0 release.
53
 
54
  = 1.3.2 =
55
  * Fixes a Notice about WC_Shortcode_Checkout->output being deprecated
56
- * PR: https://github.com/razorpay/razorpay-woocommerce/pull/28
57
 
58
  = 1.3.1 =
59
  * Improves Session management
37
  == Changelog ==
38
 
39
  = 1.4.0 =
40
+ * Added Support for WooCommerce 3.x ([#35](https://github.com/razorpay/razorpay-woocommerce/pull/35]))
41
  * Fixes around discount coupon handling (Order Amount mismatch)
42
  * Updates Razorpay SDK
43
+ * Improves Javascript Caching ([#39](https://github.com/razorpay/razorpay-woocommerce/pull/39]))
44
+ * Adds support for mobile browsers ([#37](https://github.com/razorpay/razorpay-woocommerce/pull/37]):)
45
  * Chrome on iOS
46
  * Facebook Browser
47
  * Internet Explorer Mobile
53
 
54
  = 1.3.2 =
55
  * Fixes a Notice about WC_Shortcode_Checkout->output being deprecated
56
+ * PR: [#28](https://github.com/razorpay/razorpay-woocommerce/pull/28])
57
 
58
  = 1.3.1 =
59
  * Improves Session management