OK, I've spent the day working on this project, and I've almost got it working. My three biggest remaining hurdles are getting the price type into the booking_comment table field, cleaning up the display of the EME fields on the Paypal form page, and making it more customizable and user friendly. Franky, do you think you might have some advice?
It all goes into the custom_functions.php of my theme, and then I have two pages in my WordPress that each call a single shortcode to run the Paypal form (seen by the user) and the Paypal IPN listener (not seen by the user). Like I said, it's not very elegant, but it's getting the job done (I hope!)
It looks for custom attributes with "PRICE" in the name to build options for the Paypal form.
<?php session_start();
add_action('eme_insert_rsvp_action','do_my_stuff');
function do_my_stuff($booking) {
$eventinfo = eme_get_event($booking['event_id']);
if($eventinfo['registration_requires_approval']) {
//redirect to accept payment page, using post of event_id
$_SESSION['booking_id']=$booking['booking_id'];
$_SESSION['event_id'] = $booking['event_id'];
header("Location: http://www.something.com/event-registration-payment-page/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
} else {
// DON'T DO ANYTHING, SINCE THIS FUNCTION IS JUST FOR PAYPAL
}
}
function build_paypal_buttons_page () {
$event_id=$_SESSION['event_id'];
$eventinfo = eme_get_event($event_id);
// print_r($eventinfo);
$display = "";
$display .= $eventinfo['event_name']."<br>\n";
$display .= $eventinfo['event_start_date']."<br>\n";
$display .= $eventinfo['event_start_time']."<br>\n";
$display .= $eventinfo['location_name']."<br>\n";
$display .= $eventinfo['location_address']."<br>\n";
$display .= $eventinfo['location_town']."<br>\n";
//add Paypal form, based on sample code from https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_formbasics
$display .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">'."\n";
$display .= ' <!-- Identify your business so that you can collect the payments. -->'."\n";
// $display .= '<input type="hidden" name="business" value="paypaldev@something.com">'."\n";
$display .= '<input type="hidden" name="business" value="paypal_1310754343_biz@something.com">'."\n";
$display .= ' <!-- Specify a Buy Now button. -->'."\n";
$display .= '<input type="hidden" name="cmd" value="_xclick">'."\n";
$display .= '<input type="hidden" name="notify_url" value="http://www.something.com/event-payment-complete">'."\n";
$display .= ' <!-- Specify details about the item that buyers will purchase. --> '."\n";
$display .= '<input type="hidden" name="item_name" value="'.$eventinfo['event_name'].'">'."\n";
$display .= '<input type="hidden" name="item_number" value="'.$_SESSION['booking_id'].'">'."\n";
$display .= '<input type="hidden" name="currency_code" value="USD">'."\n";
$display .= '<!-- Provide a dropdown menu option field with prices. -->'."\n";
$display .= '<input type="hidden" name="on0" value="Registration_Type">Registration Type<br />'."\n";
$display .= '<select name="os0">'."\n";
$dis2 = "";
$attrib_counter = 0;
foreach ($eventinfo['event_attributes'] as $attrib_name => $attrib_value) {
if (strpos($attrib_name,"PRICE") !== FALSE) {
$attrib_name = str_ireplace ("_PRICE","",$attrib_name);
$display .= '<option value="'.$attrib_name.'">'.$attrib_name.' - $'.$attrib_value.' USD</option>'."\n";
$dis2 .= '<input type="hidden" name="option_select'.$attrib_counter.'" value="'.$attrib_name.'">'."\n";
$dis2 .= '<input type="hidden" name="option_amount'.$attrib_counter.'" value="'.$attrib_value.'">'."\n";
} // close if PRICE
$attrib_counter++;
} // close foreach
$display .= '</select>'."\n";
$display .= '<br />'."\n";
$display .= '<!-- Specify the price that PayPal uses for each option. -->'."\n";
$display .= '<input type="hidden" name="option_index" value="0">'."\n";
$display .= $dis2;
$display .= '<!-- Display the payment button. -->'."\n";
$display .= '<input type="image" name="submit" border="0"'."\n";
$display .= 'src="https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"'."\n";
$display .= 'alt="PayPal -The safer, easier way to pay online">'."\n";
$display .= '<img alt="" border="0" width="1" height="1"'."\n";
$display .= 'src="https://www.paypal.com/en_US/i/scr/pixel.gif" >'."\n";
$display .= '</form>'."\n";
echo $display;
}
add_shortcode ('eme_paypal_buttons','build_paypal_buttons_page');
function eme_add_comment_from_paypal ($newcomment, $booking_id) {
//THIS FUNCTION DOES NOT WORK
global $wpdb;
$bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
$sql = "SELECT * FROM $bookings_table WHERE booking_id = $booking_id";
$bookings = $wpdb->get_results($sql, ARRAY_A);
if ($bookings) {
foreach ($bookings as $booking) {
$oldcomment = $booking['booking_comment'];
}
}
$oldcomment = $oldcomment . ", " . $newcomment;
$sql = "UPDATE $bookings_table SET booking_comment = $oldcomment WHERE booking_id = $booking_id";
$wpdb->query($sql);
}
function eme_paypal_listener () {
error_reporting(E_ALL ^ E_NOTICE);
$email = 'me@something.com';
$header = "";
$emailtext = "";
// Read the post from PayPal and add 'cmd'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc'))
{
$get_magic_quotes_exits = true;
}
foreach ($_POST as $key => $value)
// Handle escape characters, which depends on setting of magic quotes
{
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
// Post back to PayPal 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.sandbox.paypal.com', 443, $errno, $errstr, 30);
//$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// Process validation from PayPal
// TODO: This sample does not test the HTTP response code. All
// HTTP response codes must be handles or you should use an HTTP
// library, such as cUrl
if (!$fp) { // HTTP ERROR
} else {
// NO HTTP ERROR
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// TODO:
// 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 'VERIFIED', send an email of IPN variables and values to the
// specified email address
eme_approve_booking($_POST['item_number']);
eme_add_comment_from_paypal ($_POST['item_name'], $_POST['item_number']);
foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}
// echol( "Live-VERIFIED IPN". $emailtext . "\n\n" . $req);
// mail($email, "Live-VERIFIED IPN", $emailtext . "\n\n" . $req);
} else if (strcmp ($res, "INVALID") == 0) {
// If 'INVALID', send an email. TODO: Log for manual investigation.
foreach ($_POST as $key => $value){
$emailtext .= $key . " = " .$value ."\n\n";
}
// echo( "Live-INVALID IPN". $emailtext . "\n\n" . $req);
// mail($email, "Live-INVALID IPN", $emailtext . "\n\n" . $req);
}
}
}
fclose ($fp);
}
add_shortcode ('eme_paypal_listener','eme_paypal_listener');
?>