0

I can't seem to find an instructions for Omnipay\SagePay, and am struggling to complete the purchase when SagePay posts to my notification URL.

Can anyone provide info, or point me to where I can find out what actions and parameters are needed for the notification URL to complete the purchase please?

Ben
  • 692
  • 8
  • 25
  • Downvote? I think it is a valid question with the package having no documentation – Ben Feb 10 '14 at 12:03

2 Answers2

3

Sagepay is tricky because the notification part is done by Sagepay and not by the client, so make sure you give an Internet accessible notification URL (that was my first mistake). Here's some example code (using Laravel) to process a Sagepay payment:

public function postProcess($transactionId)
{

    //get the order details from somewhere
    $order = $this->order->findByTransaction($transactionId);

    $response = $this->gateway->completePurchase(array(
        'transactionId' => $order->transaction,
        'transactionReference' => $order->reference,
        'amount' => $order->total,
        'currency' => $order->currency,
    ))->send();

    if ( ! $response->isSuccessful())
    {
        $response->invalid(URL::to('checkout/problem'));
        die();
    }

    $response->confirm(URL::to('checkout/complete/'.$transactionId));

}

As you can see it's quite a bit different from the other examples as you need to call completePurchase() and then separately send a response to confirm.

Let me know if you need anymore help.

Cheers

beech
  • 1,034
  • 8
  • 13
  • Hi Beech. Thank you for responding to my comment, and for taking the time to find my question. I finally figured out what I was doing wrong. I was trying to instantiate a new message object to run the confirm method from, not realising that an object is passed into $response and that I call the method from there. I now have a succesful test transaction.. and your code above will help me finalise implementing the proper order processing code. Thanks – Ben Feb 11 '14 at 22:11
  • ..and yes.. I also initially made the same mistake trying to test on my local machine :) – Ben Feb 11 '14 at 22:12
  • Glad that helped. I ended up testing using http://ngrok.com/ to make give my localhost an accessible URL - such a time saver. – beech Feb 12 '14 at 10:33
  • So to be clear `reference` is a JSON string containing many of the attributes of the original transaction (VPSTxId, VendorTxCode, SecurityKey plus a few more) that was saved to the database before the user got redirected to SagePay? – Jason Sep 03 '14 at 15:16
  • Don't forget also that if successful, before returning the confirm() response to SagePay, you must store the result that SagePay have sent you, as this is the only point at which you are securely given the result of the transaction. When the user is taken to checkout/complete/{id} the result can be retrieved to decide what to tell the user. This function is also a good place to update the business transaction that the payment was for, such as the basket or cart to mark it as paid, or an invoice to add a payment to that. Don't leave that for the next page. – Jason Sep 03 '14 at 15:51
  • Last one: you should not send a `confirm()` until you have checked that you really were expecting this notification. If the status of your saved transaction indicates that you have already received a notification, then this one should be rejected as invalid. Essentially, each transaction should accept exactly ONE notification. Any further notifications should be rejected, so keep a count against the transaction in the database, or save the notification_status to check. – Jason Sep 03 '14 at 16:13
  • One more thing to add: the result of `isSuccessful()` tells you whether the payment or authentication was successful or not. its should NOT be linked to whether you return `invalid()` or `confirm()`. The example above is wrong. So long as the data you get allows you to find your transaction, and the transaction was expecting this notification, and the notification passes the `SecurityCode` check (done in `completePurchase()`), then you MUST return `confirm()`. – Jason Sep 16 '14 at 14:01
  • Having said that, the result of `isSuccessful()` or the transaction status, can be used to determine the return URL. For example, `isSuccessful()` will be false if the user cancels the payment, but you probably don't want to send them to an error page as a result, since no error happened - the user cancelled and that was perfectly valid, correct and not done in error. In this case, I would still sent the user to the "complete" page and handle the result of that after looking at the transaction status (ABORT in this case, rather than OK or AUTHENTICATED or REGISTERED). – Jason Sep 16 '14 at 14:07
1

From here you can either read more about the integration methods or scroll to the bottom of the table to download the Server documents. Our kits are available for you to download.

Are you getting an error message when Sage Pay is trying to reach your NotificationURL? Or, are you getting notification that Sage Pay has contacted you via your NotificationURL but you are not able to redirect the shopper to the RedirectionURL, the landing page to tell the shopper about the status of the transaction?

Few points to check for a 5006 error (Unable to redirect to the vendors website. The vendor failed to provide a RedirectionURL).

  • Is the SecurityKey matching?
  • If the transaction is not showing in My Sage Pay, provide Sage Pay with the TxID so that we can check the logs (if within 72 hours)
  • is the NotificationURL an http or https URL? consider html5 issues
  • if Sage Pay can't reach the NotificationURL, check that you have the ports 80 and 443 open. Have you received any attempts to the NotificationURL before?
  • check not a DNS issue
  • check your website is not spooling / not an issue with hosting company?
  • make sure Status=OK rather than Error or Invalid

Can you provide more information so we can help further?

  • Hi. The issue was me using a PHP package incorrectly. I have it working now. Great telephone support! – Ben Feb 11 '14 at 22:08