Deploy Ladill Mini / deploy (push) Successful in 57s
Cross-origin fetch to ladl.link had no CORS, so showSheet never ran. Open the sheet immediately and keep Paystack behind the Continue CTA.
186 lines
6.2 KiB
PHP
186 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\QrCode;
|
|
use App\Models\User;
|
|
use App\Services\Pay\PayClient;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Str;
|
|
use Mockery;
|
|
use Tests\TestCase;
|
|
|
|
class MiniPaymentCheckoutTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_payment_landing_shows_secure_checkout_not_momo(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Vendor',
|
|
'email' => 'vendor@example.com',
|
|
]);
|
|
|
|
$qr = QrCode::query()->create([
|
|
'user_id' => $user->id,
|
|
'short_code' => 'payland01',
|
|
'type' => QrCode::TYPE_PAYMENT,
|
|
'label' => 'Till',
|
|
'payload' => [
|
|
'content' => [
|
|
'business_name' => 'Accra Kiosk',
|
|
'currency' => 'GHS',
|
|
],
|
|
'style' => [],
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->withHeader(\App\Support\LadillLink::INTERNAL_HEADER, '1')
|
|
->get('/q/'.$qr->short_code)
|
|
->assertOk()
|
|
->assertSee('Your payment is processed securely', false)
|
|
->assertSee('md:items-center', false)
|
|
->assertSee('Complete your payment', false)
|
|
->assertSee('data-ladill-pay-sheet', false)
|
|
->assertSee('/q/'.$qr->short_code.'/pay', false)
|
|
->assertDontSee('https://ladl.link/'.$qr->short_code.'/pay', false)
|
|
->assertDontSee('MTN MoMo number', false)
|
|
->assertDontSee('Pay with MTN MoMo', false)
|
|
->assertDontSee('Paystack checkout', false);
|
|
}
|
|
|
|
public function test_json_pay_post_is_not_redirected_to_ladill_link(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Vendor',
|
|
'email' => 'vendor-ajax@example.com',
|
|
]);
|
|
|
|
$qr = QrCode::query()->create([
|
|
'user_id' => $user->id,
|
|
'short_code' => 'payajax01',
|
|
'type' => QrCode::TYPE_PAYMENT,
|
|
'label' => 'Till',
|
|
'payload' => [
|
|
'content' => [
|
|
'business_name' => 'Accra Kiosk',
|
|
'currency' => 'GHS',
|
|
],
|
|
'style' => [],
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$pay = Mockery::mock(PayClient::class);
|
|
$pay->shouldReceive('createCheckout')
|
|
->once()
|
|
->andReturn([
|
|
'id' => 100,
|
|
'reference' => 'LP-TESTMINIAjax01',
|
|
'checkout_url' => 'https://checkout.paystack.com/mini-ajax',
|
|
'provider' => 'paystack',
|
|
'platform_fee_minor' => 15,
|
|
'merchant_amount_minor' => 985,
|
|
]);
|
|
$this->app->instance(PayClient::class, $pay);
|
|
|
|
// No INTERNAL header — XHR/JSON must still hit Mini, not 307 to ladl.link.
|
|
$this->postJson('/q/'.$qr->short_code.'/pay', [
|
|
'amount' => 10,
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('checkout_url', 'https://checkout.paystack.com/mini-ajax')
|
|
->assertJsonPath('provider', 'paystack');
|
|
}
|
|
|
|
public function test_pay_initiation_does_not_require_phone_and_returns_paystack_checkout(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Vendor',
|
|
'email' => 'vendor@example.com',
|
|
]);
|
|
|
|
$qr = QrCode::query()->create([
|
|
'user_id' => $user->id,
|
|
'short_code' => 'payinit01',
|
|
'type' => QrCode::TYPE_PAYMENT,
|
|
'label' => 'Till',
|
|
'payload' => [
|
|
'content' => [
|
|
'business_name' => 'Accra Kiosk',
|
|
'currency' => 'GHS',
|
|
],
|
|
'style' => [],
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$pay = Mockery::mock(PayClient::class);
|
|
$pay->shouldReceive('createCheckout')
|
|
->once()
|
|
->with(Mockery::on(function (array $payload): bool {
|
|
return ($payload['source_service'] ?? '') === 'mini'
|
|
&& ! array_key_exists('customer_phone', $payload)
|
|
&& ($payload['line_items'][0]['unit_price_minor'] ?? 0) === 2500;
|
|
}))
|
|
->andReturn([
|
|
'id' => 99,
|
|
'reference' => 'LP-TESTMINIPAY001',
|
|
'checkout_url' => 'https://checkout.paystack.com/mini-test',
|
|
'provider' => 'paystack',
|
|
'platform_fee_minor' => 38,
|
|
'merchant_amount_minor' => 2462,
|
|
]);
|
|
$this->app->instance(PayClient::class, $pay);
|
|
|
|
$this->withHeader(\App\Support\LadillLink::INTERNAL_HEADER, '1')
|
|
->postJson('/q/'.$qr->short_code.'/pay', [
|
|
'amount' => 25,
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('checkout_url', 'https://checkout.paystack.com/mini-test')
|
|
->assertJsonPath('provider', 'paystack');
|
|
|
|
$this->assertDatabaseHas('mini_payments', [
|
|
'qr_code_id' => $qr->id,
|
|
'amount_minor' => 2500,
|
|
'payment_reference' => 'LP-TESTMINIPAY001',
|
|
'payer_phone' => null,
|
|
]);
|
|
}
|
|
|
|
public function test_payment_callback_returns_top_frame_escape(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Vendor',
|
|
'email' => 'vendor3@example.com',
|
|
]);
|
|
|
|
$qr = QrCode::query()->create([
|
|
'user_id' => $user->id,
|
|
'short_code' => 'paycb001',
|
|
'type' => QrCode::TYPE_PAYMENT,
|
|
'label' => 'Till',
|
|
'payload' => [
|
|
'content' => [
|
|
'business_name' => 'Accra Kiosk',
|
|
'currency' => 'GHS',
|
|
],
|
|
'style' => [],
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->withHeader(\App\Support\LadillLink::INTERNAL_HEADER, '1')
|
|
->get('/q/'.$qr->short_code.'/pay/callback')
|
|
->assertOk()
|
|
->assertSee('Confirming your payment', false)
|
|
->assertSee('window.top.location.replace', false);
|
|
}
|
|
}
|