Complete Ladill Pay payouts UI for Events.
Deploy Ladill Events / deploy (push) Successful in 38s

Show per-event payment history with fees and net amounts, and let organizers manage payout accounts and withdrawals without leaving the app.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-04 12:06:43 +00:00
co-authored by Cursor
parent 0aafb14836
commit d25682bc6c
7 changed files with 594 additions and 11 deletions
+138
View File
@@ -0,0 +1,138 @@
<?php
namespace Tests\Feature;
use App\Models\QrCode;
use App\Models\QrEventRegistration;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Tests\TestCase;
class EventPayoutsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->withoutMiddleware(\App\Http\Middleware\EnsurePlatformSession::class);
config([
'billing.api_url' => 'https://ladill.com/api/billing',
'identity.api_url' => 'https://ladill.com/api',
'identity.api_key' => 'test-identity-key',
]);
Http::fake([
'https://ladill.com/api/billing/balance*' => Http::response(['balance_minor' => 12500]),
'https://ladill.com/api/identity/payout-account*' => Http::response([
'data' => [
'payout_account' => [
'account_type' => 'mobile_money',
'account_name' => 'Jane Host',
'account_number' => '0241234567',
'bank_code' => 'MTN',
'bank_name' => 'MTN Mobile Money',
'currency' => 'GHS',
],
],
]),
'https://ladill.com/api/identity/wallet/withdrawals*' => Http::response([
'data' => [
[
'id' => 1,
'amount_ghs' => 50.0,
'status' => 'completed',
'created_at' => now()->subDay()->toIso8601String(),
],
],
]),
]);
}
private function user(): User
{
return User::create([
'public_id' => 'usr_payout_'.Str::random(8),
'name' => 'Event Host',
'email' => 'host+'.uniqid().'@example.com',
]);
}
public function test_payouts_page_shows_transactions_and_withdrawals(): void
{
$owner = $this->user();
$event = QrCode::create([
'user_id' => $owner->id,
'short_code' => 'summit-2026',
'type' => QrCode::TYPE_EVENT,
'label' => 'Annual summit',
'payload' => [
'content' => [
'name' => 'Annual summit',
'mode' => 'ticketing',
],
],
'is_active' => true,
]);
QrEventRegistration::create([
'qr_code_id' => $event->id,
'user_id' => $owner->id,
'reference' => 'QRE-TEST1234567890',
'badge_code' => 'BADGE001',
'tier_name' => 'VIP',
'amount_minor' => 10000,
'currency' => 'GHS',
'attendee_name' => 'Alex Buyer',
'attendee_email' => 'alex@example.com',
'status' => QrEventRegistration::STATUS_CONFIRMED,
'payment_reference' => 'LP-TESTREF001',
'paid_at' => now(),
'metadata' => [
'platform_fee_ghs' => 5.50,
'ladill_pay' => ['platform_fee_minor' => 550],
],
]);
$this->actingAs($owner)
->get(route('events.payouts'))
->assertOk()
->assertSee('Payments & Payouts')
->assertSee('Annual summit')
->assertSee('Alex Buyer')
->assertSee('VIP')
->assertSee('LP-TESTREF001')
->assertSee('MTN Mobile Money')
->assertSee('Withdrawal history')
->assertDontSee('Ladill Pay integration completes');
}
public function test_can_submit_withdrawal(): void
{
Http::fake([
'https://ladill.com/api/billing/balance*' => Http::response(['balance_minor' => 12500]),
'https://ladill.com/api/identity/payout-account*' => Http::response(['data' => ['payout_account' => []]]),
'https://ladill.com/api/identity/wallet/withdrawals*' => Http::response(['data' => []]),
'https://ladill.com/api/identity/wallet/withdraw' => Http::response([
'data' => ['id' => 9, 'amount_ghs' => 25.0, 'status' => 'pending'],
]),
]);
$owner = $this->user();
$this->actingAs($owner)
->post(route('events.payouts.withdraw'), ['amount' => 25])
->assertRedirect(route('events.payouts'))
->assertSessionHas('success');
Http::assertSent(function ($request) use ($owner) {
return $request->url() === 'https://ladill.com/api/identity/wallet/withdraw'
&& $request['user'] === $owner->public_id
&& (float) $request['amount'] === 25.0;
});
}
}