thephpleague / omnipay-sagepay

Sage Pay driver for the Omnipay PHP payment processing library
MIT License
54 stars 78 forks source link

Purchase method without profile array key gives a deprecation notice for strtoupper() on null #183

Open jamieburchell opened 2 years ago

jamieburchell commented 2 years ago

Calling the purchase() method with an array which does not include the profile key produces the deprecation:

Deprecated: strtoupper(): Passing null to parameter #1 ($string) of type string is deprecated
Omnipay\SagePay\Message\ServerAuthorizeRequest::getData at line 41

I don't think setting a profile is required (it's not in the example code) ?

PHP 8.1 league/omnipay v3.2.1 omnipay/sagepay 4.0.1

judgej commented 2 years ago

I've got a fix for this, in theory. Try as I might, I can't seem to reproduce this error but just looking at this code, I can see how it would be happening. Any hints on reproduction for a test?

This is an example of what I'm trying without teh fix, in the hope of at least seeing a deprecation warning to stdout:

docker run -it --rm --name omnipay-sagepay-test -v "$PWD":/usr/src/myapp -w /usr/src/myapp phpdockerio/php:8.1-cli vendor/bin/phpunit
jamieburchell commented 2 years ago

I'm not sure why it can't be reproduced to be honest.

The relevant part of the stack trace:

ErrorException: Deprecated: strtoupper(): Passing null to parameter #1 ($string) of type string is deprecated
#8 /var/www/vendor/omnipay/sagepay/src/Message/ServerAuthorizeRequest.php(41): Omnipay\SagePay\Message\ServerAuthorizeRequest::getData
#7 /var/www/vendor/omnipay/sagepay/src/Message/ServerPurchaseRequest.php(12): Omnipay\SagePay\Message\ServerPurchaseRequest::getData
#6 /var/www/vendor/omnipay/common/src/Common/Message/AbstractRequest.php(686): Omnipay\Common\Message\AbstractRequest::send

This was a MOTO transaction. The code I used (sensitive data replaced):

$gateway = Omnipay::create('SagePay_Server');
$gateway->setVendor('x');
$gateway->setCurrency('GBP');
$gateway->setTestMode(false);
$gateway->setExitOnResponse(true);

$card = new CreditCard([
   'firstName' => 'John',
   'lastName' => 'Smith',
   'billingAddress1' => 'Address 1',
   'billingAddress2' => '',
   'billingCity' => 'Town',
   'billingPostcode' => 'ABC 123',
   'billingCountry' => 'GB',
   'billingState' => NULL,
   'billingPhone' => '123',
   'shippingAddress1' => 'Address 1',
   'shippingAddress2' => '',
   'shippingCity' => 'Town',
   'shippingPostcode' => 'ABC 123',
   'shippingCountry' => 'GB',
   'shippingState' => NULL,
   'email' => 'test@example.com'
]);

$response = $gateway->purchase([
   'description' => 'Purchase',
   'transactionId' => 'ABC',
   'amount' => 12.12,
   'returnUrl' => 'https://example.com',
   'accountType' => 'M',
   'card' => $card
])->send();