'APPID123', 'merchant_code' => 'MERCH001', 'merchant_key' => 'test-merchant-key', 'base_url' => 'https://kbz.test/gateway', 'notify_url' => 'https://app.test/api/v1/webhooks/kbz', ]; test('verify posts a correctly signed queryorder request keyed by our own merch_order_id', function () use ($config) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['trade_status' => 'PAY_SUCCESS']])]); (new KbzMiniAppGateway($config))->verify('EVB-FIXTURE-001'); Http::assertSent(function ($request) { $body = $request->data()['Request']; return $request->url() === 'https://kbz.test/gateway' && $body['method'] === 'kbz.payment.queryorder' && $body['sign_type'] === 'SHA256' && $body['biz_content']['appid'] === 'APPID123' && $body['biz_content']['merch_code'] === 'MERCH001' && $body['biz_content']['merch_order_id'] === 'EVB-FIXTURE-001' && ! array_key_exists('total_amount', $body['biz_content']) && $body['sign'] === KbzSignature::sign($body, 'test-merchant-key'); }); }); test('verify maps PAY_SUCCESS to a completed PaymentResultData', function () use ($config) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['trade_status' => 'PAY_SUCCESS', 'mm_order_id' => 'MM123']])]); $result = (new KbzMiniAppGateway($config))->verify('EVB-FIXTURE-001'); expect($result->status)->toBe(PaymentStatus::Completed) ->and($result->gatewayTransactionId)->toBe('EVB-FIXTURE-001') ->and($result->gatewayPayload)->toBe(['trade_status' => 'PAY_SUCCESS', 'mm_order_id' => 'MM123']); }); test('verify maps WAIT_PAY to a pending PaymentResultData', function () use ($config) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['trade_status' => 'WAIT_PAY']])]); $result = (new KbzMiniAppGateway($config))->verify('EVB-FIXTURE-001'); expect($result->status)->toBe(PaymentStatus::Pending); }); test('verify maps any other/unrecognized trade_status to a failed PaymentResultData', function () use ($config) { Http::fake(['kbz.test/*' => Http::response(['Response' => ['trade_status' => 'PAY_ERROR']])]); $result = (new KbzMiniAppGateway($config))->verify('EVB-FIXTURE-001'); expect($result->status)->toBe(PaymentStatus::Failed) ->and($result->message)->toBe('PAY_ERROR'); }); test('verify returns a failed PaymentResultData when the connection fails', function () use ($config) { Http::fake(['kbz.test/*' => fn () => throw new ConnectionException('Connection refused')]); $result = (new KbzMiniAppGateway($config))->verify('EVB-FIXTURE-001'); expect($result->status)->toBe(PaymentStatus::Failed) ->and($result->gatewayTransactionId)->toBe('EVB-FIXTURE-001') ->and($result->gatewayPayload)->toBe([]) ->and($result->message)->toBe('Connection refused'); });