Solved

how to setup a IPN for paypal

Posted on 2011-03-07
7
268 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 108

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 108

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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

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 108

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 108

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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

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.…
This article discusses how to create an extensible mechanism for linked drop downs.
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 …
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

705 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now