Skip to content

Commit d799712

Browse files
committed
Version 2.0
- Throw cURL error - Throw Paystack API errors - Add methods for Page and Subscription - Change getOne to fetch - Allow pluralised listing - When using Guzzle, throw errors as long as there's no response - Remove all test files. intend to write properly
1 parent bb3faf1 commit d799712

19 files changed

Lines changed: 428 additions & 507 deletions

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ All Notable changes to `paystack-php` will be documented in this file.
44

55
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
66

7+
## 2.0 - 2016-04-26
8+
9+
### Changes
10+
- Calls will return an Object of stdClass or throw a Paystack API/cURL error instead of
11+
an array as in version 1
12+
13+
### Added
14+
- Pages
15+
- Subscriptions
16+
- Use ->fetch to get a single item or call singular form with id/code
17+
- use ->list to get a list of items or call plural form with paging parameters
18+
19+
### Added usage of TLSv1.2
20+
CURL default SSL version TLSv1.2
21+
Update Requirements for Curl, OpenSSL and PHP
22+
define `CURL_SSLVERSION_TLSv1_2` as 6 if not found, to avoid not defined error
23+
724
## 1.0.2 - 2016-03-10
825

926
### Added usage of TLSv1.2

README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ require 'path/to/src/Paystack.php';
3333
\YabaCon\Paystack::registerAutoloader();
3434
```
3535

36+
## IMPORTANT
37+
Version 2 is not compatible with version 1 code! It throws an error if there's problem error in cURL
38+
or if the Paystack API gives a false status in the response body.
39+
3640
## Usage
3741

3842
Check [ibrahimlawal/paystack-php-sample](https://github.com/ibrahimlawal/paystack-php-sample) for a sample donation page that uses this library
@@ -42,27 +46,32 @@ Check [ibrahimlawal/paystack-php-sample](https://github.com/ibrahimlawal/paystac
4246
$paystack = new \YabaCon\Paystack('secret_key');
4347

4448
// Make a call to the resource/method
45-
// $paystack->{resource}->{method}();
49+
// $paystack->{resource}->{method}();
50+
51+
// Shortcuts
4652
// for gets, use $paystack->{resource}(id)
53+
// for list, use $paystack->{resource}s()
4754

4855
// $headers is an array of header values.
49-
// $body is an array created from json_decoding response
50-
list($headers, $body, $code) = $paystack->customer(12);
51-
list($headers, $body, $code) = $paystack->customer->list();
52-
list($headers, $body, $code) = $paystack->customer->list(['perPage'=>5,'page'=>2]); // list the second page at 5 customers per page
56+
// $response is an stdClass object created from json_decoding response
57+
$response = $paystack->customer(12);
58+
$response = $paystack->customer->fetch(12);
59+
$response = $paystack->customers();
60+
$response = $paystack->customer->list();
61+
$response = $paystack->customer->list(['perPage'=>5,'page'=>2]); // list the second page at 5 customers per page
5362

54-
list($headers, $body, $code) = $paystack->customer->create([
63+
$response = $paystack->customer->create([
5564
'first_name'=>'Dafe',
5665
'last_name'=>'Aba',
5766
'email'=>"dafe@aba.c",
5867
'phone'=>'08012345678'
5968
]);
60-
list($headers, $body, $code) = $paystack->transaction->initialize([
69+
$response = $paystack->transaction->initialize([
6170
'reference'=>'unique_refencecode',
6271
'amount'=>'120000',
6372
'email'=>'dafe@aba.c'
6473
]);
65-
list($headers, $body, $code) = $paystack->transaction->verify([
74+
$response = $paystack->transaction->verify([
6675
'reference'=>'refencecode'
6776
]);
6877
```
@@ -84,7 +93,10 @@ $paystack->useGuzzle();
8493

8594
// Make a call to the resource/method
8695
// $paystack->{resource}->{method}();
96+
97+
// Shortcuts
8798
// for gets, use $paystack->{resource}(id)
99+
// for list, use $paystack->{resource}s()
88100

89101
// $response is a GuzzleHttp\Psr7\Response Object
90102
$response = $paystack->customer(12);

SAMPLES.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ configured the $paystack object as you want. Check [README](README.md) for detai
1111
// customer
1212
$paystack->customer(12);
1313
$paystack->customer->list();
14+
$paystack->customer->fetch(12);
15+
$paystack->customers();
1416
$paystack->customer->create([
1517
'first_name'=>'name',
1618
'last_name'=>'name',
@@ -28,6 +30,8 @@ $paystack->customer->list(['perPage'=>5,'page'=>2]); // list the second page at
2830

2931
// plan
3032
$paystack->plan(12);
33+
$paystack->plans();
34+
$paystack->plan->fetch("PLNxxx");
3135
$paystack->plan->list();
3236
$paystack->plan->create([
3337
'name'=>'name',
@@ -45,15 +49,46 @@ $paystack->plan->update([
4549
'name'=>'name',
4650
'description'=>'Describe at length',
4751
'amount'=>1000, // in kobo
48-
'interval'=>7,
52+
'interval'=>'weekly',
4953
'send_invoices'=>true,
5054
'send_sms'=>true,
5155
'hosted_page'=>'url',
5256
'hosted_page_url'=>'url',
5357
'hosted_page_summary'=>'details',
5458
'currency'=>'NGN'
5559
],['id'=>233]);
56-
$paystack->plan->list(['perPage'=>5,'page'=>2]); // list the second page at 5 plans per page
60+
$paystack->plan->list(['perPage'=>5,'page'=>2]); // list the second page at 5 per page
61+
62+
// page
63+
$paystack->page(12);
64+
$paystack->pages();
65+
$paystack->page->fetch(12);
66+
$paystack->page->list();
67+
$paystack->page->create([
68+
'name'=>'name',
69+
'description'=>'Describe at length',
70+
'amount'=>1000
71+
]);
72+
$paystack->page->update([
73+
'name'=>'name',
74+
'description'=>'Describe at length'],['id'=>233]);
75+
$paystack->page->list(['perPage'=>5,'page'=>2]); // list the second page at 5 per page
76+
77+
// page
78+
$paystack->subscription(12);
79+
$paystack->subscription();
80+
$paystack->subscription->fetch(12);
81+
$paystack->subscription->list();
82+
$paystack->subscription->create([
83+
'plan'=>'PLN_xxxx',
84+
'customer'=>'CUS_xxxxx',
85+
'authorization'=>'AUTH_xxx'
86+
]);
87+
$paystack->subscription->disable([
88+
'code'=>'',
89+
'token'=>''],['id'=>233]);
90+
$paystack->subscription->list(['perPage'=>5,'page'=>2]); // list the second page at 5 per page
91+
$paystack->subscriptions(['perPage'=>5,'page'=>2]); // list the second page at 5 per page
5792

5893
// transaction
5994
$paystack->transaction(12);

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22

33
- Proper resource examples - [SAMPLES.md](SAMPLES.md)
44
- Tests
5-
- Additional functions for common tasks
65
- Paystack Exception Classes and throwing

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
"guzzlehttp/guzzle": "Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. While not required by Paystack-PHP, installing it will provide you a more object-oriented experience. Also note that when Guzzle is installed, the result from API calls will be a GuzzleHttp\\Psr7\\Response Object"
3030
},
3131
"require-dev": {
32-
"phpunit/phpunit": "4.*",
33-
"scrutinizer/ocular": "~1.1",
32+
"phpunit/phpunit": "^4.*",
33+
"scrutinizer/ocular": "^1.1",
3434
"guzzlehttp/guzzle": "^6.1",
35-
"squizlabs/php_codesniffer": "~2.3",
35+
"squizlabs/php_codesniffer": "^2.3",
3636
"vlucas/phpdotenv": "^2.2"
3737
},
3838
"autoload": {
@@ -50,7 +50,7 @@
5050
},
5151
"extra": {
5252
"branch-alias": {
53-
"dev-master": "1.0.8-dev"
53+
"dev-master": "2.0.1-dev"
5454
}
5555
}
5656
}

src/Paystack.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private function definedRoutes()
6464
}
6565
/**
6666
* __call
67-
* Magic Method for getOne on routes
67+
* Magic Method for fetch on routes
6868
*
6969
* @param $method - a string whose title case is a class in the
7070
* YabaCon\Paystack\Routes namespace implementing
@@ -80,27 +80,34 @@ private function definedRoutes()
8080
public function __call($method, $args)
8181
{
8282
/*
83-
attempt to call getOne when the route is called directly
83+
attempt to call fetch when the route is called directly
8484
translates to /{root}/{get}/{id}
8585
*/
86-
if (in_array($method, $this->routes, true)) {
86+
87+
if (in_array($method, $this->routes, true) && count($args) === 1) {
8788
$route = new Router($method, $this);
88-
89-
if (count($args) === 1 && is_integer($args[0])) {
90-
// no params, just one arg... the id
91-
$args = [[], [ Router::ID_KEY => $args[0] ] ];
92-
return $route->__call('getOne', $args);
93-
} elseif (count($args) === 2 && is_integer($args[0]) && is_array($args[1])) {
94-
// there are params, and just one arg... the id
95-
$args = [$args[1], [ Router::ID_KEY => $args[0] ] ];
96-
return $route->__call('getOne', $args);
89+
// no params, just one arg... the id
90+
$args = [[], [ Router::ID_KEY => $args[0] ] ];
91+
return $route->__call('fetch', $args);
92+
}
93+
94+
// Not found is it plural?
95+
$is_plural = strripos($method, 's')===(strlen($method)-1);
96+
$singular_form = substr($method, 0, strlen($method)-1);
97+
98+
if ($is_plural && in_array($singular_form, $this->routes, true)) {
99+
$route = new Router($singular_form, $this);
100+
if ((count($args) === 1 && is_array($args[0]))||(count($args) === 0)) {
101+
return $route->__call('getList', $args);
97102
}
98103
}
104+
99105
// Should never get here
100106
throw new \InvalidArgumentException(
101-
'Route "' .
102-
$method .
103-
'" only accepts an integer id and an optional array of paging arguments.'
107+
'Route "' . $method . '" can only accept '.
108+
($is_plural ?
109+
'an optional array of paging arguments (perPage, page)'
110+
: 'an id or code') . '.'
104111
);
105112
}
106113

src/Paystack/Helpers/Router.php

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace YabaCon\Paystack\Helpers;
44

55
use \Closure;
6-
use Guzzle\Http\Exception\RequestException;
76
use \YabaCon\Paystack\Contracts\RouteInterface;
87

98
/**
@@ -31,9 +30,6 @@ class Router
3130

3231
const ID_KEY = 'id';
3332
const PAYSTACK_API_ROOT = 'https://api.paystack.co';
34-
const HEADER_KEY = 'header';
35-
const HTTP_CODE_KEY = 'httpcode';
36-
const BODY_KEY = 'body';
3733

3834
/**
3935
* moveArgsToSentargs
@@ -137,11 +133,11 @@ private function callViaCurl($interface, $payload = [ ], $sentargs = [ ])
137133
$client = new \GuzzleHttp\Client();
138134
try {
139135
$response = $client->send($request);
140-
} catch (\GuzzleHttp\Exception\RequestException $e) {
136+
} catch (\Exception $e) {
141137
if ($e->hasResponse()) {
142138
$response = $e->getResponse();
143139
} else {
144-
$response = null;
140+
throw $e;
145141
}
146142
}
147143
return $response;
@@ -166,8 +162,7 @@ private function callViaCurl($interface, $payload = [ ], $sentargs = [ ])
166162
}
167163
\curl_setopt($ch, \CURLOPT_HTTPHEADER, $flattened_headers);
168164
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
169-
\curl_setopt($ch, \CURLOPT_HEADER, 1);
170-
165+
171166
// Make sure CURL_SSLVERSION_TLSv1_2 is defined as 6
172167
// Curl must be able to use TLSv1.2 to connect
173168
// to Paystack servers
@@ -181,43 +176,25 @@ private function callViaCurl($interface, $payload = [ ], $sentargs = [ ])
181176

182177
if (\curl_errno($ch)) { // should be 0
183178
// curl ended with an error
179+
$cerr = \curl_error($ch);
184180
\curl_close($ch);
185-
return [[],[],0];
181+
throw new \Exception("Curl failed with response: '" . $cerr . "'.");
186182
}
187183

188-
$code = \curl_getinfo($ch, \CURLINFO_HTTP_CODE);
189-
190184
// Then, after your \curl_exec call:
191-
$header_size = \curl_getinfo($ch, \CURLINFO_HEADER_SIZE);
192-
$header = substr($response, 0, $header_size);
193-
$header = $this->headersFromLines(explode("\n", trim($header)));
194-
$body = substr($response, $header_size);
195-
$body = json_decode($body, true);
196-
197-
185+
$resp = json_decode($response);
198186
//close connection
199187
\curl_close($ch);
200188

201-
return [
202-
0 => $header, 1 => $body, 2=> $code,
203-
Router::HEADER_KEY => $header, Router::BODY_KEY => $body,
204-
Router::HTTP_CODE_KEY=>$code];
189+
if (!$resp->status) {
190+
throw new \Exception("Paystack Request failed with response: '" . $resp->message . "'.");
191+
}
192+
193+
return $resp;
205194
}
206195

207196
}
208197

209-
private function headersFromLines($lines)
210-
{
211-
$headers = [];
212-
foreach ($lines as $line) {
213-
$parts = explode(':', $line, 2);
214-
$headers[trim($parts[0])][] = isset($parts[1])
215-
? trim($parts[1])
216-
: null;
217-
}
218-
return $headers;
219-
}
220-
221198
/**
222199
* __call
223200
* Insert description here
@@ -239,7 +216,7 @@ public function __call($methd, $sentargs)
239216
return call_user_func_array($this->methods[$method], $sentargs);
240217
} else {
241218
// User attempted to call a function that does not exist
242-
throw new \Exception('Function "' . $method . '" does not exist for "' . $this->route . "'.");
219+
throw new \Exception('Function "' . $method . '" does not exist for "' . $this->route . '".');
243220
}
244221
}
245222

src/Paystack/Routes/Customer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ public static function create()
5454
}
5555

5656
/**
57-
Get customer
57+
Get customer by ID or code
5858
*/
59-
public static function getOne()
59+
public static function fetch()
6060
{
6161
return [
6262
RouteInterface::METHOD_KEY => RouteInterface::GET_METHOD,

0 commit comments

Comments
 (0)