Solved

how to setup a IPN for paypal

Posted on 2011-03-07
7
272 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
  • 4
  • 3
7 Comments
 
LVL 109

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 109

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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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 109

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 109

Accepted Solution

by:
Ray Paseur earned 500 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

E-commerce is quite a gambling world, and you should never entrust your business to a lucky chance. In order to outrun your competitors in a race to attract as many customers as possible, you need to have a well thought-out strategy under your belt.…
For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

837 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