Как остановить транзакцию PayPal изнутри IPN? - PullRequest
0 голосов
/ 14 февраля 2012

Я хочу иметь возможность остановить транзакцию, если проверяемые данные неверны.

Пример моего кода

// check that receiver_email is your Primary PayPal email
if($_POST['receiver_email'] != "my_email@mail.co.uk") {
exit(); // exit script
}

Я использую exit(), но во время тестированияпри использовании sandbox.paypal.com, когда адрес электронной почты неверен и exit() называется, транзакция все еще обрабатывается и, по сути, дает деньги песочнице.

1 Ответ

1 голос
/ 14 февраля 2012

Как уже упоминалось, это, безусловно, возможно.В идеале вы хотели бы разгрузить любую обработку от вашего обработчика IPN, чтобы обработчик IPN мог сосредоточиться на получении данных POST от PayPal.
Но вы можете использовать следующее, чтобы проверить, что оплаченная сумма соответствует ожидаемой сумме, и автоматически вернуть деньги, еслисумма отличается.

Например (на основе примера кода PayPal PHP, и быстро скомпонован).Примечание. Этот код служит только для иллюстрации логики, стоящей за этим.

<?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);
}
?>
...