Question

I am using the Cashflows online payment system, and am trying to submit a dynamically generated price to their server, based on a form on a webpage. However, inside the POST request that I need to send to the Cashflows terminal, I need to include an input field with a hash key. My problem is that the hash is based on a secret key, and this key is generated with one of the parameters being the price (see below), as the integration guide suggests.

How can I submit the form with the POST parameters below to the portal using PHP?

PHP:

<?php

    $secret_key = 'foobar';
    $store_id = $_POST['store_id'];
    $cart_id = $_POST['cart_id'];
    $amount = $_POST['amount'];
    $currency = $_POST['currency'];
    $test = $_POST['test'];
    $description = $_POST['description'];
    echo $check = hash('sha256', $secret_key . ':' . $store_id . ':' . $cart_id . ':' . $amount . ':' . $currency . ':' . $test . ':' . $description);
    $price = $_POST['price'];
    $qty = $_POST['qty'];
    $carriage_amount = $_POST['carriage_amount'];
    $postage_and_packaging = $_POST['postage_and_packaging'];
    $name = $_POST['name'];
    $address = $_POST['address'];
    $postcode = $_POST['postcode'];
    $country = $_POST['country'];
    $tel = $_POST['tel'];
    $email = $_POST['email'];
    $amount = $_POST['amount'];

?>

Form with dynamically generated price, a modified version of their integration example:

<form action="submit.php" method="POST">
    <input type="hidden" name="store_id" value="5939523" />
    <input type="hidden" name="cart_id" value="captubes" />
    <input type="hidden" name="currency" value="GBP" />
    <input type="hidden" name="test" value="1" />
    <input type="hidden" name="description" value="Fruush" />
    <input type="hidden" name="check" value="SOME KEY HERE" />

    <script type="text/javascript" type="text/javascript">

        // The next two functions round numbers to numerical formatting. They do not need to be altered when adding or removing products.
        function roundOff2(value, precision) {
            return places(value,1,precision);
        }

        function places(X, M, N) {
            var T, S=new String(Math.round(X*Number("1e"+N)))
            while (S.length<M+N) S='0'+S
            var y = S.substr(0, T=(S.length-N));
            if(N>0) 
            {
                y += '.' + S.substr(T, N);
            }

            return y;
        }

        // This function checks for empty quantities. It does not need to be altered when adding or removing products.
        function CheckNull2(value) {
            if (value == "") {
                value = "0";
            }

            return value;
        }

        // This function defines the postage and packaging location. It does not need to be altered when adding or removing products.
        function typeOfCarriage(x,whereabouts) {
            x.carriage_amount.value = whereabouts;
        }

        // This function addeds the postage and packaging to the total price of the products. Add new postage rates here, and also edit further down the page to add them to the table.
        function calculate(x) {

            basicprice = calc(x);

            if( Number(basicprice) > 0 ) {

                var postage_and_packaging = 0;

                switch (x.carriage_amount.value) {
                    case "uk" :
                        postage_and_packaging = 1.99;
                        break;
                    case "europe" :
                        postage_and_packaging = 2.99;
                        break;
                    default :
                        postage_and_packaging = 4.99;
                        break;
                }

                x.amount.value = Number(basicprice) + postage_and_packaging;

            } else {

                x.amount.value = "0";

            }

            x.amount.value = roundOff2(x.amount.value,2);

        }

        // The standard price, exluding postage and packaging is calculated here. It does not need to be altered when adding or removing products.
        function calc(x) {

            var b = Number(CheckNull2(x.price.value));
            var c = Number(CheckNull2(x.qty.value));
            var a = (b * c);

            return a;

        }

    </script>

    <p>
        <h3>Number of caps</h3>
        Tube of 6 caps: &pound;4.99 - Quantity: <input name="price" value="4.99" type="hidden" /><input name="qty" size="3" value="1" />
    </p>

    <p>
        <h3>Postage &amp; Packaging:</h3>
        <input name="carriage_amount" value="uk" type="hidden">
        <input checked="checked" name="postage_and_packaging" onClick="typeOfCarriage(this.form,'uk');calculate(this.form)" value="" type="radio" />UK (&pound;1.99)
        <input name="postage_and_packaging" onClick="typeOfCarriage(this.form,'europe');calculate(this.form)" value="" type="radio" />Europe(&pound;2.99)
        <input name="postage_and_packaging" onClick="typeOfCarriage(this.form,'world');calculate(this.form)" value="" type="radio" />Rest of World (&pound;4.99)
    </p>

    <p>
        <h3>Your Details (you will get a chance to change these):</h3>
        <span style="width: 100px; float: left;">Name:</span> <input type="text" name="name" /><br />
        <span style="width: 100px; float: left;">Address:</span> <input type="text" name="address" /><br />
        <span style="width: 100px; float: left;">Postcode:</span> <input type="text" name="postcode" /><br />
        <span style="width: 100px; float: left;">Country:</span> <input type="text" name="country" /><br />
        <span style="width: 100px; float: left;">Telephone:</span> <input type="text" name="tel" /><br />
        <span style="width: 100px; float: left;">Email:</span> <input type="text" name="email" />
    </p>

    <input name="calcButton" onClick="calculate(this.form)" value="Calculate Total" type="button"> Total: &pound; <input type="text" name="amount" value="6.98" />
    <input value="Checkout" onClick="calculate(this.form)" type="submit" />
</form>
Was it helpful?

Solution 3

In the end, the answer was relatively straightforward - I couldn't find a no-JavaScript solution, so instead of calculating everything client-side, I used AJAX to pull in a form with a correctly generated hash.

OTHER TIPS

What I would do is post the form to a PHP page on your server, generate the hash, and then post it to the page that will receive it. You can do all of that with fsockopen() or cURL and there are a ton of examples out there on how to use those.

Definitely do not store that variable as a hidden field on the form because it can be read, intercepted, and manipulated and cause a headache later for your ecommerce system.

You can POST to your page that will generate the key and send user another form with hidden fields that will automatically submit to cashflow once the page loads. Here's an example of that form:

<html>
<head>
<script type="text/javascript">
function submit_form()
{
    document.myform.submit();
}
</script>
</head>
<body onload="submit_form();">
    <form method="POST" name="myform" action="http://www.google.com/">
        <input type="hidden" name="field1" value="value1"/>
        <input type="hidden" name="field2" value="value2"/>
    </form>
</body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top