草庐IT

php - 电子邮件不使用sandox ipn发送给 Paypal 中的买家

coder 2024-04-17 原文

你好,我正在开发一个 paypal 插件,可以添加响应者、添加产品。

我正在开发用于测试的沙箱。

我做响应者而不是添加产品相关的响应者。在前端,当我点击“购买”按钮时,它会转到 sandbox.paypal,在这里我完成付款程序,在我的虚拟商家帐户上我接受付款并知道发送给买家的电子邮件完成但电子邮件不是发送给我,我阅读了代码 10 遍,但我没有得到问题。

这是我的代码:

Paypal 表格:

<form name="_xclick" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" target="_blank">
    <input type="hidden" name="cmd" value="_xclick">
    <input type="hidden" name="business" value="'.$paypalID.'">
    <input type="hidden" name="return" value="'.$return_url.'">
    <input type="hidden" name="currency_code" value="'.$currency.'">
    <input type="hidden" name="item_name" value="'.$product_name.'">
    <input type="hidden" name="amount" id="p'.$product_id.'" value="'.$product_price.'">
    <input type="hidden" name="custom" value="'.$responderID.'">
    <input name="notify_url" value="'.plugin_dir_url( __FILE__ ).'ipn_sandbox.php" type="hidden">
    <input type="image" src="'.$upload_image.'" border="0" name="submit" alt="Make payments with PayPal - its fast, free and secure!">
</form>

这是我的 ipn_sandbox.php 代码:

<?php
    // STEP 1: Read POST data
    // reading posted data from directly from $_POST causes serialization 
    // issues with array data in POST
    // reading raw POST data from input stream instead. 

    $raw_post_data = file_get_contents('php://input');
    $raw_post_array = explode('&', $raw_post_data);

    $myPost = array();
    foreach ($raw_post_array as $keyval) {
        $keyval = explode ('=', $keyval);

        if (count($keyval) == 2)
            $myPost[$keyval[0]] = urldecode($keyval[1]);
    }

    // read the post from PayPal system and add 'cmd'
    $req = 'cmd=_notify-validate';
    if(function_exists('get_magic_quotes_gpc')) {
        $get_magic_quotes_exists = true;
    } 

    foreach ($myPost as $key => $value) {        
        if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 
            $value = urlencode(stripslashes($value)); 
        } else {
            $value = urlencode($value);
        }
        $req .= "&$key=$value";
    }

    // STEP 2: Post IPN data back to paypal to validate
    $ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

    if( !($res = curl_exec($ch)) ) {
        curl_close($ch);
        exit; 
    }
    curl_close($ch);

    $path = $_SERVER['DOCUMENT_ROOT'];

    include_once $path . '/wp-config.php';
    include_once $path . '/wp-load.php';
    include_once $path . '/wp-includes/wp-db.php';
    include_once $path . '/wp-includes/pluggable.php';

    global $wpdb;
    if (strcmp ($res, "VERIFIED") == 0) {
        $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'];
        $responderID            =   $_POST['custom'];
        $name                   =   $_POST['first_name'];
        $payment_status         =   $_POST['payment_status'];
        $site_url               =   get_bloginfo('wpurl');
        $table_resp             =   $wpdb->prefix.'paypal_responders';
        $responder_to_use       =   $wpdb->get_row("SELECT * FROM $table_resp WHERE id ='$responderID'");
        $subject                =   $responder_to_use->subject;
        $from                   =   $responder_to_use->from_email;
        $attachment             =   $responder_to_use->attachment;
        $att_secure             =   $responder_to_use->att_secure;
        $message        .=  $responder_to_use->message_body;
        $message                .=  '<br /><br />
                                    <a title="Click here to download Attachment" href="'.plugin_dir_url(__FILE__).'responders/download.php?filename='.$att_secure.'" width="150" height="150" target="_blank">Click here to download Attachment</a>';

        if($message){
            $message    =   str_replace('[item_name]',$item_name,$message);
            $message    =   str_replace('[txn_id]',$txn_id,$message);
            $message    =   str_replace(' [mc_gross]',$payment_amount,$message);
            $message    =   str_replace('[mc_currency]',$payment_currency,$message);
            $message    =   str_replace('[receiver_email]',$receiver_email,$message);
            $message    =   str_replace('[payer_email]',$payer_email,$message);
            $message    =   str_replace('[name]',$name,$message);
            $message    =   str_replace('[site_url]',$site_url,$message);
            $message    =   str_replace('[payment_status]',$payment_status,$message);
        }else{
            $message    =       'Dear '.$name.',
                                Thank you for your purchase from '.$site_url.'. The details of your purchase are below.
                                Transaction ID: '.$txn_id.'
                                Item Name: '.$item_name.'
                                Payment Amount: '.$payment_amount.'
                                Payment Amount: '.$payment_status.'
                                Paid to: '.$receiver_email.'
                                Thanks and Enjoy!
                                ~Enigma Digital <br />
                                <br />
                                <a title="Click here to download Attachment" href="'.plugin_dir_url(__FILE__).'responders/download.php?filename='.$att_secure.'" width="150" height="150" target="_blank">Click here to download Attachment</a>';
        }

        $table          =   $wpdb->prefix . "paypal_transactions";
        $txn_id_check   =   $wpdb->get_results("SELECT * FROM $table WHERE txn_id ='$txn_id'");

        if(!$txn_id_check){
            $data   =   array(
                            'txn_id'            =>      $txn_id,
                            'product_name'      =>      $item_name,
                            'product_price'     =>      $payment_amount,
                            'payer_email'       =>      $payer_email,
                        );

            $wpdb->insert($table,$data) or die(mysql_error());
            $num = md5(time());

            $headers .= 'From: ' .$from. "\r\n" .'Reply-To: ' .$from . "\r\n";
            $headers  .= 'MIME-Version: 1.0' . "\r\n";
            $headers  .= "Content-Type: text/html; charset=iso-8859-1 ";
            $headers  .= "--".$num."--";

            //mail to buyer
            mail( $payer_email , $subject, $message, $headers );
        }
    }
?>

我也使用 wp_mail() 除了 mail() 但没有任何反应。

任何人都可以帮助解决问题。

最佳答案

代码存在一些问题,您可以做一些事情来开始调试过程。不过,您不太可能在这里得到直接的解决方案,因为这是一个开放式问题。

在执行任何操作之前,请确保 error_reporting 设置为 E^ALL 并且 display_errors 设置为 On在您的 php.ini 中。 (Turorial, if you need it)。检查您的 error_log - 如果存在 - 立即获得线索。

在向其附加更多数据之前,您需要声明 $message。您开始将数据附加到第 77 行的 $message ($message .= $responder_to_use->message_body;) 但尚未设置,这将产生警告.

现在有 3 个原因无法发送电子邮件本身:

  1. 您的服务器未设置为发送邮件。
  2. $txn_id_check 未设置或为 false。如果 $txn_id 不在您的数据库中,就会出现这种情况。我假设您在开始交易时添加了这一行 - 但您检查过了吗?
  3. 您在其中一个包含的文件中有语法错误。

让我们解决#1。在服务器上创建一个文件,其中只有一行会向您发送一封简单的电子邮件:

<?php mail('your@email', 'Test email', 'Yay, I can send mail!'); ?>

在浏览器中访问该文件。检查您的收件箱,并检查您的垃圾邮件。没有邮件?这就是问题所在。


下一个 #2:这可能是在用户访问 PayPal 之前将交易添加到数据库的脚本的问题。我们没有此代码,但您可以轻松检查 - 只需检查数据库以查看是否存在任何行。


#3:这里应该很容易检查语法错误,只需直接在浏览器中访问 IPN 脚本即可。将向您显示 fatal error 。


还是不行?其他地方可能有问题。最好的检查方法是进行一些基本的调试...

首先通过电子邮件将完整的 $_POST 数组发送给您自己,就在脚本的顶部。

<?php
    mail('your@email', 'Full Post Data - '.time(), print_r($_REQUEST, true));

    // STEP 1: Read POST data
    // reading posted data from directly from $_POST causes serialization 
    // issues with array data in POST
    // reading raw POST data from input stream instead. 

    $raw_post_data = file_get_contents('php://input');
    $raw_post_array = explode('&', $raw_post_data);

    [...]

最后将脚本的输出通过电子邮件发送给自己。

<?php
    ob_start();

    $time = time(); // Referenced in your email subjects. It will get confusing with lots of these emails otherwise. Gmail and other clients who use a conversation view will properly catalogue these emails if the subjects match.

    mail('your@email', 'Full Post Data - '.$time, print_r($_REQUEST, true));

    // STEP 1: Read POST data
    // reading posted data from directly from $_POST causes serialization 
    // issues with array data in POST
    // reading raw POST data from input stream instead. 

    [...] // Rest of your script here...

    $output_buffer = ob_get_contents();
    ob_end_clean();

    mail('your@email', 'Output buffer - '.$time, $output_buffer);
?>

关于php - 电子邮件不使用sandox ipn发送给 Paypal 中的买家,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25662843/

有关php - 电子邮件不使用sandox ipn发送给 Paypal 中的买家的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  4. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  5. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  6. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  7. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  8. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  9. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  10. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

随机推荐