Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

how to setup a IPN for paypal

Posted on 2011-03-07
7
Medium Priority
?
283 Views
Last Modified: 2012-05-11
Hi all
I am working with PHPBB and would like to add a trigger to posting from one of my area so that client cant post untill they have payed in paypal first so

------ Example FORUM -- View Current Subjects -- POST -- Enter Information client wants to post - Click post button - go to paypal confirm payment - post is submitted

any help would be great
0
Comment
Question by:awolarczuk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35062511
You're on the right track to use the PayPal IPN.  Once the "payment completed" signal is received, you will have the client's email address.  You can use this to set the authorization in your data base of clients.

One consideration you may want to take into account - some clients will have a different email in your system than the one they use for PayPal.  You would want to have an intersection table to account for this.

Information on how to use the PayPal IPN is available on the X.com web site.
0
 

Author Comment

by:awolarczuk
ID: 35062682
O ok cool mate how would i start this
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35062729
I can show you a teaching sample of the IPN.  You have to tell your PayPal account to use it for your payments.  One of the things that is dicey about working with the IPN (like a CRON job or Email Pipe) is that it has no browser output.  To facilitate getting my messages, I collect them in a buffer with ob_start() then I grab the buffer with ob_get_contents() and email the contents to myself.  Not very high-tech, but quite effective.

HTH, ~Ray
<?php // RAY_paypal_ipn.php - CUSTOM PayPal IPN PROCESSING


// LOCAL FUNCTIONS AND VARIABLES, DB STUFF, ETC. - NO SESSION HERE - FUNCTION warning_RAY() SENDS AN EMAIL MESSAGE
require_once('common.php');


// READ THE POST FROM PayPal AND ADD 'cmd'
$req      = 'cmd=_notify-validate';
$postdata = '';
foreach ($_POST as $key => $value)
{
    $postdata .= PHP_EOL . " $key = $value ";      // SAVE THE COLLECTION
    $$key     = trim(stripslashes($value));        // ASSIGN LOCAL VARIABLES
    $value    = urlencode(stripslashes($value));   // ENCODE FOR BOUNCE-BACK
    $req      .= "&$key=$value";                   // APPEND TO VERIFICATION STRING
}

// SET THE HEADERS FOR THE CONFIRMATION POST BACK TO PayPal
$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";

// OPEN THE HTTP PIPE FOR THE POST BACK TO PayPal
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);

// TEST FOR SUCCESSFUL OPENNING OF THE HTTP PIPE
if (!$fp) // HTTP ERROR
{
    warning_RAY("IPN HTTP ERROR", "FSOCKOPEN FAILED \n\n ERRNO=$errno \n\n ERRSTR=$errstr \n\n");
    die();
}

// WITH HTTP OPEN - WRITE HEADER AND REQUEST
fputs ($fp, $header . $req);

// WITH HTTP OPEN - READ PayPal RESPONSE
$paypal_reply   = '';
$paypal_headers = '';
while (!feof($fp))
{
    $paypal_reply    = fgets($fp, 1024);
    $paypal_headers .= $paypal_reply;
}
fclose ($fp);

// IF THIS IS TRULY A POST FROM PAYPAL, PROCESS ORDER NOTIFICATION
if ($paypal_reply == "VERIFIED")
{
    $errormsg = "";

    // IF PAYMENT IS NOT COMPLETED (MAY BE E-CHECK?)
    if ($payment_status != "Completed") { $errormsg .= "\nE: payment_status"; }

    // IF PAYMENT WAS NOT SENT TO ME?
    $receiver_email = strtolower($receiver_email);
    if ($receiver_email == "me@my.org") { } else { $errormsg .= "\nE: receiver_email"; } // ??? SET EMAIL ADDRESS

    // I AM NOT CHECKING SOME THINGS BECAUSE WE ARE USING ENCRYPTED OR STORED BUY-NOW BUTTONS
    if ($mc_currency != 'USD') { $errormsg .= "\nE: mc_currency"; }

    // CHECK FOR TXN_ID ALREADY PROCESSED - NORMAL FOR E-CHECK
    $sql = "SELECT txn_id FROM PAYPAL_ORDER_LOG WHERE txn_id = \"$txn_id\" ";
    if (!$result = mysql_query($sql, $db_connection)) { fatal_query_error($sql); }
    $num_rows = mysql_num_rows($result);
    if ($num_rows  > 0) { $errormsg .= "\nE: Transaction id $txn_id already processed $num_rows time(s)"; }

    // LOG THE TRANSACTION
    $order_date  = date('Y-m-d\TH:i:s');
    $item_number = mysql_real_escape_string($item_number, $db_connection);
    $mc_gross    = mysql_real_escape_string($mc_gross,    $db_connection);
    $address_zip = mysql_real_escape_string($address_zip, $db_connection);
    $txn_id      = mysql_real_escape_string($txn_id,      $db_connection);
    $receipt_id  = mysql_real_escape_string($receipt_id,  $db_connection);
    $last_name   = mysql_real_escape_string($last_name,   $db_connection);
    $payer_email = mysql_real_escape_string($payer_email, $db_connection);
    $postdata    = mysql_real_escape_string($postdata,    $db_connection);
    $sql = "INSERT INTO PAYPAL_ORDER_LOG (    order_date,      item_number,      mc_gross,      address_zip,      txn_id,      receipt_id,      last_name,      payer_email,      postdata  )
            VALUES                       ( \"$order_date\", \"$item_number\", \"$mc_gross\", \"$address_zip\", \"$txn_id\", \"$receipt_id\", \"$last_name\", \"$payer_email\", \"$postdata\")";
    if (!$result = mysql_query($sql)) { fatal_query_error($sql); }

    // ISSUE A MESSAGE TO THE HOME OFFICE ?
    warning_RAY("IPN VERIFIED", "IPN REPLY $paypal_headers \n\n$errormsg \n\nPOST DATA FOLLOWS: $postdata \n\n");

    // GENERATE ARRAYS OF PURCHASE DATA FROM THE WEIRD PAYPAL VARIABLE NAMES
    // NOTE: NO POSITION ZERO IN THESE ARRAYS
    $w_item_number = array();
    $w_quantity    = array();
    $w_mc_gross    = array();
    $w_item_name   = array();

    // IF TRANSACTION TYPE IS CART, MAY BE MULTIPLE ITEMS IN DIFFERENT QUANTITIES - LOAD ARRAYS
    // NOTE NOTE NOTE NO POSITION ZERO IN THESE ARRAYS
    if ($txn_type == "cart")
    {
        while ($num_cart_items > 0)
        {
            $proxy = "item_number" . "$num_cart_items";
            $w_item_number[$num_cart_items] = $$proxy;

            $proxy = "quantity" . "$num_cart_items";
            $w_quantity[$num_cart_items] = $$proxy;

            $proxy = "mc_gross_" . "$num_cart_items";
            $w_mc_gross[$num_cart_items] = $$proxy;

            $proxy = "item_name" . "$num_cart_items";
            $w_item_name[$num_cart_items] = $$proxy;

            $num_cart_items--;
        }
    }
    else
    {
        // NOT A CART - SINGLETON ITEM ONLY - NORMALIZE INTO ARRAY FOR USE WITH ITERATOR
        // NOTE NOTE NOTE NO POSITION ZERO IN THESE ARRAYS
        $w_item_number[1] = $item_number;
        $w_quantity[1]    = $quantity;
        $w_mc_gross[1]    = $mc_gross;
        $w_item_name[1]   = $item_name;
    }

// *****************************************************
// ACTIVATE THIS CODE BLOCK TO SEE WHAT IS IN THE ORDER ARRAYS
//
//    ob_start();
//    echo "<pre>\n";
//    echo "\nW_ITEM_NUMBER"; var_dump($w_item_number);
//    echo "\nW_QUANTITY";    var_dump($w_quantity);
//    echo "\nW_MC_GROSS";    var_dump($w_mc_gross);
//    echo "\nW_ITEM_NAME";   var_dump($w_item_name);
//    $foo = ob_get_contents();
//    ob_end_clean();
//    warning_RAY("IPN VARDUMPS", "$foo \n\n");
// *****************************************************


    // ITERATE OVER THE ARRAYS
    $kount = 0; // NO POSITION ZERO IN THESE ARRAYS
    while ($kount < count($w_item_number))
    {
        $kount++; // BUMP BEFORE WORKING
        $my_item_number = $w_item_number[$kount];
        $my_quantity    = $w_quantity[$kount];
        $my_mc_gross    = $w_mc_gross[$kount];
        $my_item_name   = $w_item_name[$kount];

        //
        // ??? PROCESS THE ORDERS USING YOUR BUSINESS LOGIC
        //

    } // END ITERATION OVER THE ORDERS

    // END OF NORMAL PAYPAL IPN PROCESSING
    die();
}

// NOT NORMAL PROCESSING
// LOG INVALID POSTS FOR MANUAL INVESTIGATION AND INTERVENTION
if ($paypal_reply == "INVALID")
{
    warning_RAY("IPN INVALID", "IPN REPLY $paypal_headers \n\n$errormsg \n\nPOST DATA FOLLOWS: $postdata \n\n");
    die();
}

// OTHERWISE, PayPal RETURNED BAD DATA (OR INTERNET HTTP ERRORS OR TIMEOUT)
warning_RAY("IPN REPLY UNKNOWN", "IPN REPLY $paypal_headers \n\n$errormsg \n\nPOST DATA FOLLOWS: $postdata \n\n");
die();

Open in new window

0
Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

 

Author Comment

by:awolarczuk
ID: 35062733
do i attach the php code i sent to you on the post button ??
the problem is that some area of the website allows free posting how would i get around this???
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35064093
@awolarczuk:  It sounds like you need the services of a professional developer.  Here is a thumbnail sketch of what you would want to have built.

1. A data base that can record who is allowed into the paid pages of the site.  This is what the IPN would update.
2. An IPN that can update the data base
3. A login routine (or similar) that can distinguish between the paid and the unpaid.
4. Appropriate hooks in the PHPBB system to call the login routine and limit or allow access to the protected paid pages.

When a payment is received at PayPal (and under certain other circumstances) PayPal will make a POST request to your IPN script.  The script must decode the request, update the data base and send a response to the client.  It's fairly advanced programming -- expect several hundred lines of code if it is done correctly.  Fortunately with a Google search you can find a professional PayPal developer.

Best regard,s ~Ray
0
 

Author Comment

by:awolarczuk
ID: 35064513
How about PDT would that do what i need to do
0
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 2000 total points
ID: 35064774
PDT (Payment Data Transfer) is a little bit different animal.  I think you have access to more information in the IPN, but PayPal is constantly evolving, and you may find enough information in the PDT.  What you will not find is the secondary calls, like payment clearing on an eCheck, a disputed payment, or a credit card reversal.  You need to keep account of these things until the money is in your hands.
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_html_paymentdatatransfer

PayPal has about a 160+ page developers guide in PDF format on their site.  You need to download the latest version whenever you start a build because even if it says it dates from last December, you may find revisions that are not reflected in the revision numbers.  At least I have.
0

Featured Post

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question