Route event ticket payments through centralized Ladill Pay.
Deploy Ladill Events / deploy (push) Successful in 45s
Deploy Ladill Events / deploy (push) Successful in 45s
Replace per-owner gateway checkout with platform Paystack via the Pay API, drop owner key requirements from settings, and add coverage for init and idempotent completion. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\QrCode;
|
||||
use App\Models\QrEventRegistration;
|
||||
use App\Models\User;
|
||||
use App\Services\Events\EventRegistrationService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LadillPayEventRegistrationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
config([
|
||||
'pay.api_url' => 'https://ladill.com/api/pay',
|
||||
'pay.api_key' => 'events-pay-test-key',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_paid_registration_uses_ladill_pay_without_merchant_gateway(): void
|
||||
{
|
||||
Http::fake([
|
||||
'https://ladill.com/api/pay/checkouts' => Http::response([
|
||||
'id' => 55,
|
||||
'reference' => 'LP-EVENTTEST0001',
|
||||
'checkout_url' => 'https://checkout.paystack.com/events-test',
|
||||
'platform_fee_minor' => 82,
|
||||
'merchant_amount_minor' => 4918,
|
||||
'provider' => 'paystack',
|
||||
], 201),
|
||||
]);
|
||||
|
||||
$user = User::factory()->create(['public_id' => 'usr_evt_'.uniqid()]);
|
||||
|
||||
$qr = QrCode::create([
|
||||
'user_id' => $user->id,
|
||||
'short_code' => 'evt'.strtolower(substr(uniqid(), -6)),
|
||||
'type' => QrCode::TYPE_EVENT,
|
||||
'label' => 'Demo Event',
|
||||
'is_active' => true,
|
||||
'payload' => [
|
||||
'content' => [
|
||||
'name' => 'Demo Event',
|
||||
'mode' => 'ticketing',
|
||||
'registration_open' => true,
|
||||
'currency' => 'GHS',
|
||||
'tiers' => [
|
||||
['name' => 'General', 'price' => 50, 'capacity' => 100],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$result = app(EventRegistrationService::class)->register($qr, [
|
||||
'tier' => 'General',
|
||||
'attendee_name' => 'Ada Lovelace',
|
||||
'attendee_email' => 'ada@example.com',
|
||||
'attendee_phone' => '0244111222',
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['paid']);
|
||||
$this->assertSame('https://checkout.paystack.com/events-test', $result['checkout_url']);
|
||||
$this->assertSame(QrEventRegistration::STATUS_PENDING, $result['registration']->status);
|
||||
$this->assertSame('LP-EVENTTEST0001', $result['registration']->payment_reference);
|
||||
|
||||
Http::assertSent(function ($request) use ($user) {
|
||||
if (! str_ends_with($request->url(), '/api/pay/checkouts')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $request->hasHeader('Authorization', 'Bearer events-pay-test-key')
|
||||
&& ($request['merchant'] ?? '') === $user->public_id
|
||||
&& ($request['source_service'] ?? '') === 'events'
|
||||
&& ($request['fee_tier'] ?? '') === 'sales'
|
||||
&& ($request['customer_email'] ?? '') === 'ada@example.com';
|
||||
});
|
||||
}
|
||||
|
||||
public function test_complete_is_idempotent_for_confirmed_registration(): void
|
||||
{
|
||||
Http::fake([
|
||||
'https://ladill.com/api/pay/checkouts/verify' => Http::response([
|
||||
'reference' => 'LP-IDEMP00001',
|
||||
'status' => 'paid',
|
||||
'amount_minor' => 5000,
|
||||
'platform_fee_minor' => 75,
|
||||
'merchant_amount_minor' => 4925,
|
||||
], 200),
|
||||
]);
|
||||
|
||||
$user = User::factory()->create(['public_id' => 'usr_idem_'.uniqid()]);
|
||||
$qr = QrCode::create([
|
||||
'user_id' => $user->id,
|
||||
'short_code' => 'idm'.strtolower(substr(uniqid(), -6)),
|
||||
'type' => QrCode::TYPE_EVENT,
|
||||
'label' => 'Idempotent Event',
|
||||
'is_active' => true,
|
||||
'payload' => [
|
||||
'content' => ['name' => 'Idempotent Event'],
|
||||
],
|
||||
]);
|
||||
|
||||
$registration = QrEventRegistration::create([
|
||||
'qr_code_id' => $qr->id,
|
||||
'user_id' => $user->id,
|
||||
'reference' => 'QRE-IDEMP00001',
|
||||
'badge_code' => 'BADGE01',
|
||||
'tier_name' => 'General',
|
||||
'amount_minor' => 5000,
|
||||
'currency' => 'GHS',
|
||||
'attendee_name' => 'Test User',
|
||||
'attendee_email' => 'test@example.com',
|
||||
'status' => QrEventRegistration::STATUS_CONFIRMED,
|
||||
'payment_reference' => 'LP-IDEMP00001',
|
||||
'paid_at' => now(),
|
||||
]);
|
||||
|
||||
$completed = app(EventRegistrationService::class)->complete('LP-IDEMP00001');
|
||||
|
||||
$this->assertSame(QrEventRegistration::STATUS_CONFIRMED, $completed->status);
|
||||
Http::assertNothingSent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user