/**
  * Order is completed = payment done.
  * Update event booking meta to indicate this, for Event-related Products.
  */
 function mp_product_order_paid($order)
 {
     $user_id = $order->post_author;
     $total_payment = $event_ids = array();
     if (is_array($order->mp_cart_info) && count($order->mp_cart_info)) {
         foreach ($order->mp_cart_info as $product_id => $variations) {
             foreach ($variations as $variation) {
                 $event_id = $this->order_to_event_id($product_id, $variation);
                 if (!$event_id) {
                     continue;
                 }
                 $event_ids[] = $event_id;
                 $tickets = !empty($total_payment[$event_id]) ? $total_payment[$event_id] : array('count' => 0, 'order_id' => $order->ID, 'product_id' => $product_id);
                 $tickets['count'] += (int) $variation['quantity'];
                 $total_payment[$event_id] = $tickets;
             }
         }
     }
     $user_bookings = array();
     $event_ids = join(',', array_unique($event_ids));
     global $wpdb;
     $table = Eab_EventsHub::tablename(Eab_EventsHub::BOOKING_TABLE);
     $bookings = $wpdb->get_results($wpdb->prepare("SELECT event_id,id FROM {$table} WHERE user_id=%d AND event_id IN ({$event_ids})", $user_id));
     foreach ($bookings as $booking) {
         $user_bookings[$booking->event_id] = $booking->id;
     }
     foreach ($total_payment as $event_id => $booking_info) {
         if (empty($user_bookings[$event_id])) {
             //continue; // Possibly paying for wrong variation!
             // Well, the guy apparently paid... so book him
             $wpdb->query($wpdb->prepare("INSERT INTO " . Eab_EventsHub::tablename(Eab_EventsHub::BOOKING_TABLE) . " VALUES(null, %d, %d, NOW(), 'yes') ON DUPLICATE KEY UPDATE `status` = 'yes';", $event_id, $user_id));
             $user_bookings[$event_id] = $wpdb->insert_id;
             // --todo: Add to BP activity stream
             do_action('incsub_event_booking_yes', $event_id, $user_id);
             // End booking extras
         }
         $booking_id = $user_bookings[$event_id];
         Eab_EventModel::update_booking_meta($booking_id, 'booking_transaction_key', serialize($booking_info));
         Eab_EventModel::update_booking_meta($booking_id, 'booking_ticket_count', $booking_info['count']);
     }
 }
 /**
  * Approve a payment on the admin side
  */
 function approve_payment()
 {
     $user_id = $_POST["user_id"];
     $event_id = $_POST["event_id"];
     if (!$user_id or !$event_id) {
         die(json_encode(array("error" => "User ID or Event ID is missing")));
     }
     $payments = maybe_unserialize(stripslashes(Eab_EventModel::get_booking_meta($event_id, "manual_payment")));
     if (!is_array($payments)) {
         die(json_encode(array("error" => "Record could not be found")));
     } else {
         foreach ($payments as $key => $payment) {
             if ($payment["id"] == $user_id) {
                 $payments[$key]["stat"] = "paid";
                 $payments = array_filter(array_unique($payments));
                 Eab_EventModel::update_booking_meta($event_id, "manual_payment", serialize($payments));
                 die;
             }
         }
     }
     die(json_encode(array("error" => "Record could not be found")));
 }
 function process_paypal_ipn()
 {
     $req = 'cmd=_notify-validate';
     $request = $_REQUEST;
     $post_values = "";
     $cart = array();
     foreach ($request as $key => $value) {
         $value = urlencode(stripslashes($value));
         $req .= "&{$key}={$value}";
         $post_values .= " {$key} : {$value}\n";
     }
     $pay_to_email = $request['receiver_email'];
     $pay_from_email = $request['payer_email'];
     $transaction_id = $request['txn_id'];
     $status = $request['payment_status'];
     $amount = $request['mc_gross'];
     $ticket_count = $request['quantity'];
     // Ticket count is the number of paid for tickets
     $currency = $request['mc_currency'];
     $test_ipn = $request['test_ipn'];
     $event_id = $request['item_number'];
     $booking_id = (int) $request['booking_id'];
     $blog_id = (int) $request['blog_id'];
     if (is_multisite()) {
         switch_to_blog($blog_id);
     }
     $eab_options = get_option('incsub_event_default');
     $header = "";
     // post back to PayPal system to validate
     $header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
     // Sandbox host: http://stackoverflow.com/questions/17477815/receiving-error-invalid-host-header-from-paypal-ipn
     if ((int) @$eab_options['paypal_sandbox'] == 1) {
         $header .= "Host: www.sandbox.paypal.com\r\n";
     } else {
         $header .= "Host: www.paypal.com\r\n";
     }
     // End host
     $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
     $header .= "Connection: Close\r\n";
     $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
     if ((int) @$eab_options['paypal_sandbox'] == 1) {
         $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
     } else {
         $fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);
     }
     define('EAB_PROCESSING_PAYPAL_IPN', true);
     $booking_obj = Eab_EventModel::get_booking($booking_id);
     if (!$booking_obj || !$booking_obj->id) {
         header('HTTP/1.0 404 Not Found');
         header('Content-type: text/plain; charset=UTF-8');
         print 'Booking not found';
         exit(0);
     }
     if ($booking_obj->event_id != $event_id) {
         header('HTTP/1.0 404 Not Found');
         header('Content-type: text/plain; charset=UTF-8');
         print 'Fake event id. REF: PP0';
         exit(0);
     }
     if (@$eab_options['currency'] != $currency) {
         header('HTTP/1.0 400 Bad Request');
         header('Content-type: text/plain; charset=UTF-8');
         print 'We were not expecting you. REF: PP1';
         exit(0);
     }
     if ($amount != $ticket_count * apply_filters('eab-payment-event_price-for_user', get_post_meta($event_id, 'incsub_event_fee', true), $event_id, $booking_obj->user_id)) {
         header('HTTP/1.0 400 Bad Request');
         header('Content-type: text/plain; charset=UTF-8');
         print 'We were not expecting you. REF: PP2';
         exit(0);
     }
     if (!$ticket_count) {
         header('HTTP/1.0 400 Bad Request');
         header('Content-type: text/plain; charset=UTF-8');
         print 'Cheapskate. REF: PP2';
         exit(0);
     }
     if (strtolower($pay_to_email) != strtolower(@$eab_options['paypal_email'])) {
         header('HTTP/1.0 400 Bad Request');
         header('Content-type: text/plain; charset=UTF-8');
         print 'We were not expecting you. REF: PP3';
         exit(0);
     }
     if (!$fp) {
         header('HTTP/1.0 400 Bad Request');
         header('Content-type: text/plain; charset=UTF-8');
         print 'We were not expecting you. REF: PP4';
         exit(0);
     } else {
         fputs($fp, $header . $req);
         while (!feof($fp)) {
             $res = trim(fgets($fp, 1024));
             if (strcmp($res, "VERIFIED") == 0) {
                 break;
             }
             if (strcmp($res, "INVALID") == 0) {
                 break;
             }
         }
         if (strcmp($res, "VERIFIED") == 0) {
             if ($test_ipn == 1) {
                 if ((int) @$eab_options['paypal_sandbox'] == 1) {
                     // Sandbox, it's allowed so do stuff
                     Eab_EventModel::update_booking_meta($booking_obj->id, 'booking_transaction_key', $transaction_id);
                     Eab_EventModel::update_booking_meta($booking_obj->id, 'booking_ticket_count', $ticket_count);
                     do_action('eab-ipn-event_paid', $event_id, $amount, $booking_obj->id);
                 } else {
                     // Sandbox, not allowed, bail out
                     header('HTTP/1.0 400 Bad Request');
                     header('Content-type: text/plain; charset=UTF-8');
                     print 'We were not expecting you. REF: PP1';
                     exit(0);
                 }
             } else {
                 // Paid
                 Eab_EventModel::update_booking_meta($booking_obj->id, 'booking_transaction_key', $transaction_id);
                 Eab_EventModel::update_booking_meta($booking_obj->id, 'booking_ticket_count', $ticket_count);
                 do_action('eab-ipn-event_paid', $event_id, $amount, $booking_obj->id);
             }
             header('HTTP/1.0 200 OK');
             header('Content-type: text/plain; charset=UTF-8');
             print 'Success';
             exit(0);
         } else {
             if (strcmp($res, "INVALID") == 0) {
                 $message = "Invalid PayPal IPN {$transaction_id}";
             }
         }
         fclose($fp);
     }
     if (is_multisite()) {
         restore_current_blog();
     }
     header('HTTP/1.0 200 OK');
     header('Content-type: text/plain; charset=UTF-8');
     print 'Thank you very much for letting us know. REF: ' . $message;
     exit(0);
 }