thephpleague / omnipay-sagepay

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

Help please. Asking for card parameter when integrating sagepay form #150

Closed jagku closed 4 years ago

jagku commented 4 years ago

I am integrating SagePay\Form to my site and have the following:

$gateway = OmniPay::create('SagePay\Form')->initialize([ 'vendor' => 'my_vendor', 'testMode' => true, 'encryptionKey' => 'my_encryption_key', ]);

$request = $gateway->authorize([ 'VendorTxCode' => 'ABC_1234', 'transactionId' => 12345, 'Amount' => 10, 'Currency' => 'GBP', 'Description' => 'my_description', 'SuccessURL' => 'https://example.com/success', 'returnURL' => 'https://example.com/success', 'FailureURL' => 'https://example.com/failure', ... other sagepay parameters ... ]);

$request->send(); $response->redirect();

However, After the parameters have been sent for authorization I get an error:

PHP Fatal error: Uncaught Omnipay\Common\Exception\InvalidRequestException: The card parameter is required in /vendor/omnipay/common/src/Common/Message/AbstractRequest.php

As this is a Form, I don't have any card details to send. Do you know what I am doing wrong?

judgej commented 4 years ago

The creditCard model holds other things that the gateway needs. Use it to include the name of the customer, their billing/shipping addresses, email address.

I can't remember which of those are mandatory (if any), so try using an empty credidCard model and see how that goes. If that works, then we probably need to remove this validation check, but I do have a hunch at least some details of the customer is required.

Docs need updating regardless.

jagku commented 4 years ago

Hi,

Do you mean adding:

use Omnipay\Common\CreditCard; to the top of the script

I then populate it as per your server example (although this is being used for a form) ie

$card = new CreditCard([ 'firstName' => 'Card', 'lastName' => 'User', // Billing address details are required. ... ]);

then push this array in to the authorize function (instead of purchase)?

Sorry, a little confused here.

TIA

judgej commented 4 years ago

Yes, that's right. In your authorize or purchase method array, include the element, along with everything you already have:

'card' => $card,

I have this in some test scripts:

$card = new CreditCard([
    'firstName' => 'Jason',
    'lastName' => 'Judge',
    ...
]);

$requestMessage = $gateway->purchase([
// or
//$requestMessage = $gateway->authorize([
    'amount' => '99.99',
    'currency' => 'GBP',
    'card' => $card,
    'transactionId' => $transactionId,
    'description' => 'Pizzas for everyone',
    ...
]);

Look from page 36 here:

https://www.sagepay.co.uk/file/14206/download-document/FORM_Integration_and_Protocol_Guidelines_050115.pdf

A number of fields are listed as mandatory, such as the billing and delivery names, and billing address. These fields are supplied by Omnipay through the CreditCard object, so that is why it must be included. I do need to document this a little more.

jagku commented 4 years ago

Hi,

Thanks.

Therefore should DeliveryAddress1 be repeated in the purchase array? The reason I am asking is that I have placed this in the Credit Card array but it complains that this parameter is required.

My code follows:

$card = new CreditCard([ 'firstName' => 'Card', 'lastName' => 'User', 'BillingSurname' => 'User', 'BillingFirstnames' => 'Card', 'BillingAddress1' => 'AAA', 'BillingCity' => '-', 'BillingPostCode' => 'EC1R 0XX', 'BillingCountry' => 'GB', 'DeliverySurname' => 'User', 'DeliveryFirstnames' => 'Card', 'DeliveryAddress1' => 'AAA', 'DeliveryCity' => '-', 'DeliveryPostCode' => 'EC1R 0XX', 'DeliveryCountry' => 'GB' ]);

$request = $gateway->purchase([ 'card' => $card, 'description' => 'Pizzas for everyone', 'transactionId' => 'TRANS_123', 'VendorTxCode' => 'TRANS_123', 'Amount' => '99.99', 'Currency' => 'GBP', 'SuccessURL' => "my success url", 'returnURL' => "my return url", 'FailureURL' => "my cancel url", 'CustomerEMail' => "a@example.com", 'VendorEMail' => "a@example.com", 'EmailMessage' => "Order: 123", 'Apply3DSecure' => 0 ]);

$response = $request->send(); $response->redirect();

jagku commented 4 years ago

Ok, figured out the problem.

judgej commented 4 years ago

If you just supply the billing address, the driver will duplicate it into the delivery address for you.

The first name, last name, and billing address is the minimum requirements.