php paypal. A way to validate a payment before acc

2020-08-03 09:02发布

问题:

Is there a way to validate a payment before paypal proceed the order ?

I Use my own shopping cart. When the customer click on Submit Order, I redirect the user on an other page call, PayPalRedirect.php

PayPalRedirect.php

<form name="paypalform" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="upload" value="1">
<input type="hidden" name="invoice" value="<? echo $idInvoice; ?>">
<input type="hidden" name="business" value="business_email@example.com">
<input type="hidden" name="notify_url" value="http://mydomain.com/catalog/IPNReceip">


 <? 
    $cpt = 1;
        foreach($ordering as $k => $v)
        {
        ?>
            <input type="hidden" name="item_name_<? echo $cpt?>" value="<? echo$v->Product->ProductNumber; ?>">
            <input type="hidden" name="quantity_<? echo $cpt?>" value="<? echo $v->Qty; ?>">
            <input type="hidden" name="amount_<? echo $cpt?>" value="<? echo $v->Price ?>"> 
            <?
            $cpt++;
        }
    ?>


<input type="hidden" name="currency_code" value="CAD">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form> 

I use this JavaScript to submit the form when the page is loaded:

<script>
document.forms.paypalform.submit(); 
</script>

At this time all is alright. The user is Redirect to PayPal page and can login to PayPal and then pay the order.

My question at this point is. Is there a way with PayPal to call a web service in my side (for example: http://mydomain.com/ValidatePayment.php) and pass all the items of the shoping cart that paypal receive to confirm that the price is correct. If the price is not correct, I would like to response to paypal that the payment is invalid and cancel the transaction. All that before the customer click on PayNow of paypal page. How can I do this if it's possible?

Thanks a lot

回答1:

I don't think it is possible to do what you want. Once you send the client over to Paypal, they will handle the payment and send you a confirmation at the end.

If you want to make sure the client paid the correct amount, you should check the confirmation that Paypal sends you.

As you probably know Paypal has two payment confirmation mechanisms - PDT and IPN.

PDT relies on the client coming back to your website after the payment. Once the client makes the payment, Paypal will send you a PDT message with the details of the transaction. This information is what you can use to show a receipt to the client. The issue is if the client closes his browser immediately after making a payment. If that happens, you may never receive the PDT message.

IPN does not rely on the client coming back to your website. Every time a client makes a payment, Paypal will send you an IPN message with the details of the transaction.

You can use either one or both to confirm that payment was completed. And you can also check that the payment was made for the amount you were expecting.

See below the flow I use on my website:

1 - client presses button to make payment with Paypal

2 - my website sends client to Paypal with the details of the transaction

3 - Paypal handles the payment

4 - once payment is completed, Paypal will send the client back to my website with a PDT message.

5 - my website sends a confirmation message to Paypal to check that the PDT message is legit and came from Paypal.

6 - Paypal sends back a message with all the details of the transaction, including price paid.

7 - my website checks the confirmation message from Paypal and shows a receipt on screen to my client

8 - Paypal will also send an IPN message once a payment is made to my seller account.

9 - when my website receives an IPN message, it sends back a message to Paypal to confirm that the message is legit and was originated from Paypal.

10 - my website then checks the confirmation message sent back from Paypal and confirms the payment was correct.

Note that in most cases I will receive two messages from Paypal (one PDT and one IPN). It is ok because I keep track of each transaction and if I receive an IPN for a transaction where I have already marked as paid, I simply discard the IPN message.

Note that if you receive the PDT message you don't really need the IPN message. However I recommend you implement both just in case the client closes his browser before Paypal has a chance to send him back to your website.

In both messages (PDT and IPN) Paypal tells you if the payment cleared or not. As you probably know, some payment types do not clear until a few days after they are submitted to Paypal. Paypal recommends that you don't ship the product until the payment has cleared. Paypal will send you another IPN message once the payment is cleared.

I have two scripts on my website - one to handle the PDT messages and another one to handle the IPN messages. They are very similar when handling payment confirmation. See below an example:

$req = 'cmd=_notify-synch';

$tx_token = $_GET['tx'];
$auth_token = "enter your own authorization token";
$req .= "&tx=$tx_token&at=$auth_token";

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

//$fp = fsockopen ('http://www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled
// replace www.sandbox.paypal.com with www.paypal.com when you go live
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

if (!$fp)
{
    // HTTP ERROR
}
else
{
    fputs ($fp, $header . $req);
    // read the body data
    $res = '';
    $headerdone = false;
    while (!feof($fp))
    {
        $line = fgets ($fp, 1024);
        if (strcmp($line, "\r\n") == 0)
        {
            // read the header
            $headerdone = true;
        }
        else if ($headerdone)
        {
            // header has been read. now read the contents
            $res .= $line;
        }
    }

    // parse the data
    $lines = explode("\n", $res);
    $keyarray = array();
    if (strcmp ($lines[0], "SUCCESS") == 0)
    {
        for ($i=1; $i<count($lines);$i++)
        {
            list($key,$val) = explode("=", $lines[$i]);
            $keyarray[urldecode($key)] = urldecode($val);
        }
        $firstname = $keyarray['first_name'];
        $lastname = $keyarray['last_name'];
        $itemname = $keyarray['item_name'];
        $amount = $keyarray['payment_gross'];
        $invoiceid = $keyarray['invoice'];
        $profileid = $keyarray['subscr_id'];
        // check the payment_status is Completed
        // check that txn_id has not been previously processed
        // check that receiver_email is your Primary PayPal email
        // check that payment_amount/payment_currency are correct
        // process payment
        // show receipt to client
    }
}

I hope this helps. Please feel free to ask follow up questions.

Good luck!



标签: php paypal