Issues (26)

src/classes/Instamojo.php (15 issues)

1
<?php namespace IlyasKazi\Instamojo\Classes;
2
3
use App\User;
0 ignored issues
show
The type App\User was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
4
use IlyasKazi\Instamojo\Models\InstamojoPayment;
5
use IlyasKazi\Instamojo\Models\InstamojoRefund;
6
7
use Exception;
8
9
class Instamojo
10
{
11
    const version = '1.1';
12
13
    protected $curl;
14
    protected $endpoint = 'https://www.instamojo.com/api/1.1/';
15
    protected $api_key = null;
16
    protected $auth_token = null;
17
18
    /**
19
    * @param string $api_key
20
    * @param string $auth_token is available on the d
21
    * @param string $endpoint can be set if you are working on an alternative server.
22
    * @return array AuthToken object.
23
    */
24
    public function __construct($api_key, $auth_token=null, $endpoint=null) 
25
    {
26
        $this->api_key = (string) $api_key;
27
        $this->auth_token = (string) $auth_token;
28
        if(!is_null($endpoint)){
29
            $this->endpoint = (string) $endpoint;   
30
        }
31
    }
32
33
    public function __destruct() 
34
    {
35
        if(!is_null($this->curl)) {
36
            curl_close($this->curl);
37
        }
38
    }
39
40
    /**
41
    * @return array headers with Authentication tokens added 
42
    */
43
    private function build_curl_headers() 
44
    {
45
        $headers = array("X-Api-key: $this->api_key");
46
        if($this->auth_token) {
47
            $headers[] = "X-Auth-Token: $this->auth_token";
48
        }
49
        return $headers;        
50
    }
51
    
52
    public static function testme()
53
    {
54
        echo 1;
55
    }
56
57
    /**
58
    * @param string $path
59
    * @return string adds the path to endpoint with.
60
    */
61
    private function build_api_call_url($path)
62
    {
63
        if (strpos($path, '/?') === false and strpos($path, '?') === false) {
64
            return $this->endpoint . $path . '/';
65
        }
66
        return $this->endpoint . $path;
67
68
    }
69
70
    /**
71
    * @param string $method ('GET', 'POST', 'DELETE', 'PATCH')
72
    * @param string $path whichever API path you want to target.
73
    * @param array $data contains the POST data to be sent to the API.
74
    * @return array decoded json returned by API.
75
    */
76
    private function api_call($method, $path, array $data=null) 
77
    {
78
        $path = (string) $path;
79
        $method = (string) $method;
80
        $data = (array) $data;
81
        $headers = $this->build_curl_headers();
82
        $request_url = $this-> build_api_call_url($path);
83
84
        $options = array();
85
        $options[CURLOPT_HTTPHEADER] = $headers;
86
        $options[CURLOPT_RETURNTRANSFER] = true;
87
88
        if($method == 'POST') {
89
            $options[CURLOPT_POST] = 1;
90
            $options[CURLOPT_POSTFIELDS] = http_build_query($data);
91
        } else if($method == 'DELETE') {
92
            $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
93
        } else if($method == 'PATCH') {
94
            $options[CURLOPT_POST] = 1;
95
            $options[CURLOPT_POSTFIELDS] = http_build_query($data);         
96
            $options[CURLOPT_CUSTOMREQUEST] = 'PATCH';
97
        } else if ($method == 'GET' or $method == 'HEAD') {
98
            if (!empty($data)) {
99
                /* Update URL to container Query String of Paramaters */
100
                $request_url .= '?' . http_build_query($data);
101
            }
102
        }
103
        // $options[CURLOPT_VERBOSE] = true;
104
        $options[CURLOPT_URL] = $request_url;
105
        $options[CURLOPT_SSL_VERIFYPEER] = true;
106
        $options[CURLOPT_CAINFO] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem';
107
108
        $this->curl = curl_init();
109
        $setopt = curl_setopt_array($this->curl, $options);
0 ignored issues
show
The assignment to $setopt is dead and can be removed.
Loading history...
It seems like $this->curl can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
        $setopt = curl_setopt_array(/** @scrutinizer ignore-type */ $this->curl, $options);
Loading history...
110
        $response = curl_exec($this->curl);
0 ignored issues
show
It seems like $this->curl can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

110
        $response = curl_exec(/** @scrutinizer ignore-type */ $this->curl);
Loading history...
111
        $headers = curl_getinfo($this->curl);
0 ignored issues
show
The assignment to $headers is dead and can be removed.
Loading history...
It seems like $this->curl can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

111
        $headers = curl_getinfo(/** @scrutinizer ignore-type */ $this->curl);
Loading history...
112
113
        $error_number = curl_errno($this->curl);
0 ignored issues
show
It seems like $this->curl can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
        $error_number = curl_errno(/** @scrutinizer ignore-type */ $this->curl);
Loading history...
114
        $error_message = curl_error($this->curl);
0 ignored issues
show
It seems like $this->curl can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
        $error_message = curl_error(/** @scrutinizer ignore-type */ $this->curl);
Loading history...
115
        $response_obj = json_decode($response, true);
116
117
        if($error_number != 0){
118
            if($error_number == 60){
119
                throw new \Exception("Something went wrong. cURL raised an error with number: $error_number and message: $error_message. " .
120
                    "Please check http://stackoverflow.com/a/21114601/846892 for a fix." . PHP_EOL);
121
            }
122
            else{
123
                throw new \Exception("Something went wrong. cURL raised an error with number: $error_number and message: $error_message." . PHP_EOL);
124
            }
125
        }
126
127
        if($response_obj['success'] == false) {
128
            $message = json_encode($response_obj['message']);
129
            throw new \Exception($message . PHP_EOL);
130
        }
131
        return $response_obj;
132
    }
133
134
    /**
135
    * @return string URL to upload file or cover image asynchronously
136
    */
137
    public function getUploadUrl()
138
    {
139
        $result = $this->api_call('GET', 'links/get_file_upload_url', array());
140
        return $result['upload_url'];
141
    }
142
143
    /**
144
    * @param string $file_path
145
    * @return string JSON returned when the file upload is complete.
146
    */
147
    public function uploadFile($file_path)
148
    {
149
        $upload_url = $this->getUploadUrl();
150
        $file_path = realpath($file_path);
151
        $file_name = basename($file_path);
152
        $ch = curl_init();
153
        $data = array('fileUpload' => $this->getCurlValue($file_path, $file_name));
154
        curl_setopt($ch, CURLOPT_URL, $upload_url);
0 ignored issues
show
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
        curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, $upload_url);
Loading history...
155
        curl_setopt($ch, CURLOPT_POST, 1);
156
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
157
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
158
        return curl_exec($ch);
0 ignored issues
show
Bug Best Practice introduced by
The expression return curl_exec($ch) also could return the type boolean which is incompatible with the documented return type string.
Loading history...
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

158
        return curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
159
    }
160
161
    public function getCurlValue($file_path, $file_name, $content_type='')
162
    {
163
        // http://stackoverflow.com/a/21048702/846892
164
        // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
165
        // See: https://wiki.php.net/rfc/curl-file-upload
166
        if (function_exists('curl_file_create')) {
167
            return curl_file_create($file_path, $content_type, $file_name);
168
        }
169
170
        // Use the old style if using an older version of PHP
171
        $value = "@{$file_path};filename=$file_name";
172
        if ($content_type) {
173
            $value .= ';type=' . $content_type;
174
        }
175
176
        return $value;
177
    }
178
179
    /**
180
    * Uploads any file or cover image mentioned in $link and 
181
    * updates it with the json required by the API.
182
    * @param array $link
183
    * @return array $link updated with uploaded file information if applicable.
184
    */
185
    public function uploadMagic(array $link)
186
    {
187
        if(!empty($link['file_upload'])) {
188
            $file_upload_json = $this->uploadFile($link['file_upload']);
189
            $link['file_upload_json'] = $file_upload_json;
190
            unset($link['file_upload']);
191
        }
192
        if(!empty($link['cover_image'])) {
193
            $cover_image_json = $this->uploadFile($link['cover_image']);
194
            $link['cover_image_json'] = $cover_image_json;
195
            unset($link['cover_image']);
196
        }
197
        return $link;        
198
    }
199
200
    /**
201
    * Authenticate using username and password of a user.
202
    * Automatically updates the auth_token value.
203
    * @param array $args contains username=>USERNAME and password=PASSWORD 
204
    * @return array AuthToken object.
205
    */
206
    public function auth(array $args)
207
    {
208
        $response = $this->api_call('POST', 'auth', $args);
209
        $this->auth_token = $response['auth_token']['auth_token']; 
210
        return $this->auth_token; 
211
    }
212
213
    /**
214
    * @return array list of Link objects.
215
    */
216
    public function linksList() 
217
    {
218
        $response = $this->api_call('GET', 'links', array());   
219
        return $response['links'];
220
    }
221
222
    /**
223
    * @return array single Link object.
224
    */  
225
    public function linkDetail($slug) 
226
    {
227
        $response = $this->api_call('GET', 'links/' . $slug, array()); 
228
        return $response['link'];
229
    }
230
231
    /**
232
    * @return array single Link object.
233
    */  
234
    public function linkCreate(array $link) 
235
    {   
236
        if(empty($link['currency'])){
237
            $link['currency'] = 'INR';
238
        }
239
        $link = $this->uploadMagic($link);
240
        $response = $this->api_call('POST', 'links', $link);
241
        return $response['link'];
242
    }
243
244
    /**
245
    * @return array single Link object.
246
    */  
247
    public function linkEdit($slug, array $link) 
248
    {
249
        $link = $this->uploadMagic($link);
250
        $response = $this->api_call('PATCH', 'links/' . $slug, $link);
251
        return $response['link'];
252
    }
253
254
    /**
255
    * @return array single Link object.
256
    */  
257
    public function linkDelete($slug) 
258
    {
259
        $response = $this->api_call('DELETE', 'links/' . $slug, array());
260
        return $response;
261
    }
262
263
    /**
264
    * @return array list of Payment objects.
265
    */  
266
    public function paymentsList($limit = null, $page = null) 
267
    {
268
        $params = array();
269
        if (!is_null($limit)) {
270
            $params['limit'] = $limit;
271
        }
272
273
        if (!is_null($page)) {
274
            $params['page'] = $page;
275
        }
276
277
        $response = $this->api_call('GET', 'payments', $params);
278
        return $response['payments'];
279
    }
280
281
    /**
282
    * @param string payment_id as provided by paymentsList() or Instamojo's webhook or redirect functions.
0 ignored issues
show
The type IlyasKazi\Instamojo\Classes\payment_id was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
283
    * @return array single Payment object.
284
    */  
285
    public function paymentDetail($payment_id) 
286
    {
287
        $response = $this->api_call('GET', 'payments/' . $payment_id, array()); 
288
        return $response['payment'];
289
    }
290
291
292
    /////   Request a Payment  /////
293
294
    /**
295
    * @param array single PaymentRequest object.
0 ignored issues
show
The type IlyasKazi\Instamojo\Classes\single was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
296
    * @return array single PaymentRequest object.
297
    */
298
    public function paymentRequestCreate(array $payment_request) 
299
    {
300
        $response = $this->api_call('POST', 'payment-requests', $payment_request); 
301
        return $response['payment_request'];
302
    }
303
304
    /**
305
    * @param string id as provided by paymentRequestCreate, paymentRequestsList, webhook or redirect.
0 ignored issues
show
The type IlyasKazi\Instamojo\Classes\id was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
306
    * @return array single PaymentRequest object.
307
    */
308
    public function paymentRequestStatus($id) 
309
    {
310
        $response = $this->api_call('GET', 'payment-requests/' . $id, array()); 
311
        return $response['payment_request'];
312
    }
313
314
    /**
315
    * @param string id as provided by paymentRequestCreate, paymentRequestsList, webhook or redirect.
316
    * @param string payment_id as received with the redirection URL or webhook.
317
    * @return array single PaymentRequest object.
318
    */
319
    public function paymentRequestPaymentStatus($id, $payment_id) 
320
    {
321
        $response = $this->api_call('GET', 'payment-requests/' . $id . '/' . $payment_id, array()); 
322
        return $response['payment_request'];
323
    }
324
325
326
    /**
327
    * @param array datetime_limits containing datetime data with keys 'max_created_at', 'min_created_at',
0 ignored issues
show
The type IlyasKazi\Instamojo\Classes\datetime_limits was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
328
    * 'min_modified_at' and 'max_modified_at' in ISO 8601 format(optional).
329
    * @return array containing list of PaymentRequest objects.
330
    * For more information on the allowed date formats check the
331
    * docs: https://www.instamojo.com/developers/request-a-payment-api/#toc-filtering-payment-requests
332
    */
333
    public function paymentRequestsList($datetime_limits=null) 
334
    {
335
        $endpoint = 'payment-requests';
336
337
        if(!empty($datetime_limits)){
338
            $query_string = http_build_query($datetime_limits);
339
340
            if(!empty($query_string)){
341
                $endpoint .= '/?' . $query_string;
342
            }
343
        }
344
        $response = $this->api_call('GET', $endpoint, array()); 
345
        return $response['payment_requests'];
346
    }
347
348
349
    /////   Refunds  /////
350
351
    /**
352
    * @param array single Refund object.
353
    * @return array single Refund object.
354
    */
355
    public function refundCreate(array $refund) 
356
    {
357
        $response = $this->api_call('POST', 'refunds', $refund); 
358
        return $response['refund'];
359
    }
360
361
    /**
362
    * @param string id as provided by refundCreate or refundsList.
363
    * @return array single Refund object.
364
    */
365
    public function refundDetail($id) 
366
    {
367
        $response = $this->api_call('GET', 'refunds/' . $id, array()); 
368
        return $response['refund'];
369
    }
370
371
    /**
372
    * @return array containing list of Refund objects.
373
    */
374
    public function refundsList() 
375
    {
376
        $response = $this->api_call('GET', 'refunds', array()); 
377
        return $response['refunds'];
378
    }
379
380
}
381