php - 如何从 IPN 中停止 PayPal 交易?

标签 php paypal payment-processing paypal-ipn

如果我检查的详细信息不正确,我希望能够停止交易。

我的代码示例

// 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()交易仍在进行中,本质上是给沙盒账户钱。

最佳答案

如前所述,这当然是可能的。理想情况下,您希望从 IPN 处理程序卸载任何处理,以便 IPN 处理程序可以专注于从 PayPal 接收 POST 数据。
但您可以使用以下方法检查支付金额是否与预期金额相符,如果金额不同则自动退款。

例如(基于 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);
}
?>

关于php - 如何从 IPN 中停止 PayPal 交易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9270334/

相关文章:

php - CS Cart 4移动支付界面

php - 尝试在 MYSQL 中使用 IF 和 MAX 来获取两个表之间的最新日期

javascript - 访问 braintree 数组内部的问题

.net - PayPal API 通过交易 ID 获取送货地址

PHP : edit issued invoice

c# - 对 cybersource 的无效交易尝试给出错误

php - CSRF token 与 Nonce 混淆——它们是一样的吗?

php - 从另一个插件/扩展类覆盖插件的功能

php - 易受 SQL 注入(inject)攻击的 GET 参数 - PHP

paypal - PayFlow 定期付款