/**
  * Processes the  custom bulk actions on the Orders screen bulk action drop-down
  *
  * + Create & send invoice
  * + Create draft invoice
  * + Apply invoice payment
  *
  * @since 3.0
  */
 public function process_order_bulk_actions()
 {
     global $typenow;
     if ('shop_order' == $typenow) {
         // get the action
         $wp_list_table = _get_list_table('WP_Posts_List_Table');
         $action = $wp_list_table->current_action();
         $actions = array('wc_freshbooks_create_and_send_invoice', 'wc_freshbooks_create_draft_invoice', 'wc_freshbooks_apply_invoice_payment', 'wc_freshbooks_update_invoice_status', 'wc_freshbooks_update_invoice_from_order');
         // return if not processing our actions
         if (!in_array($action, $actions)) {
             return;
         }
         // security check
         check_admin_referer('bulk-posts');
         // make sure order IDs are submitted
         if (isset($_REQUEST['post'])) {
             $order_ids = array_map('absint', $_REQUEST['post']);
         }
         // return if there are no orders to export
         if (empty($order_ids)) {
             return;
         }
         // give ourselves an unlimited timeout if possible
         @set_time_limit(0);
         foreach ($order_ids as $order_id) {
             $order = new WC_FreshBooks_Order($order_id);
             switch ($action) {
                 case 'wc_freshbooks_create_and_send_invoice':
                     $order->create_invoice();
                     break;
                 case 'wc_freshbooks_create_draft_invoice':
                     $order->create_invoice(false);
                     break;
                 case 'wc_freshbooks_apply_invoice_payment':
                     $order->apply_invoice_payment();
                     break;
                 case 'wc_freshbooks_update_invoice_status':
                     $order->refresh_invoice();
                     break;
                 case 'wc_freshbooks_update_invoice_from_order':
                     $order->update_invoice_from_order();
                     break;
                 default:
                     break;
             }
         }
     }
 }
 /**
  * Handle payment webhook events
  *
  * @link http://developers.freshbooks.com/docs/callbacks/#events
  *
  * @param string $action the event type
  * @param string $payment_id the associated payment ID
  * @since 3.0
  */
 public function handle_payment($action, $payment_id)
 {
     try {
         // try to find matching order by payment ID
         $order_id = $this->get_object_by_freshbooks_id('order', 'payment', $payment_id);
         // if a payment was created in FreshBooks manually, look up the associated invoice first
         if (!$order_id) {
             $payment = wc_freshbooks()->get_api()->get_payment($payment_id);
             // no payment found
             if (!$payment) {
                 return;
             }
             // invoice IDs included as part of the payment response contain
             // leading zeroes for some odd reason, so strip them first
             $order_id = $this->get_object_by_freshbooks_id('order', 'invoice', ltrim($payment['invoice_id'], '0'));
             // no matching invoice found, likely deleted
             if (!$order_id) {
                 return;
             }
         }
         $order = new WC_FreshBooks_Order($order_id);
         if ('delete' == $action) {
             delete_post_meta($order->id, '_wc_freshbooks_payment_id', $payment_id);
         } else {
             update_post_meta($order->id, '_wc_freshbooks_payment_id', $payment_id);
         }
         $order->refresh_invoice();
     } catch (SV_WC_API_Exception $e) {
         wc_freshbooks()->log(sprintf('Payment handling failed: %s', $e->getMessage()));
     }
 }