From 40b0588037d7046cf90ceeb394f054939606ae8c Mon Sep 17 00:00:00 2001 From: Luke Holder Date: Tue, 21 Apr 2020 20:16:05 +0800 Subject: [PATCH 1/5] Fix namespace --- src/Message/CompletePurchaseResponse.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Message/CompletePurchaseResponse.php b/src/Message/CompletePurchaseResponse.php index b0a4aad..a846bdd 100644 --- a/src/Message/CompletePurchaseResponse.php +++ b/src/Message/CompletePurchaseResponse.php @@ -2,7 +2,9 @@ namespace Omnipay\Paystack\Message; -class CompletePurchaseResponse extends \Omnipay\Common\Message\AbstractResponse +use Omnipay\Common\Message\AbstractResponse; + +class CompletePurchaseResponse extends AbstractResponse { public function isSuccessful() From 9918a7329a83761fc2f846a2e6aff893410e4155 Mon Sep 17 00:00:00 2001 From: Luke Holder Date: Tue, 16 Jun 2020 08:46:55 +0800 Subject: [PATCH 2/5] WIP --- src/Gateway.php | 10 ++++- src/Message/AbstractRequest.php | 9 +++++ src/Message/CompletePurchaseRequest.php | 8 +--- src/Message/PurchaseRequest.php | 19 +++++----- src/Message/PurchaseResponse.php | 1 - src/Message/RefundRequest.php | 48 ++++++++++++++++++++++++ src/Message/RefundResponse.php | 49 +++++++++++++++++++++++++ tests/GatewayTest.php | 5 +-- 8 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 src/Message/RefundRequest.php create mode 100644 src/Message/RefundResponse.php diff --git a/src/Gateway.php b/src/Gateway.php index dff28b8..7a995f1 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -5,7 +5,7 @@ use Omnipay\Common\AbstractGateway; use Omnipay\Paystack\Message\CompletePurchaseRequest; use Omnipay\Paystack\Message\PurchaseRequest; -use Omnipay\Paystack\Message\PurchaseResponse; +use Omnipay\Paystack\Message\RefundRequest; /** * PayStack Gateway @@ -81,4 +81,12 @@ public function completePurchase(array $parameters = []) { return $this->createRequest(CompletePurchaseRequest::class, $parameters); } + + /** + * @inheritDoc + */ + public function refund(array $parameters = []) + { + return $this->createRequest(RefundRequest::class, $parameters); + } } diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index f3f14fb..7f7ceec 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -37,4 +37,13 @@ public function setSecretKey($value) { $this->setParameter('secret_key', $value); } + + public function getRequestHeaders() + { + return [ + 'Authorization' => 'Bearer ' . $this->getSecretKey(), + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache' + ]; + } } diff --git a/src/Message/CompletePurchaseRequest.php b/src/Message/CompletePurchaseRequest.php index 30e43b5..d6d5bf9 100644 --- a/src/Message/CompletePurchaseRequest.php +++ b/src/Message/CompletePurchaseRequest.php @@ -28,13 +28,7 @@ public function getData() public function sendData($data) { try { - $headers = [ - 'Authorization' => 'Bearer ' . $this->getSecretKey(), - 'Content-Type' => 'application/json', - 'Cache-Control' => 'no-cache' - ]; - - $response = $this->httpClient->request('GET', $this->getApiEndpoint(), $headers, json_encode($data)); + $response = $this->httpClient->request('GET', $this->getApiEndpoint(), $this->getRequestHeaders(), json_encode($data)); $responseData = json_decode((string)$response->getBody(), true); } catch (\Exception $e) { throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e); diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index 9a2d765..367c909 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -23,14 +23,19 @@ public function getData() $amount = $this->getAmountInteger(); $email = $this->getParameter('email'); - $reference = $this->getTransactionReference(); - return [ + $data = [ 'amount' => $amount, 'email' => $email, 'callback_url' => $this->getReturnUrl(), - 'reference' => $reference + 'metadata' => $this->getParameter('metadata') ]; + + if ($reference = $this->getTransactionReference()) { + $data['reference'] = $reference; + } + + return $data; } /** @@ -39,13 +44,7 @@ public function getData() public function sendData($data) { try { - $headers = [ - 'Authorization' => 'Bearer ' . $this->getSecretKey(), - 'Content-Type' => 'application/json', - 'Cache-Control' => 'no-cache' - ]; - - $response = $this->httpClient->request('POST', $this->getApiEndpoint(), $headers, json_encode($data)); + $response = $this->httpClient->request('POST', $this->getApiEndpoint(), $this->getRequestHeaders(), json_encode($data)); $responseData = json_decode((string)$response->getBody(), true); } catch (\Exception $e) { throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e); diff --git a/src/Message/PurchaseResponse.php b/src/Message/PurchaseResponse.php index d89a052..6ff11b3 100644 --- a/src/Message/PurchaseResponse.php +++ b/src/Message/PurchaseResponse.php @@ -7,7 +7,6 @@ class PurchaseResponse extends AbstractResponse implements RedirectResponseInterface { - public function isSuccessful() { return false; diff --git a/src/Message/RefundRequest.php b/src/Message/RefundRequest.php new file mode 100644 index 0000000..e48604d --- /dev/null +++ b/src/Message/RefundRequest.php @@ -0,0 +1,48 @@ +baseApiEndpoint . '/refund'; + } + + /** + * @inheritdoc + */ + public function getData() + { + $amount = $this->getAmountInteger(); + $reference = $this->getTransactionReference(); + + $data = ['transaction' => $reference]; + + if ($amount) { + $data['amount'] = $amount; + } + + return $data; + } + + /** + * @inheritdoc + */ + public function sendData($data) + { + try { + $response = $this->httpClient->request('POST', $this->getApiEndpoint(), $this->getRequestHeaders(), json_encode($data)); + $responseData = json_decode((string)$response->getBody(), true); + } catch (\Exception $e) { + throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e); + } + + return $this->response = new RefundResponse($this, $responseData); + } +} diff --git a/src/Message/RefundResponse.php b/src/Message/RefundResponse.php new file mode 100644 index 0000000..5e8e1b9 --- /dev/null +++ b/src/Message/RefundResponse.php @@ -0,0 +1,49 @@ +data['message']) && $message = $this->data['message']) { + return $message; + } + + return ''; + } + + public function getCode() + { + if (isset($this->data['data']) && $data = $this->data['data']) { + return $data['access_code']; + } + + return ''; + } + + public function getTransactionReference() + { + if (isset($this->data['data']) && $data = $this->data['data']) { + if(isset($data['transaction']) && $transaction = $data['transaction']) + { + return $transaction['id']; + } + } + + return ''; + } +} diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 365f356..04eb6d9 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -20,7 +20,7 @@ public function setUp() $this->gateway = new Gateway($this->getHttpClient(), $this->getHttpRequest()); $this->options = [ - 'amount' => '100', + 'amount' => '2500', 'reference' => static::PURCHASE_REFERENCE ]; } @@ -30,8 +30,7 @@ public function testPurchase() $this->setMockHttpResponse('PurchaseSuccess.txt'); $options = array_merge($this->options, [ - 'email' => 'email@email.com', - 'reference' => static::PURCHASE_REFERENCE + 'email' => 'email@email.com' ]); $response = $this->gateway->purchase($options)->send(); From 2748d03e8bffdc6635edd8442fc3eb7a0fe16f2e Mon Sep 17 00:00:00 2001 From: Luke Holder Date: Tue, 16 Jun 2020 09:07:36 +0800 Subject: [PATCH 3/5] Fix tests --- src/Message/RefundRequest.php | 5 ++--- src/Message/RefundResponse.php | 12 +++++++++--- tests/GatewayTest.php | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Message/RefundRequest.php b/src/Message/RefundRequest.php index e48604d..5f15eca 100644 --- a/src/Message/RefundRequest.php +++ b/src/Message/RefundRequest.php @@ -37,12 +37,11 @@ public function getData() public function sendData($data) { try { - $response = $this->httpClient->request('POST', $this->getApiEndpoint(), $this->getRequestHeaders(), json_encode($data)); - $responseData = json_decode((string)$response->getBody(), true); + $response = $this->sendRequest('POST', $this->getApiEndpoint(), $data); } catch (\Exception $e) { throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e); } - return $this->response = new RefundResponse($this, $responseData); + return $this->response = new RefundResponse($this, $response); } } diff --git a/src/Message/RefundResponse.php b/src/Message/RefundResponse.php index 5e8e1b9..7c95480 100644 --- a/src/Message/RefundResponse.php +++ b/src/Message/RefundResponse.php @@ -9,6 +9,13 @@ class RefundResponse extends AbstractResponse public function isSuccessful() { + + if (isset($this->data['data']) && $transaction = $this->data['data']['transaction']) { + if (isset($transaction['status']) && $transaction['status'] == 'reversed') { + return true; + } + } + return false; } @@ -38,9 +45,8 @@ public function getCode() public function getTransactionReference() { if (isset($this->data['data']) && $data = $this->data['data']) { - if(isset($data['transaction']) && $transaction = $data['transaction']) - { - return $transaction['id']; + if (isset($data['transaction']) && $transaction = $data['transaction']) { + return $transaction['reference']; } } diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 04eb6d9..4ed4dc4 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -13,6 +13,12 @@ class GatewayTest extends GatewayTestCase /** @var Gateway */ protected $gateway; + /** @var array */ + protected $options; + + /** + * + */ public function setUp() { parent::setUp(); @@ -25,6 +31,9 @@ public function setUp() ]; } + /** + * + */ public function testPurchase() { $this->setMockHttpResponse('PurchaseSuccess.txt'); @@ -36,10 +45,17 @@ public function testPurchase() $response = $this->gateway->purchase($options)->send(); $this->assertTrue($response->isRedirect(), 'Purchase response is a redirect'); - $this->assertEquals(static::PURCHASE_REFERENCE, $response->getTransactionReference(), 'Reference is as we gave it.'); + $this->assertEquals( + static::PURCHASE_REFERENCE, + $response->getTransactionReference(), + 'Reference is as we gave it.' + ); $this->assertEquals('Authorization URL created', $response->getMessage()); } + /** + * + */ public function testRefund() { $this->setMockHttpResponse('RefundSuccess.txt'); From b25ea5594c4a84b264412d80bdfdd0360f72ffc6 Mon Sep 17 00:00:00 2001 From: Luke Holder Date: Tue, 16 Jun 2020 09:10:52 +0800 Subject: [PATCH 4/5] Only require php 7 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index db821e7..461fc54 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.0", "omnipay/common": "^3.0" }, "require-dev": { From f5507dd9746ac4bd1f6ab7c8b151513993c93558 Mon Sep 17 00:00:00 2001 From: Luke Holder Date: Tue, 16 Jun 2020 10:27:18 +0800 Subject: [PATCH 5/5] Fix URL --- src/Message/AbstractRequest.php | 3 +-- src/Message/CompletePurchaseRequest.php | 7 +++---- src/Message/PurchaseRequest.php | 4 +++- src/Message/RefundRequest.php | 13 ++++++------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index b0d8da6..fbc9bec 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -2,12 +2,11 @@ namespace Omnipay\Paystack\Message; -use Omnipay\Common\Exception\BadMethodCallException; use Omnipay\Common\Exception\InvalidRequestException; abstract class AbstractRequest extends \Omnipay\Common\Message\AbstractRequest { - protected $baseApiEndpoint = 'https://api.paystack.co/'; + protected $baseApiEndpoint = 'https://api.paystack.co'; /** * @return string The URL endpoint for the request diff --git a/src/Message/CompletePurchaseRequest.php b/src/Message/CompletePurchaseRequest.php index 637f5e4..538acd9 100644 --- a/src/Message/CompletePurchaseRequest.php +++ b/src/Message/CompletePurchaseRequest.php @@ -11,7 +11,7 @@ class CompletePurchaseRequest extends AbstractRequest */ public function getApiEndpoint() { - return $this->baseApiEndpoint . 'transaction/verify/' . rawurlencode($this->getTransactionReference()); + return '/transaction/verify/' . rawurlencode($this->getTransactionReference()); } /** @@ -28,12 +28,11 @@ public function getData() public function sendData($data) { try { - $response = $this->sendRequest('GET', $this->getApiEndpoint(), json_encode($data)); + $response = $this->sendRequest('GET', $this->getApiEndpoint(), $data); } catch (\Exception $e) { - throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e); } - return $this->response = new CompletePurchaseResponse($this, $responseData); + return $this->response = new CompletePurchaseResponse($this, $response); } } \ No newline at end of file diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index 27f8407..70d9712 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -11,7 +11,7 @@ class PurchaseRequest extends AbstractRequest */ public function getApiEndpoint() { - return $this->baseApiEndpoint . '/transaction/initialize/'; + return '/transaction/initialize'; } /** @@ -26,7 +26,9 @@ public function getData() return [ 'amount' => $amount, + 'currency' => $this->getCurrency(), 'email' => $email, + 'reference' => $this->getTransactionReference(), 'callback_url' => $this->getReturnUrl(), 'metadata' => $this->getParameter('metadata') ]; diff --git a/src/Message/RefundRequest.php b/src/Message/RefundRequest.php index 5f15eca..82c458e 100644 --- a/src/Message/RefundRequest.php +++ b/src/Message/RefundRequest.php @@ -11,7 +11,7 @@ class RefundRequest extends AbstractRequest */ public function getApiEndpoint() { - return $this->baseApiEndpoint . '/refund'; + return '/refund'; } /** @@ -19,13 +19,12 @@ public function getApiEndpoint() */ public function getData() { - $amount = $this->getAmountInteger(); - $reference = $this->getTransactionReference(); + $data = []; + $data['transaction'] = $this->getTransactionReference(); + $data['currency'] = $this->getCurrency(); - $data = ['transaction' => $reference]; - - if ($amount) { - $data['amount'] = $amount; + if ($this->getAmountInteger()) { + $data['amount'] = $this->getAmountInteger(); } return $data;