Skip to content

Commit

Permalink
Merge pull request #1 from io-digital/handle-webhooks
Browse files Browse the repository at this point in the history
WIP: Handle webhooks
  • Loading branch information
rianzietsman authored Apr 29, 2020
2 parents 884ebb0 + 8fb251b commit 05b5e5b
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 0 deletions.
6 changes: 6 additions & 0 deletions config/peachpayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
'api_uri_live' => 'https://oppwa.com/',
'api_uri_version' => 'v1/',
'skip_3ds_for_stored_cards' => true,
'webhook_url' => '/peach-webhook',
'webhook_excluded' => ['card', 'authentication'],
'webhook_secret_key' => env('PEACH_PAYMENTS_WEBHOOK_SECRET_KEY'),
];
}

Expand All @@ -32,4 +35,7 @@
'api_uri_live' => 'https://oppwa.com/',
'api_uri_version' => 'v1/',
'skip_3ds_for_stored_cards' => true,
'webhook_url' => '/peach-webhook',
'webhook_excluded' => ['card', 'authentication'],
'webhook_secret_key' => env('PEACH_PAYMENTS_WEBHOOK_SECRET_KEY'),
];
35 changes: 35 additions & 0 deletions database/migrations/create_payment_events_table.php.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePaymentEventsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('payment_events', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('type');
$table->string('action')->nullable();
$table->text('payload');
$table->timestamps();
$table->softDeletes();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('payment_events');
}
}
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ $response->isValidationError($resultCode); // true|false
Saving the response is also available:
`$response->save($result, $paymentCard);`

### Webhooks

The following change needs to be made in your `app/Http/Middleware/VerifyCsrfToken.php` file:

```php
protected $except = [
config('peachpayment.webhook_url')
];
```

### Helpers
#### Setting.php
This class allows you to inject or modify your Peach Payment credentials
Expand Down
7 changes: 7 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Route;
use IoDigital\PeachPayment\Http\Controllers\WebhookController;

Route::post(Config::get('peachpayment.webhook_url'), [WebhookController::class, 'index'])->name('peachpayment.index');
13 changes: 13 additions & 0 deletions src/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace IoDigital\PeachPayment\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
54 changes: 54 additions & 0 deletions src/Http/Controllers/WebhookController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace IoDigital\PeachPayment\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Config;
use IoDigital\PeachPayment\Models\PaymentEvent;

class WebhookController extends Controller
{
protected $model;

public function __construct(PaymentEvent $model)
{
$this->model = $model;
}

public function index(Request $request)
{
$event = new PaymentEvent();
$body = $this->decryptMessage($request);
$payload = $body['payload'];

$excludedValues = Config::get('peachpayment.webhook_excluded');

foreach ($excludedValues as $exclude) {
unset($payload[$exclude]);
}

$event->type = $body['type'];
$event->action = $body['action'];
$event->payload = $payload;
$event->save();

return response([], Response::HTTP_OK);
}

private function decryptMessage(Request $request)
{
$keyFromConfiguration = Config::get('peachpayment.webhook_secret_key');
$ivFromHeader = $request->header('X-Initialization-Vector');
$authTagFromHeader = $request->header('X-Authentication-Tag');

$key = hex2bin($keyFromConfiguration);
$iv = hex2bin($ivFromHeader);
$authTag = hex2bin($authTagFromHeader);
$cipherText = hex2bin($request->getContent());

$result = openssl_decrypt($cipherText, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $authTag)

return json_decode($result, true);
}
}
21 changes: 21 additions & 0 deletions src/Models/PaymentEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace IoDigital\PeachPayment\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class PaymentEvent extends Model
{
use SoftDeletes;

protected $fillable = [
'type',
'action',
'payload',
];

protected $casts = [
'payload' => 'array',
];
}
3 changes: 3 additions & 0 deletions src/PeachPaymentServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public function boot()
$this->publishes([
__DIR__.'/../database/migrations/create_payment_cards_table.php.stub' => database_path('migrations/' . date('Y_m_d_His', time()) . '_create_payment_cards_table.php'),
__DIR__.'/../database/migrations/create_payment_results_table.php.stub' => database_path('migrations/' . date('Y_m_d_His', time()) . '_create_payment_results_table.php'),
__DIR__.'/../database/migrations/create_payment_events_table.php.stub' => database_path('migrations/' . date('Y_m_d_His', time()) . '_create_payment_events_table.php'),
], 'peachpayment-migrations');

$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}
}

Expand Down
31 changes: 31 additions & 0 deletions tests/Unit/WebhookTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace IoDigital\PeachPayment\Tests\Unit;

use Illuminate\Foundation\Testing\RefreshDatabase;
use IoDigital\PeachPayment\Tests\TestCase;

class WebhookTest extends TestCase
{
use RefreshDatabase;

/**
* Setup the test environment.
*/
public function setUp(): void
{
parent::setUp();

$this->artisan('migrate');
}

/**
* @test
*/
public function it_can_receive_an_event()
{
$response = $this->postJson(route('peachpayment.index'), []);

$response->assertOk();
}
}

0 comments on commit 05b5e5b

Please sign in to comment.