Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve response handling #18

Merged
merged 2 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ This packages comes with the following tables
- `pesapal_tokens` - to store the `access_token` and `expires_at` for the Pesapal API
- `pesapal_ipns` - to store the Instant Payment Notifications

Publish and run the migrations with:
Publish and run the migrations

```bash
php artisan vendor:publish --tag="pesapal-migrations"
php artisan migrate
```

You can publish the config file with:
You can optionally publish the config file

```bash
php artisan vendor:publish --tag="pesapal-config"
Expand Down Expand Up @@ -84,8 +84,11 @@ class Kernel extends ConsoleKernel

```php
# Laravel 11 -> routes/console.php
Schedule::call('pesapal:auth')->everyFourMinutes();
Schedule::call('model:prune')->everyFiveMinutes();
use Illuminate\Support\Facades\Schedule;
use NjoguAmos\Pesapal\Models\PesapalToken;

Schedule::command('pesapal:auth')->everyFourMinutes();
Schedule::command('model:prune', ['--model' => [PesapalToken::class]])->everyFiveMinutes();
```

You can also call the `createToken' in `Pesapal` class directly to generate the `access_token`. The method will return null or an new `PesapalToken` instance.
Expand Down
3 changes: 2 additions & 1 deletion src/Commands/PesapalAuthCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace NjoguAmos\Pesapal\Commands;

use NjoguAmos\Pesapal\Models\PesapalToken;
use NjoguAmos\Pesapal\Pesapal;
use Illuminate\Console\Command;
use JsonException;
Expand All @@ -23,7 +24,7 @@ public function handle(): int
{
$token = Pesapal::createToken();

if($token) {
if($token instanceof PesapalToken) {
$this->info(string: 'A fresh access token has been retrieved and saved to the database.');

return self::SUCCESS;
Expand Down
71 changes: 33 additions & 38 deletions src/Pesapal.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use NjoguAmos\Pesapal\Requests\GetPesapalTransactionStatus;
use Saloon\Exceptions\Request\FatalRequestException;
use Saloon\Exceptions\Request\RequestException;
use Saloon\Http\Response;

class Pesapal
{
Expand All @@ -26,82 +27,80 @@ class Pesapal
* @throws RequestException
* @throws JsonException
*/
public static function createToken(): ?PesapalToken
public static function createToken(): PesapalToken | Response
{
$connector = new PesapalBaseConnector();
$request = new CreatePesapalToken();

$response = $connector->send($request);

if ($response->ok()) {
return PesapalToken::create([
'access_token' => $response->json(key: 'token'),
// The 'expiryDate' is in UTC timezone, so it is first parsed with the UTC timezone.
// Then, the timezone is converted to the application's timezone using the 'tz' method.
'expires_at' => Carbon::parse($response->json(key: 'expiryDate'), 'UTC')->tz(config(key: 'app.timezone'))
]);
if (! $response->ok()) {
return $response;
}

return null;
return PesapalToken::create([
'access_token' => $response->json(key: 'token'),
// The 'expiryDate' is in UTC timezone, so it is first parsed with the UTC timezone.
// Then, the timezone is converted to the application's timezone using the 'tz' method.
'expires_at' => Carbon::parse($response->json(key: 'expiryDate'), 'UTC')->tz(config(key: 'app.timezone'))
]);

}

/**
* @throws FatalRequestException
* @throws RequestException
* @throws JsonException
*/
public static function createIpn(string $url, IpnType $ipnType): ?PesapalIpn
public static function createIpn(string $url, IpnType $ipnType): PesapalIpn | Response
{
$connector = new PesapalConnector();
$request = new CreatePesapalIpn(url: $url, ipnType: $ipnType);

$response = $connector->send($request);

if ($response->ok()) {
return PesapalIpn::updateOrCreate(
attributes: [
'url' => $response->json(key: 'url'),
],
values: [
'ipn_id' => $response->json(key: 'ipn_id'),
'url' => $response->json(key: 'url'),
'type' => $ipnType,
'status' => $response->json(key: 'ipn_status'),
// The 'created_date' is in UTC timezone, so it is first parsed with the UTC timezone.
// Then, the timezone is converted to the application's timezone using the 'tz' method.
'created_at' => Carbon::parse($response->json(key: 'created_date'), 'UTC')->tz(config(key: 'app.timezone'))
]
);
if (! $response->ok()) {
return $response;
}

return null;
return PesapalIpn::updateOrCreate(
attributes: [
'url' => $response->json(key: 'url'),
],
values: [
'ipn_id' => $response->json(key: 'ipn_id'),
'url' => $response->json(key: 'url'),
'type' => $ipnType,
'status' => $response->json(key: 'ipn_status'),
// The 'created_date' is in UTC timezone, so it is first parsed with the UTC timezone.
// Then, the timezone is converted to the application's timezone using the 'tz' method.
'created_at' => Carbon::parse($response->json(key: 'created_date'), 'UTC')->tz(config(key: 'app.timezone'))
]
);

}

/**
* @throws FatalRequestException
* @throws RequestException
* @throws JsonException
*/
public static function getIpns(): ?array
public static function getIpns(): array | Response
{
$connector = new PesapalConnector();
$request = new GetPesapalIpns();

$response = $connector->send($request);

if ($response->ok()) {
return $response->array();
}

return null;
return $response->ok() ? $response->array() : $response;
}

/**
* @throws FatalRequestException
* @throws RequestException
* @throws JsonException
*/
public static function createOrder(PesapalOrderData $orderData, PesapalAddressData $billingAddress): ?array
public static function createOrder(PesapalOrderData $orderData, PesapalAddressData $billingAddress): array | Response
{
// @TODO: Validate the order data and billing address

Expand All @@ -113,11 +112,7 @@ public static function createOrder(PesapalOrderData $orderData, PesapalAddressDa

$response = $connector->send($request);

if ($response->ok()) {
return $response->array();
}

return null;
return $response->ok() ? $response->array() : $response;
}

/**
Expand Down