Sage Pay Payment Gateway Integration using PHP

by Vincy. Last modified on September 27th, 2022.

Sage Pay payment gateway integration is easier to implement on websites. Sage Pay provides API access for requesting payment processes from our website.

This type of payment integration can be done in three ways using Sage Pay checkout pages, Sage Pay drop-in checkout and using own form. People having experience in any kind of payment integration (PayPal) can find it easy to follow the API documentation for integrating Sage Pay.

If you are a newbie to payment integration, this article will help you to start with a simple example for integrating Sage payment in the test environment.

In this example,  I have integrated Sage Pay using our own form to get the card details from the user. Also, it contains the amount, currency and many data that need to be sent while requesting sage payment.

On submitting this form the data will be posted to the PHP code. In this code, the form data are used as CURL params while sending a payment request. After processing the payment, the API will result in a JSON response based on which the end-user will be acknowledged about the payment process.

Get Sage Pay Merchant Session Key

Login to MySagePay (test or live) using your Sage Pay account credentials and get the Integration Key and the Integration Password by clicking the Create API Credentials.

These two credentials are combined as IntegrationKey: IntegrationPassword and then encoded by using base64 encoding. The code will be sent via the PHP CURL request for authorization. The CURL will return Merchant Session Key with the expiry token. The PHP code for getting the merchant session key is as follows.

<?php
$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_URL => "https://pi-test.sagepay.com/api/v1/merchant-session-keys",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => '{ "vendorName": "VENDOR_NAME" }',
    CURLOPT_HTTPHEADER => array(
        "Authorization: Basic " . BASIC_AUTHORIZATION_CODE,
        "Cache-Control: no-cache",
        "Content-Type: application/json"
    )
));

$response = curl_exec($curl);
$response = json_decode($response, true);
$err = curl_error($curl);

curl_close($curl);
?>

Sage Payment HTML

This HTML code has the sagepay.js included and a form to get the card details from the end-user to process Sage Payment. The sagepay.js library is used for transmitting the card details in a secured manner.

On submitting this form the default submits event is prevented and the card details are tokenized by invoking tokeniseCardDetails().  On successful invocation, the card identifier will be created and populated in a hidden field before triggering the form to submit the event.

<script src="https://pi-test.sagepay.com/api/v1/js/sagepay.js"></script>
<script>
document.querySelector('[type=submit]')
        .addEventListener('click', function(e) {
            e.preventDefault();
            sagepayOwnForm({ merchantSessionKey: '<?php echo $response['merchantSessionKey']; ?>' })
              .tokeniseCardDetails({
                  cardDetails: {
                     cardholderName: $('#card-holder-name').val(),
                     cardNumber: $("#card-number").val(),
                     expiryDate: $("#expiryMonth").val()+$("#expiryYear").val(),
                     securityCode: $("#cvv").val()
                  },
                  onTokenised : function(result) {
                    if (result.success) {
                      document.querySelector('[name="card-identifier"]').value = result.cardIdentifier;
                      document.querySelector('form').submit();
                    } else {
                    	   if(result.errors.length>0) {
                            $("#error-message").show();
                            $("#error-message").html("");
                            for(i=0;i<result.errors.length;i++) {
                                $("#error-message").append("<div>" + result.errors[i].code+": " +result.errors[i].message + "</div>");
                            }
                        }
                    }
                  }
              });
        }, false);
</script>

Submit Sage Pay Payment Request

On submitting the Sage Pay payment form, the field data are posted to the PHP file process_transaction.php. On this page, the payment request is sent via a CURL request to the Sage Pay API.

The API will return a JSON response that contains the status of the payment process. Based on this response, the end-user will be acknowledged.

<?php
$merchantSessionKey = $_POST["merchantSessionKey"];
$cardIdentifier = $_POST["card-identifier"];

$amount = $_POST["amount"];
$currency = $_POST["currency"];

$firstName = $_POST["first_name"];
$lastName = $_POST["last_name"];

$billing_address = $_POST["billing_address"];
$billing_city = $_POST["billing_city"];
$billing_zip = $_POST["billing_zip"];
$billing_country = $_POST["billing_country"];

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => "https://pi-test.sagepay.com/api/v1/transactions",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => '{' .
    '"transactionType": "Payment",' .
    '"paymentMethod": {' .
    '    "card": {' .
    '        "merchantSessionKey": "' . $merchantSessionKey . '",' .
    '        "cardIdentifier": "' . $cardIdentifier . '"' .
    '    }' .
    '},' .
    '"vendorTxCode": "SagePayExample' . time() . '",' .
    '"amount": ' . $amount . ',' .
    '"currency": "' . $currency . '",' .
    '"description": "Sage Payment Integration Example",' .
    '"apply3DSecure": "UseMSPSetting",' .
    '"customerFirstName": "' . $firstName . '",' .
    '"customerLastName": "' . $lastName . '",' .
    '"billingAddress": {' .
    '    "address1": "' . $billing_address . '",' .
    '    "city": "' . $billing_city . '",' .
    '    "postalCode": "' . $billing_zip . '",' .
    '    "country": "' . $billing_country . '"' .
    '},' .
    '"entryMethod": "Ecommerce"' .
    '}',
    CURLOPT_HTTPHEADER => array(
        "Authorization: BASIC_AUTHORIZATION_CODE",
        "Cache-Control: no-cache",
        "Content-Type: application/json"
    ),
));

$response = curl_exec($curl);
$result = json_decode($response);
$err = curl_error($curl);

curl_close($curl);
?>
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css"/ >
</head>
<body>
    <?php if(!empty($result->status) && $result->status == "Ok") { ?>
    <div id="response-container" class="success">
        <div class="img-response">
            <img src="success.png" />
        </div>
        <div class="ack-message">Thank You!</div>
        <div>Sage Payment is Completed.</div>
    </div>
    <?php } else {?>
    <div id="response-container" class="error">
        <div class="img-response">
            <img src="error.png" />
        </div>
        <div class="ack-message">Payment Failed!</div>
        <div>Problem in Processing Sage Payment.</div>
    </div>
    <?php  } ?>
</body>
</html>

Sage Payment Output

The following screenshots show the UI that will be shown to the end-user on the success and failure response of the Sage Payment process.

sage-payment-success

sage-payment-error

Download

Vincy
Written by Vincy, a web developer with 15+ years of experience and a Masters degree in Computer Science. She specializes in building modern, lightweight websites using PHP, JavaScript, React, and related technologies. Phppot helps you in mastering web development through over a decade of publishing quality tutorials.

Comments to “Sage Pay Payment Gateway Integration using PHP”

  • ebad says:

    Hi vincy ,
    i’m unable to get Merchant Session Key , can you please guide me about this thanks

  • Mike says:

    great post, simplifies the sage documentation, but . . .
    I’m having trouble creating the BASIC_AUTHORIZATION_CODE
    I’m using:
    $basicAuthorisationCode = base64_encode($integrationKey. ‘:’ .$integrationPassword);

    did I miss something?
    cheers
    Mike

    • Vincy says:

      Hi Mike,

      The encoding step is correct. Verify the following.
      1. If the integrationKey and integrationPassword variables have the right keys.
      2. Add the prefix “Basic ” in the Authorization header like,
      CURLOPT_HTTPHEADER => array(
      “Authorization: Basic ” . $baseAuthorizarionCode,
      “Cache-Control: no-cache”,
      “Content-Type: application/json”
      )

  • Andy says:

    Great article!

    Followed your integration article and can successfully generate the merchant session key, but the “payment failed” notification keeps showing each time.

    Gone through everything, and can’t spot what’s causing this.

    Any ideas where we’re going wrong?

    Thanks,

    Andy

    • Vincy says:

      Hi Andy, it is difficult and almost impossible to debug payment gateway integration without access to the code and environment. Kindly contact me via my email and I will see how I can help.

Leave a Reply

Your email address will not be published. Required fields are marked *

↑ Back to Top

Share this page