'APPID123', 'merchant_code' => 'MERCH001', 'merchant_key' => 'test-merchant-key', 'base_url' => 'https://kbz.test/gateway', 'notify_url' => 'https://app.test/api/v1/webhooks/kbz', ]; $paymentRequest = new PaymentRequestData( bookingId: 1, merchantOrderId: 'EVB-FIXTURE-001', amount: '15000', currency: 'MMK', method: PaymentMethod::KbzMiniApp, ); test('initiate posts a correctly signed precreate request to the configured base_url', function () use ($config, $paymentRequest) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['result' => 'SUCCESS', 'prepay_id' => 'PREPAY123']])]); (new KbzMiniAppGateway($config))->initiate($paymentRequest); Http::assertSent(function ($request) { $body = $request->data()['Request']; return $request->url() === 'https://kbz.test/gateway' && $body['method'] === 'kbz.payment.precreate' && $body['sign_type'] === 'SHA256' && $body['biz_content']['appid'] === 'APPID123' && $body['biz_content']['merch_code'] === 'MERCH001' && $body['biz_content']['merch_order_id'] === 'EVB-FIXTURE-001' && $body['biz_content']['trade_type'] === 'MINIAPP' && $body['biz_content']['total_amount'] === '15000' && $body['biz_content']['trans_currency'] === 'MMK' && $body['sign'] === KbzSignature::sign($body, 'test-merchant-key'); }); }); test('initiate returns a pending PaymentResultData on a successful precreate', function () use ($config, $paymentRequest) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['result' => 'SUCCESS', 'prepay_id' => 'PREPAY123']])]); $result = (new KbzMiniAppGateway($config))->initiate($paymentRequest); logger()->info('Payment initiation result', ['result' => $result]); expect($result->status)->toBe(PaymentStatus::Pending) ->and($result->gatewayTransactionId)->toBe('EVB-FIXTURE-001') ->and($result->gatewayPayload['prepayId'])->toBe('PREPAY123'); }); test('initiate returns a failed PaymentResultData when KBZ rejects the request', function () use ($config, $paymentRequest) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['result' => 'FAIL', 'msg' => 'Invalid merchant']])]); $result = (new KbzMiniAppGateway($config))->initiate($paymentRequest); expect($result->status)->toBe(PaymentStatus::Failed) ->and($result->gatewayTransactionId)->toBeNull() ->and($result->message)->toBe('Invalid merchant'); }); test('initiate returns a failed PaymentResultData when the connection fails', function () use ($config, $paymentRequest) { Http::fake(['kbz.test/*' => fn () => throw new ConnectionException('Connection refused')]); $result = (new KbzMiniAppGateway($config))->initiate($paymentRequest); expect($result->status)->toBe(PaymentStatus::Failed) ->and($result->gatewayTransactionId)->toBeNull() ->and($result->gatewayPayload)->toBe([]) ->and($result->message)->toBe('Connection refused'); });