payment = ShoppingPayment::create([ 'shopping_order_id' => 0, 'reference' => 'test-'.uniqid(), 'amount' => 9900, 'currency' => 'EUR', 'clearingtype' => 'cc', 'mode' => 'test', ]); }); it('records an APPROVED response with txid and userid', function (): void { $response = [ 'status' => 'APPROVED', 'txid' => '12345', 'userid' => '67890', ]; $transaction = PayoneTransactionRecorder::recordFromResponse($this->payment, 'authorization', $response); expect($transaction)->toBeInstanceOf(PaymentTransaction::class) ->and($transaction->shopping_payment_id)->toBe($this->payment->id) ->and($transaction->request)->toBe('authorization') ->and($transaction->status)->toBe('APPROVED') ->and($transaction->txid)->toBe('12345') ->and($transaction->userid)->toBe('67890') ->and($transaction->mode)->toBe('test') ->and($transaction->errorcode)->toBeNull() ->and($transaction->transmitted_data)->toMatchArray($response); }); it('records an ERROR response with error fields and no txid', function (): void { $response = [ 'status' => 'ERROR', 'errorcode' => '909', 'errormessage' => 'Card declined', 'customermessage' => 'Ihre Karte wurde abgelehnt.', ]; $transaction = PayoneTransactionRecorder::recordFromResponse($this->payment, 'authorization', $response); expect($transaction->status)->toBe('ERROR') ->and($transaction->txid)->toEqual(0) ->and($transaction->userid)->toEqual(0) ->and($transaction->errorcode)->toBe('909') ->and($transaction->errormessage)->toBe('Card declined') ->and($transaction->customermessage)->toBe('Ihre Karte wurde abgelehnt.') ->and($transaction->transmitted_data)->toMatchArray($response); }); it('records a REDIRECT response', function (): void { $response = [ 'status' => 'REDIRECT', 'txid' => '99999', 'userid' => '11111', 'redirecturl' => 'https://paypal.com/redirect', ]; $transaction = PayoneTransactionRecorder::recordFromResponse($this->payment, 'authorization', $response); expect($transaction->status)->toBe('REDIRECT') ->and($transaction->txid)->toBe('99999') ->and($transaction->userid)->toBe('11111'); }); it('falls back to useridFallback when response has no userid', function (): void { $response = ['status' => 'APPROVED', 'txid' => '555']; $transaction = PayoneTransactionRecorder::recordFromResponse($this->payment, 'authorization', $response, 42); expect($transaction->userid)->toEqual(42); }); it('records an invoice payment with synthetic FNCMIV status', function (): void { $requestPayload = ['clearingtype' => 'fnc', 'onlinebanktransfertype' => 'MIV', 'amount' => 9900]; $transaction = PayoneTransactionRecorder::recordInvoicePayment($this->payment, 'authorization', $requestPayload); expect($transaction)->toBeInstanceOf(PaymentTransaction::class) ->and($transaction->status)->toBe('FNCMIV') ->and($transaction->txaction)->toBe('invoice_open') ->and($transaction->txid)->toEqual(0) ->and($transaction->userid)->toEqual(0) ->and($transaction->mode)->toBe('test') ->and($transaction->transmitted_data)->toMatchArray($requestPayload); }); it('records a webhook callback with PAYONE status and stored fields', function (): void { $data = [ 'key' => 'somekey', 'txid' => '321623031', 'userid' => '158723953', 'txaction' => 'paid', 'price' => '89.00', 'errorcode' => '0', ]; $transaction = PayoneTransactionRecorder::recordWebhookCallback($this->payment, $data); expect($transaction)->toBeInstanceOf(PaymentTransaction::class) ->and($transaction->request)->toBe('transaction') ->and($transaction->status)->toBe('PAYONE') ->and($transaction->txid)->toBe('321623031') ->and($transaction->userid)->toBe('158723953') ->and($transaction->txaction)->toBe('paid') ->and($transaction->mode)->toBe('test') // falls back to payment->mode when data has none ->and($transaction->transmitted_data)->toMatchArray(['txaction' => 'paid', 'price' => '89.00']); }); it('strips cardpan and cardcvc2 from stored transmitted_data', function (): void { $payload = [ 'clearingtype' => 'cc', 'cardpan' => '4111111111111111', 'cardcvc2' => '123', 'amount' => 9900, ]; $transaction = PayoneTransactionRecorder::recordInvoicePayment($this->payment, 'authorization', $payload); expect($transaction->transmitted_data)->not->toHaveKey('cardpan') ->and($transaction->transmitted_data)->not->toHaveKey('cardcvc2') ->and($transaction->transmitted_data)->toMatchArray(['clearingtype' => 'cc', 'amount' => 9900]); });