Вопрос

We are using WorldPay to process payments for a tiered membership system, for which the payment amount varies dependent upon the membership tier selected.

The payment is passed to WorldPay via a form post from a number of hidden fields, including:

<input type="hidden" name="amount" value="295.00" />

Essentially, the form is submitted via POST to WorldPay and the user follows a number of steps to process their payment. Once complete, the user is redirected to a specified confirmation page.

This appears to be the typical manner in which WorldPay accepts payments. There's an obvious issue here, in that the value of the hidden field could easily be tampered with by anyone with a basic knowledge of HTML. The form is posted directly to WorldPay, so we have no PostBack in which to validate the amount against the membership tier.

We have the option to validate the payment amount when a payment notification is returned to us from WorldPay by routing the callback through a handler before the confirmation page; however, I would like to avoid the situation where user submits a tampered form, pays the incorrect amount and receives no membership, then has to contact the company to have their money returned.

How might we validate that the amount being submitted is correct before processing payment?

Update

It has occurred to me that we have an additional problem whereby, even if we validate the form post server-side, there is nothing stopping a malicious user from spoofing the form post direct to WorldPay.

Это было полезно?

Решение

It is a vulnerability indeed, it can be solved easily using a signature. Check out this link:

http://culttt.com/2012/07/25/integrating-worldpay-into-a-database-driven-website/

This method should be better promoted on the help page, too bad.

Другие советы

One solution I can think of is this, capture the form tag's submit:

<form id="myForm" onsubmit="return validatePayment();">

and then create that JavaScript file that looks like this:

var isValidAmount = false;

function validatePayment() {
    if (isValidAmount) { return true; }

    // in here you want to issue an AJAX call back to your server
    // with the appropriate information ... I would recommend using
    // jQuery and so it might look something like this:
    $.ajax( {
        type: "POST",
        url: url,
        data: { amount: $("#amount").val(), someotherfield: somevalue },
        success: function(data, textStatus, jqXHR) {
            // set the flag so that it can succeed the next time through
            isValidAmount = true;

            // resubmit the form ... it will reenter this function but leave
            // immediately returning true so the submit will actually occur
            $("myForm").submit();
        },
    });

    // this will keep the form from actually submitting the first time
    return false;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top