A Star
A Star

Reputation: 637

How do I stop a PayPal transaction from inside the IPN?

I want to be able to stop a transaction if the details that I am checking are incorrect.

An example of my code

// check that receiver_email is your Primary PayPal email
if($_POST['receiver_email'] != "[email protected]") {
exit(); // exit script
}

I use exit() but while testing this using sandbox.paypal.com when the email is incorrect and exit() is called the transaction still processes and in essence gives the sandbox account the money.

Upvotes: 0

Views: 750

Answers (1)

Robert
Robert

Reputation: 19356

As mentioned, this is certainly possible. Ideally, you would want to offload any processing from your IPN handler so that the IPN handler can focus on receiving POST data from PayPal.
But you can use the following to check the paid amount matches the amount expected, and automatically refund if the amount differs.

For example (based on the PayPal PHP sample code, and quickly thrown together). Note: This code merely serves to illustrate the logic behind this.

<?php

// Set this dynamically.
$amountToBeExpected = "0.99";


// PHP 4.1

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}

// 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 ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];

if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// 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


    if($payment_amount != $amountToBeExpected) {
        /** RefundTransaction NVP example; last modified 08MAY23.
         *
         *  Issue a refund for a prior transaction. 
        */

        $environment = 'sandbox';   // or 'beta-sandbox' or 'live'

        /**
         * Send HTTP POST Request
         *
         * @param   string  The API method name
         * @param   string  The POST Message fields in &name=value pair format
         * @return  array   Parsed HTTP Response body
         */
        function PPHttpPost($methodName_, $nvpStr_) {
            global $environment;

            // Set up your API credentials, PayPal end point, and API version.
            $API_UserName = urlencode('my_api_username');
            $API_Password = urlencode('my_api_password');
            $API_Signature = urlencode('my_api_signature');
            $API_Endpoint = "https://api-3t.paypal.com/nvp";
            if("sandbox" === $environment || "beta-sandbox" === $environment) {
                $API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
            }
            $version = urlencode('51.0');

            // Set the curl parameters.
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
            curl_setopt($ch, CURLOPT_VERBOSE, 1);

            // Turn off the server and peer verification (TrustManager Concept).
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);

            // Set the API operation, version, and API signature in the request.
            $nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";

            // Set the request as a POST FIELD for curl.
            curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

            // Get response from the server.
            $httpResponse = curl_exec($ch);

            if(!$httpResponse) {
                exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
            }

            // Extract the response details.
            $httpResponseAr = explode("&", $httpResponse);

            $httpParsedResponseAr = array();
            foreach ($httpResponseAr as $i => $value) {
                $tmpAr = explode("=", $value);
                if(sizeof($tmpAr) > 1) {
                    $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
                }
            }

            if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
                exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
            }

            return $httpParsedResponseAr;
        }

        // Set request-specific fields.
        $transactionID = urlencode($txn_id);
        $refundType = urlencode('Full');                        // or 'Partial'
        //$amount;                                              // required if Partial.
        //$memo;                                                    // required if Partial.
        $currencyID = urlencode('USD');                         // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')

        // Add request-specific fields to the request string.
        $nvpStr = "&TRANSACTIONID=$transactionID&REFUNDTYPE=$refundType&CURRENCYCODE=$currencyID";

        if(isset($memo)) {
            $nvpStr .= "&NOTE=$memo";
        }

        if(strcasecmp($refundType, 'Partial') == 0) {
            if(!isset($amount)) {
                exit('Partial Refund Amount is not specified.');
            } else {
                $nvpStr = $nvpStr."&AMT=$amount";
            }

            if(!isset($memo)) {
                exit('Partial Refund Memo is not specified.');
            }
        }

        // Execute the API operation; see the PPHttpPost function above.
        $httpParsedResponseAr = PPHttpPost('RefundTransaction', $nvpStr);

        if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
            exit('Refund Completed Successfully: '.print_r($httpParsedResponseAr, true));
        } else  {
            exit('RefundTransaction failed: ' . print_r($httpParsedResponseAr, true));
        }



    }



}
else if (strcmp ($res, "INVALID") == 0) {

}
}
fclose ($fp);
}
?>

Upvotes: 1

Related Questions