function run()
 {
     //Get the data from stripe
     $data_raw = file_get_contents("php://input");
     $data = json_decode($data_raw);
     if (!$data) {
         CRM_Core_Error::Fatal("Stripe Callback: cannot json_decode data, exiting. <br /> {$data}");
     }
     $test_mode = !$data->livemode;
     $stripe_key = CRM_Core_DAO::singleValueQuery("SELECT user_name FROM civicrm_payment_processor WHERE payment_processor_type = 'Stripe' AND is_test = '{$test_mode}'");
     require_once "packages/stripe-php/lib/Stripe.php";
     Stripe::setApiKey($stripe_key);
     //Retrieve Event from Stripe using ID even though we already have the values now.
     //This is for extra security precautions mentioned here: https://stripe.com/docs/webhooks
     $stripe_event_data = Stripe_Event::retrieve($data->id);
     $customer_id = $stripe_event_data->data->object->customer;
     switch ($stripe_event_data->type) {
         //Successful recurring payment
         case 'invoice.payment_succeeded':
             //Get the Stripe charge object
             try {
                 $charge = Stripe_Charge::retrieve($stripe_event_data->data->object->charge);
             } catch (Exception $e) {
                 CRM_Core_Error::Fatal("Failed to retrieve Stripe charge.  Message: " . $e->getMessage());
                 break;
             }
             //Find the recurring contribution in CiviCRM by mapping it from Stripe
             $rel_info_query = CRM_Core_DAO::executeQuery("SELECT invoice_id, end_time FROM civicrm_stripe_subscriptions WHERE customer_id = '{$customer_id}'");
             if (!empty($rel_info_query)) {
                 $rel_info_query->fetch();
                 $invoice_id = $rel_info_query->invoice_id;
                 $end_time = $rel_info_query->end_time;
             } else {
                 CRM_Core_Error::Fatal("Error relating this customer ({$customer_id}) to the one in civicrm_stripe_subscriptions");
             }
             //Compare against now + 24hrs to prevent charging 1 extra day.
             $time_compare = time() + 86400;
             //Fetch Civi's info about this recurring object
             $recur_contrib_query = CRM_Core_DAO::executeQuery("SELECT id, contact_id, currency, contribution_status_id, is_test, contribution_type_id, payment_instrument_id, campaign_id FROM civicrm_contribution_recur WHERE invoice_id = '{$invoice_id}'");
             if (!empty($recur_contrib_query)) {
                 $recur_contrib_query->fetch();
             } else {
                 CRM_Core_Error::Fatal("ERROR: Stripe triggered a Webhook on an invoice not found in civicrm_contribution_recur: " . $stripe_event_data);
             }
             //Build some params
             $stripe_customer = Stripe_Customer::retrieve($customer_id);
             $recieve_date = date("Y-m-d H:i:s", $charge->created);
             $total_amount = $charge->amount / 100;
             $fee_amount = $charge->fee / 100;
             $net_amount = $total_amount - $fee_amount;
             $transaction_id = $charge->id;
             $new_invoice_id = $stripe_event_data->data->object->id;
             if (empty($recur_contrib_query->campaign_id)) {
                 $recur_contrib_query->campaign_id = 'NULL';
             }
             $first_contrib_check = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_contribution WHERE invoice_id = '{$invoice_id}' AND contribution_status_id = '2'");
             if (!empty($first_contrib_check)) {
                 CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution SET contribution_status_id = '1' WHERE id = '{$first_contrib_check}'");
                 return;
             }
             //Create this instance of the contribution for accounting in CiviCRM
             CRM_Core_DAO::executeQuery("\n        \tINSERT INTO civicrm_contribution (\n        \tcontact_id, contribution_type_id, payment_instrument_id, receive_date, \n        \ttotal_amount, fee_amount, net_amount, trxn_id, invoice_id, currency,\n        \tcontribution_recur_id, is_test, contribution_status_id, campaign_id\n        \t) VALUES (\n        \t'{$recur_contrib_query->contact_id}', '{$recur_contrib_query->contribution_type_id}', '{$recur_contrib_query->payment_instrument_id}', '{$recieve_date}', \n        \t'{$total_amount}', '{$fee_amount}', '{$net_amount}', '{$transaction_id}', '{$new_invoice_id}', '{$recur_contrib_query->currency}', \n        \t'{$recur_contrib_query->id}', '{$recur_contrib_query->is_test}', '1', {$recur_contrib_query->campaign_id}\n        \t)");
             if ($time_compare > $end_time) {
                 $end_date = date("Y-m-d H:i:s", $end_time);
                 //Final payment.  Recurring contribution complete
                 $stripe_customer->cancelSubscription();
                 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_subscriptions WHERE invoice_id = '{$invoice_id}'");
                 CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET end_date = '{$end_date}', contribution_status_id = '1' WHERE invoice_id = '{$invoice_id}'");
                 return;
             }
             //Successful charge & more to come so set recurring contribution status to In Progress
             if ($recur_contrib_query->contribution_status_id != 5) {
                 CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET contribution_status_id = 5 WHERE invoice_id = '{$invoice_id}'");
                 return;
             }
             break;
             //Failed recurring payment
         //Failed recurring payment
         case 'invoice.payment_failed':
             //Get the Stripe charge object
             try {
                 $charge = Stripe_Charge::retrieve($stripe_event_data->data->object->charge);
             } catch (Exception $e) {
                 CRM_Core_Error::Fatal("Failed to retrieve Stripe charge.  Message: " . $e->getMessage());
                 break;
             }
             //Find the recurring contribution in CiviCRM by mapping it from Stripe
             $invoice_id = CRM_Core_DAO::singleValueQuery("SELECT invoice_id FROM civicrm_stripe_subscriptions WHERE customer_id = '{$customer_id}'");
             if (empty($invoice_id)) {
                 CRM_Core_Error::Fatal("Error relating this customer ({$customer_id}) to the one in civicrm_stripe_subscriptions");
             }
             //Fetch Civi's info about this recurring object
             $recur_contrib_query = CRM_Core_DAO::executeQuery("SELECT id, contact_id, currency, contribution_status_id, is_test, contribution_type_id, payment_instrument_id, campaign_id FROM civicrm_contribution_recur WHERE invoice_id = '{$invoice_id}'");
             if (!empty($recur_contrib_query)) {
                 $recur_contrib_query->fetch();
             } else {
                 CRM_Core_Error::Fatal("ERROR: Stripe triggered a Webhook on an invoice not found in civicrm_contribution_recur: " . $stripe_event_data);
             }
             //Build some params
             $recieve_date = date("Y-m-d H:i:s", $charge->created);
             $total_amount = $charge->amount / 100;
             $fee_amount = $charge->fee / 100;
             $net_amount = $total_amount - $fee_amount;
             $transaction_id = $charge->id;
             if (empty($recur_contrib_query->campaign_id)) {
                 $recur_contrib_query->campaign_id = 'NULL';
             }
             //Create this instance of the contribution for accounting in CiviCRM
             CRM_Core_DAO::executeQuery("\n        \tINSERT INTO civicrm_contribution (\n        \tcontact_id, contribution_type_id, payment_instrument_id, receive_date, \n        \ttotal_amount, fee_amount, net_amount, trxn_id, invoice_id, currency,\n        \tcontribution_recur_id, is_test, contribution_status_id, campaign_id\n        \t) VALUES (\n        \t'{$recur_contrib_query->contact_id}', '{$recur_contrib_query->contribution_type_id}', '{$recur_contrib_query->payment_instrument_id}', '{$recieve_date}', \n        \t'{$total_amount}', '{$fee_amount}', '{$net_amount}', '{$transaction_id}', '{$invoice_id}', '{$recur_contrib_query->currency}', \n        \t'{$recur_contrib_query->id}', '{$recur_contrib_query->is_test}', '4', {$recur_contrib_query->campaign_id}\n        \t)");
             //Failed charge.  Set to status to: Failed
             if ($recur_contrib_query->contribution_status_id != 4) {
                 CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET contribution_status_id = 4 WHERE invoice_id = '{$invoice_id}'");
                 return;
             } else {
                 //This has failed more than once.  Now what?
             }
             break;
             //One-time donation and per invoice payment
         //One-time donation and per invoice payment
         case 'charge.succeeded':
             //Not implemented
             break;
     }
     parent::run();
 }
Esempio n. 2
0
 public function testRetrieve()
 {
     authorizeFromEnv();
     $c = Stripe_Charge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => '4242424242424242', 'exp_month' => 5, 'exp_year' => 2015)));
     $d = Stripe_Charge::retrieve($c->id);
     $this->assertEqual($d->id, $c->id);
 }
Esempio n. 3
0
 public function testUpdateMetadataAll()
 {
     authorizeFromEnv();
     $charge = Stripe_Charge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => '4242424242424242', 'exp_month' => 5, 'exp_year' => 2015)));
     $charge->metadata = array('test' => 'foo bar');
     $charge->save();
     $updatedCharge = Stripe_Charge::retrieve($charge->id);
     $this->assertEqual('foo bar', $updatedCharge->metadata['test']);
 }
 public function markAsSafe()
 {
     self::authorizeFromEnv();
     $card = array('number' => '4242424242424242', 'exp_month' => 5, 'exp_year' => 2015);
     $charge = Stripe_Charge::create(array('amount' => 100, 'currency' => 'usd', 'card' => $card));
     $charge->markAsSafe();
     $updatedCharge = Stripe_Charge::retrieve($charge->id);
     $this->assertEqual('safe', $updatedCharge['fraud_details']['user_report']);
 }
Esempio n. 5
0
 public function get_transaction($transaction_id)
 {
     try {
         $ch = Stripe_Charge::retrieve($transaction_id);
         return $ch;
     } catch (Exception $e) {
         $this->error = TRUE;
         $this->message = $e->getMessage();
         $this->code = $e->getCode();
         return FALSE;
     }
 }
Esempio n. 6
0
 public function refund(Varien_Object $payment, $amount)
 {
     $transactionId = $payment->getParentTransactionId();
     try {
         Stripe_Charge::retrieve($transactionId)->refund();
     } catch (Exception $e) {
         $this->debugData($e->getMessage());
         Mage::throwException(Mage::helper('paygate')->__('Payment refunding error.'));
     }
     $payment->setTransactionId($transactionId . '-' . Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND)->setParentTransactionId($transactionId)->setIsTransactionClosed(1)->setShouldCloseParentTransaction(1);
     return $this;
 }
 public function post()
 {
     $this->authenticate();
     $attendance = $this->app->db->queryRow('SELECT * FROM attendance WHERE person_id=%d AND event_id=%d', $this->person['id'], $this->event['id']);
     // Set your secret key: remember to change this to your live secret key in production
     // See your keys here https://dashboard.stripe.com/account
     \Stripe::setApiKey($this->app->config->stripe->secret_key);
     try {
         $ch = \Stripe_Charge::retrieve($attendance['ticket_id']);
         $re = $ch->refunds->create();
         $this->app->db->query('DELETE FROM attendance WHERE person_id=%d AND event_id=%d', $this->person['id'], $this->event['id']);
         $this->resp->setJSON(true);
     } catch (\Stripe_CardError $e) {
         $this->resp->setJSON($e->getMessage());
     }
 }
Esempio n. 8
0
function stripe_refund($params)
{
    require_once 'stripe/Stripe.php';
    $gatewaytestmode = $params["testmode"];
    if ($gatewaytestmode == "on") {
        Stripe::setApiKey($params['private_test_key']);
    } else {
        Stripe::setApiKey($params['private_live_key']);
    }
    # Invoice Variables
    $transid = $params['transid'];
    # Perform Refund
    try {
        $ch = Stripe_Charge::retrieve($transid);
        $ch->refund();
        return array("status" => "success", "transid" => $ch["id"], "rawdata" => $ch);
    } catch (Exception $e) {
        $response['error'] = $e->getMessage();
        return array("status" => "error", "rawdata" => $response['error']);
    }
}
Esempio n. 9
0
 public function post()
 {
     $this->app->db->query('START TRANSACTION');
     // Get the next event
     $event = $this->app->db->queryRow('SELECT * FROM events WHERE end_time > NOW() ORDER BY start_time ASC LIMIT 1');
     $personid = $this->req->getPost('person_id');
     $person = $this->app->db->queryRow('SELECT * FROM people WHERE id=%d', $personid);
     $attendance = $this->app->db->queryRow('SELECT * FROM attendance WHERE person_id=%d AND event_id=%d', $personid, $event['id']);
     if ($this->req->getPost('action') === 'invite') {
         $code = substr(str_shuffle('QWERTYUIOPASDFGHJKLZXCVBNM1234567890'), 0, 20);
         $viewdata = array('summary' => "You're invited to Edge: claim your ticket now", 'person' => $person, 'event' => $event, 'attendance' => $attendance, 'code' => $code);
         $htmloutput = $this->app->view->render('emails/invite.html', $viewdata);
         $textoutput = $this->app->view->render('emails/invite.txt', $viewdata);
         $this->app->db->query("UPDATE attendance SET invite_date_sent=NOW(), invite_code=%s WHERE person_id=%d AND event_id=%d", $code, $personid, $event['id']);
         $this->sendEmail($person['email'], 'Invite to Edge conf', $textoutput, $htmloutput);
         $this->alert('info', 'Sent invite to ' . $person['email']);
     } else {
         if (isset($_POST['action']) and $_POST['action'] == 'remind') {
             $this->app->db->query("UPDATE attendance SET invite_date_reminded=NOW() WHERE person_id=%d AND event_id=%d", $personid, $event['id']);
             $viewdata = array('person' => $person, 'event' => $event, 'code' => $this->app->db->querySingle("SELECT invite_code FROM attendance WHERE person_id=%d AND event_id=%d", $personid, $event['id']));
             $htmloutput = $this->app->view->render('emails/reminder.html', $viewdata);
             $textoutput = $this->app->view->render('emails/reminder.txt', $viewdata);
             $this->sendEmail($person['email'], 'Reminder: Edge conf invite', $textoutput, $htmloutput);
             $this->alert('info', 'Sent reminder to ' . $person['email']);
         } else {
             if (isset($_POST['action']) and $_POST['action'] == 'cancel') {
                 \Stripe::setApiKey($this->app->config->stripe->secret_key);
                 try {
                     $ch = \Stripe_Charge::retrieve($attendance['ticket_id']);
                     $re = $ch->refunds->create();
                     $this->app->db->query('DELETE FROM attendance WHERE person_id=%d AND event_id=%d', $personid, $event['id']);
                 } catch (\Stripe_CardError $e) {
                     $this->resp->setStatus(500);
                     $this->resp->setJSON($e->getMessage());
                 }
             }
         }
     }
     $this->app->db->query("COMMIT");
 }
Esempio n. 10
0
 public function stripe_retrieve_charge($charge_id)
 {
     return Stripe_Charge::retrieve($charge_id);
 }
Esempio n. 11
0
function striper_order_status_completed($order_id = null)
{
    global $woocommerce;
    if (!$order_id) {
        $order_id = $_POST['order_id'];
    }
    $data = get_post_meta($order_id);
    $total = $data['_order_total'][0] * 100;
    $params = array();
    if (isset($_POST['amount']) && ($amount = $_POST['amount'])) {
        $params['amount'] = round($amount);
    }
    $authcap = get_post_meta($order_id, 'auth_capture', true);
    if ($authcap) {
        Stripe::setApiKey(get_post_meta($order_id, 'key', true));
        try {
            $tid = get_post_meta($order_id, 'transaction_id', true);
            $ch = Stripe_Charge::retrieve($tid);
            if ($total < $ch->amount) {
                $params['amount'] = $total;
            }
            $ch->capture($params);
        } catch (Stripe_Error $e) {
            // There was an error
            $body = $e->getJsonBody();
            $err = $body['error'];
            if ($this->logger) {
                $this->logger->add('striper', 'Stripe Error:' . $err['message']);
            }
            wc_add_notice(__('Payment error:', 'striper') . $err['message'], 'error');
            return null;
        }
        return true;
    }
}
 /**
  * Get a Stripe charge object instance.
  *
  * @param string $charge_id Charge ID in Stripe.
  *
  * @return Stripe_Charge|string Charge object; else error message.
  */
 public static function get_charge($charge_id)
 {
     $input_time = time();
     // Initialize.
     $input_vars = get_defined_vars();
     // Arguments.
     require_once dirname(__FILE__) . '/stripe-sdk/lib/Stripe.php';
     Stripe::setApiKey($GLOBALS['WS_PLUGIN__']['s2member']['o']['pro_stripe_api_secret_key']);
     try {
         $charge = Stripe_Charge::retrieve($charge_id);
         self::log_entry(__FUNCTION__, $input_time, $input_vars, time(), $charge);
         return $charge;
         // Stripe charge object.
     } catch (exception $exception) {
         self::log_entry(__FUNCTION__, $input_time, $input_vars, time(), $exception);
         return self::error_message($exception);
     }
 }
Esempio n. 13
0
 /**
  * Process the changes from the Modify Pro Site Status metabox.
  *
  * @param $blog_id
  */
 public static function process_modify($blog_id)
 {
     global $psts, $current_user;
     $success_msg = $error_msg = '';
     if (isset($_POST['stripe_mod_action'])) {
         $customer_id = self::get_customer_data($blog_id)->customer_id;
         $exitsing_invoice_object = Stripe_Invoice::all(array("customer" => $customer_id, "count" => 1));
         $last_payment = $exitsing_invoice_object->data[0]->total / 100;
         $refund_value = $_POST['refund_amount'];
         $refund_amount = $refund_value * 100;
         $refund_amount = (int) $refund_amount;
         $refund = $last_payment;
         switch ($_POST['stripe_mod_action']) {
             case 'cancel':
                 $end_date = date_i18n(get_option('date_format'), $psts->get_expire($blog_id));
                 try {
                     $customer_data = self::get_customer_data($blog_id);
                     $customer_id = $customer_data->customer_id;
                     $sub_id = $customer_data->subscription_id;
                     $cu = Stripe_Customer::retrieve($customer_id);
                     // Don't use ::cancelSubscription because it doesn't know which subscription if we have multiple
                     $cu->subscriptions->retrieve($sub_id)->cancel();
                     //record stat
                     $psts->record_stat($blog_id, 'cancel');
                     $psts->log_action($blog_id, sprintf(__('Subscription successfully cancelled by %1$s. They should continue to have access until %2$s', 'psts'), $current_user->display_name, $end_date));
                     $success_msg = sprintf(__('Subscription successfully cancelled. They should continue to have access until %s.', 'psts'), $end_date);
                     update_blog_option($blog_id, 'psts_stripe_canceled', 1);
                 } catch (Exception $e) {
                     $error_msg = $e->getMessage();
                     $psts->log_action($blog_id, sprintf(__('Attempt to Cancel Subscription by %1$s failed with an error: %2$s', 'psts'), $current_user->display_name, $error_msg));
                 }
                 break;
             case 'cancel_refund':
                 $end_date = date_i18n(get_option('date_format'), $psts->get_expire($blog_id));
                 $cancellation_success = false;
                 try {
                     $customer_data = self::get_customer_data($blog_id);
                     $customer_id = $customer_data->customer_id;
                     $sub_id = $customer_data->subscription_id;
                     $cu = Stripe_Customer::retrieve($customer_id);
                     // Don't use ::cancelSubscription because it doesn't know which subscription if we have multiple
                     $cu->subscriptions->retrieve($sub_id)->cancel();
                     $cancellation_success = true;
                     //record stat
                 } catch (Exception $e) {
                     $error_msg = $e->getMessage();
                 }
                 if ($cancellation_success == false) {
                     $psts->log_action($blog_id, sprintf(__('Attempt to Cancel Subscription and Refund Prorated (%1$s) Last Payment by %2$s failed with an error: %3$s', 'psts'), $psts->format_currency(false, $refund), $current_user->display_name, $error_msg));
                     $error_msg = sprintf(__('Whoops, Stripe returned an error when attempting to cancel the subscription. Nothing was completed: %s', 'psts'), $error_msg);
                     break;
                 }
                 $refund_success = false;
                 if ($cancellation_success == true) {
                     try {
                         $charge_object = Stripe_Charge::all(array("count" => 1, "customer" => $customer_id));
                         $charge_id = $charge_object->data[0]->id;
                         $ch = Stripe_Charge::retrieve($charge_id);
                         $ch->refund();
                         $refund_success = true;
                     } catch (Exception $e) {
                         $error_msg = $e->getMessage();
                     }
                 }
                 if ($refund_success == true) {
                     $psts->log_action($blog_id, sprintf(__('Subscription cancelled and a prorated (%1$s) refund of last payment completed by %2$s', 'psts'), $psts->format_currency(false, $refund), $current_user->display_name));
                     $success_msg = sprintf(__('Subscription cancelled and a prorated (%s) refund of last payment were successfully completed.', 'psts'), $psts->format_currency(false, $refund));
                     update_blog_option($blog_id, 'psts_stripe_canceled', 1);
                 } else {
                     $psts->log_action($blog_id, sprintf(__('Subscription cancelled, but prorated (%1$s) refund of last payment by %2$s returned an error: %3$s', 'psts'), $psts->format_currency(false, $refund), $current_user->display_name, $error_msg));
                     $error_msg = sprintf(__('Subscription cancelled, but prorated (%1$s) refund of last payment returned an error: %2$s', 'psts'), $psts->format_currency(false, $refund), $error_msg);
                     update_blog_option($blog_id, 'psts_stripe_canceled', 1);
                 }
                 break;
             case 'refund':
                 try {
                     $charge_object = Stripe_Charge::all(array("count" => 1, "customer" => $customer_id));
                     $charge_id = $charge_object->data[0]->id;
                     $ch = Stripe_Charge::retrieve($charge_id);
                     $ch->refund();
                     $psts->log_action($blog_id, sprintf(__('A full (%1$s) refund of last payment completed by %2$s The subscription was not cancelled.', 'psts'), $psts->format_currency(false, $refund), $current_user->display_name));
                     $success_msg = sprintf(__('A full (%s) refund of last payment was successfully completed. The subscription was not cancelled.', 'psts'), $psts->format_currency(false, $refund));
                     $psts->record_refund_transaction($blog_id, $charge_id, $refund);
                 } catch (Exception $e) {
                     $error_msg = $e->getMessage();
                     $psts->log_action($blog_id, sprintf(__('Attempt to issue a full (%1$s) refund of last payment by %2$s returned an error: %3$s', 'psts'), $psts->format_currency(false, $refund), $current_user->display_name, $error_msg));
                     $error_msg = sprintf(__('Attempt to issue a full (%1$s) refund of last payment returned an error: %2$s', 'psts'), $psts->format_currency(false, $refund), $error_msg);
                 }
                 break;
             case 'partial_refund':
                 try {
                     $charge_object = Stripe_Charge::all(array("count" => 1, "customer" => $customer_id));
                     $charge_id = $charge_object->data[0]->id;
                     $ch = Stripe_Charge::retrieve($charge_id);
                     $ch->refund(array("amount" => $refund_amount));
                     $psts->log_action($blog_id, sprintf(__('A partial (%1$s) refund of last payment completed by %2$s The subscription was not cancelled.', 'psts'), $psts->format_currency(false, $refund_value), $current_user->display_name));
                     $success_msg = sprintf(__('A partial (%s) refund of last payment was successfully completed. The subscription was not cancelled.', 'psts'), $psts->format_currency(false, $refund_value));
                     $psts->record_refund_transaction($blog_id, $charge_id, $refund);
                 } catch (Exception $e) {
                     $error_msg = $e->getMessage();
                     $psts->log_action($blog_id, sprintf(__('Attempt to issue a partial (%1$s) refund of last payment by %2$s returned an error: %3$s', 'psts'), $psts->format_currency(false, $refund_value), $current_user->display_name, $error_msg));
                     $error_msg = sprintf(__('Attempt to issue a partial (%1$s) refund of last payment returned an error: %2$s', 'psts'), $psts->format_currency(false, $refund_value), $error_msg);
                 }
                 break;
         }
     }
     //display resulting message
     if ($success_msg) {
         echo '<div class="updated fade"><p>' . $success_msg . '</p></div>';
     } else {
         if ($error_msg) {
             echo '<div class="error fade"><p>' . $error_msg . '</p></div>';
         }
     }
 }
 public function process_refund($order_id, $amount = NULL, $reason = '')
 {
     if ($amount > 0) {
         $CHARGE_ID = get_post_meta($order_id, '_transaction_id', true);
         $charge = Stripe_Charge::retrieve($CHARGE_ID);
         $refund = $charge->refunds->create(array('amount' => $amount * 100, 'metadata' => array('Order #' => $order_id, 'Refund reason' => $reason)));
         if ($refund) {
             $repoch = $refund->created;
             $rdt = new DateTime("@{$repoch}");
             $rtimestamp = $rdt->format('Y-m-d H:i:s e');
             $refundid = $refund->id;
             $wc_order = new WC_Order($order_id);
             $wc_order->add_order_note(__('Stripe Refund completed at. ' . $rtimestamp . ' with Refund ID = ' . $refundid, 'woocommerce'));
             return true;
         } else {
             return false;
         }
     } else {
         return false;
     }
 }
 public function testChargeWithAdditionalInvalidChargeDataFields()
 {
     $data = array('amount' => 7.45, 'stripeToken' => 'tok_65Vl7Y7eZvKYlo2CurIZVU1z', 'statement_descriptor' => 'some chargeParams', 'invalid' => 'foobar');
     $result = $this->StripeComponent->charge($data);
     $this->assertRegExp('/^ch\\_[a-zA-Z0-9]+/', $result['stripe_id']);
     $charge = Stripe_Charge::retrieve('chargeParams');
     $this->assertEquals($result['stripe_id'], $charge->id);
     $this->assertEquals($data['statement_descriptor'], $charge->statement_descriptor);
     $this->assertObjectNotHasAttribute('invalid', $charge);
 }
 /**
  * Refund a payment or invoice
  * @param  object &$order         Related PMPro order object.
  * @param  string $transaction_id Payment or invoice id to void.
  * @return bool                   True or false if the refund worked.
  */
 function refund(&$order, $transaction_id = NULL)
 {
     //default to using the payment id from the order
     if (empty($transaction_id) && !empty($order->payment_transaction_id)) {
         $transaction_id = $order->payment_transaction_id;
     }
     //need a transaction id
     if (empty($transaction_id)) {
         return false;
     }
     //if an invoice ID is passed, get the charge/payment id
     if (strpos($transaction_id, "in_") !== false) {
         $invoice = Stripe_Invoice::retrieve($transaction_id);
         if (!empty($invoice) && !empty($invoice->payment)) {
             $transaction_id = $invoice->payment;
         }
     }
     //get the charge
     $charge = Stripe_Charge::retrieve($transaction_id);
     //can't find the charge?
     if (empty($charge)) {
         $order->status = "error";
         $order->errorcode = "";
         $order->error = "";
         $order->shorterror = "";
         return false;
     }
     //attempt refund
     try {
         $refund = $charge->refund();
     } catch (Exception $e) {
         //$order->status = "error";
         $order->errorcode = true;
         $order->error = __("Error: ", "pmpro") . $e->getMessage();
         $order->shorterror = $order->error;
         return false;
     }
     if ($refund->status == "succeeded") {
         $order->status = "refunded";
         $order->saveOrder();
         return true;
     } else {
         $order->status = "error";
         $order->errorcode = true;
         $order->error = sprintf(__("Error: Unkown error while refunding charge #%s", "pmpro"), $transaction_id);
         $order->shorterror = $order->error;
         return false;
     }
 }
 public function updateCharge(PhortuneCharge $charge)
 {
     $this->loadStripeAPILibraries();
     $charge_id = $charge->getMetadataValue('stripe.chargeID');
     if (!$charge_id) {
         throw new Exception(pht('Unable to update charge; no Stripe chargeID!'));
     }
     $secret_key = $this->getSecretKey();
     $stripe_charge = Stripe_Charge::retrieve($charge_id, $secret_key);
     // TODO: Deal with disputes / chargebacks / surprising refunds.
 }
Esempio n. 18
0
         $authorized_this_time++;
     } else {
         ##Save the Authorize Token Here   [authfailed]
         $query = "INSERT INTO fund_disbursed (fund_disbursed_id,account_id,project_id, element_id,fund_amount, disburse_status, application_fee, disburse_token, fund_disbursed_datetime )\n                VALUES ('', '{$aID}', '{$aID}', '{$eID}', '{$fund_amount}','authfailed', '{$application_fee}' , '" . $charge["id"] . "', NOW())";
         mysql_query($query) or die("mysql error @ insert authfailed");
     }
 } else {
     if ($action == 'capture') {
         list($charge_id, $authstatus) = getAuthorizeTokenID($funding_details_id);
         error_log("<<<<<charge_id [{$charge_id}]>>>>><<<<<authstatus [{$authstatus}]>>>>>", 0);
         if ($authstatus == 'authfailed' or $authstatus == 'declined') {
             continue;
         }
         if ($charge_id != '') {
             Stripe::setApiKey($stripeUserAccessToken);
             $ch = Stripe_Charge::retrieve($charge_id);
             $charge = $ch->capture();
             if ($DEBUG) {
                 print_r($charge);
                 print_r($ch);
                 print $ch['captured'];
             }
             if ($charge['captured'] == 1 or $charge['captured'] == 'true') {
                 ## Update Status in database;
                 $query = "UPDATE fund_disbursed  SET disburse_status  = 'captured' WHERE funding_details_id = '{$funding_details_id}' AND disburse_token = '{$charge_id}' ";
                 mysql_query($query) or die("mysql error @ capture update");
                 $paid_this_time++;
                 $query = "UPDATE element_detail  SET element_detail_disbursed = '1' WHERE element_id  = '{$eID}' AND account_id = '{$aID}' ";
                 mysql_query($query) or die("mysql error @ capture update");
                 sendSuccessMailToDonor($funding_details_id, $fund_amount / 100, $funder_id);
                 #                         sendSuccessMailToEntrepreneur($funding_details_id, $fund_amount/100, $funder_id);
function stripe_capture_meta_box_action($order_id, $items)
{
    if (isset($items['_stripe_capture_charge']) && 1 == $items['_stripe_capture_charge']) {
        global $post;
        $chargeid = get_post_meta($post->ID, '_transaction_id', true);
        if (class_exists('WC_Stripe_Gateway')) {
            $stripepg = new WC_Stripe_Gateway();
            if ('yes' == $stripepg->stripe_sandbox) {
                Stripe::setApiKey($stripepg->stripe_testsecretkey);
            } else {
                Stripe::setApiKey($stripepg->stripe_livesecretkey);
            }
        }
        $capturecharge = Stripe_Charge::retrieve($chargeid);
        $captureresponse = $capturecharge->capture();
        if (true == $captureresponse->captured && true == $captureresponse->paid) {
            $epoch = $captureresponse->created;
            $dt = new DateTime("@{$epoch}");
            $timestamp = $dt->format('Y-m-d H:i:s e');
            $wc_order = new WC_Order($order_id);
            update_post_meta($order_id, '_stripe_charge_status', 'charge_auth_captured_later');
            $wc_order->add_order_note(__('Stripe charge captured at-' . $timestamp . ',Charge ID=' . $captureresponse->id . ',Card=' . $captureresponse->source->brand . ' : ' . $captureresponse->source->last4 . ' : ' . $captureresponse->source->exp_month . '/' . $captureresponse->source->exp_year, 'woocommerce'));
            unset($wc_order);
        }
    }
}
         CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_subscriptions WHERE invoice_id = '{$invoice_id}'");
         CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET end_date = '{$end_date}', contribution_status_id = '1' WHERE invoice_id = '{$invoice_id}'");
         return;
     }
     //Successful charge & more to come so set recurring contribution status to In Progress
     if ($recur_contrib_query->contribution_status_id != 5) {
         CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET contribution_status_id = 5 WHERE invoice_id = '{$invoice_id}'");
         return;
     }
     break;
     //Failed recurring payment
 //Failed recurring payment
 case 'invoice.payment_failed':
     //Get the Stripe charge object
     try {
         $charge = Stripe_Charge::retrieve($stripe_event_data->data->object->charge);
     } catch (Exception $e) {
         CRM_Core_Error::Fatal("Failed to retrieve Stripe charge.  Message: " . $e->getMessage());
         break;
     }
     //Find the recurring contribution in CiviCRM by mapping it from Stripe
     $invoice_id = CRM_Core_DAO::singleValueQuery("SELECT invoice_id FROM civicrm_stripe_subscriptions WHERE customer_id = '{$customer_id}'");
     if (empty($invoice_id)) {
         CRM_Core_Error::Fatal("Error relating this customer ({$customer_id}) to the one in civicrm_stripe_subscriptions");
     }
     //Fetch Civi's info about this recurring object
     $recur_contrib_query = CRM_Core_DAO::executeQuery("SELECT id, contact_id, currency, contribution_status_id, is_test, contribution_type_id, payment_instrument_id, campaign_id FROM civicrm_contribution_recur WHERE invoice_id = '{$invoice_id}'");
     if (!empty($recur_contrib_query)) {
         $recur_contrib_query->fetch();
     } else {
         CRM_Core_Error::Fatal("ERROR: Stripe triggered a Webhook on an invoice not found in civicrm_contribution_recur: " . $stripe_event_data);
Esempio n. 21
0
 /**
  * Process a refund against an existing charge
  *
  * @param Transaction $originalTransaction
  * @param $amount
  * @return Transaction
  */
 public function refund($originalTransaction, $amount, $target)
 {
     // Fetch the original transaction that we are refunding against
     try {
         $charge = Stripe_Charge::retrieve($originalTransaction->provider_transaction_id);
     } catch (Stripe_InvalidRequestError $e) {
         return null;
     }
     // Attempt the refund
     $refund = $this->ledger->newStripeRefund($charge->refunds->create(["amount" => $amount]), $originalTransaction->provider_customer_id);
     // Associate the target object with this originalTransaction.
     $refund->target = $target;
     // Update the ledger
     $refund->save();
     return $refund;
 }
 public function testCreateCustomerAndCharge()
 {
     $this->StripeComponent->startup($this->Controller);
     Stripe::setApiKey(Configure::read('Stripe.TestSecret'));
     $token = Stripe_Token::create(array('card' => array('number' => '4242424242424242', 'exp_month' => 12, 'exp_year' => 2020, 'cvc' => 777, 'name' => 'Casi Robot', 'address_zip' => '91361')));
     $data = array('stripeToken' => $token->id, 'description' => 'Create Customer & Charge', 'email' => '*****@*****.**');
     $result = $this->StripeComponent->customerCreate($data);
     $this->assertRegExp('/^cus\\_[a-zA-Z0-9]+/', $result['stripe_id']);
     $customer = Stripe_Customer::retrieve($result['stripe_id']);
     $this->assertEquals($result['stripe_id'], $customer->id);
     $chargeData = array('amount' => '14.69', 'stripeCustomer' => $customer->id);
     $charge = $this->StripeComponent->charge($chargeData);
     $this->assertRegExp('/^ch\\_[a-zA-Z0-9]+/', $charge['stripe_id']);
     $charge = Stripe_Charge::retrieve($charge['stripe_id']);
     $chargeData['amount'] = $chargeData['amount'] * 100;
     $this->assertEquals($chargeData['amount'], $charge->amount);
     $customer->delete();
 }
Esempio n. 23
0
 /**
  * Get an existing customer charge
  * @param string $charge_id
  * @return Stripe_Charge|false
  */
 public function getCharge($charge_id = '')
 {
     try {
         return Stripe_Charge::retrieve($charge_id, $this->access_token);
     } catch (Exception $ex) {
         $this->log($ex);
         return false;
     }
 }
Esempio n. 24
0
/**
 * Process refund in Stripe
 *
 * @access      public
 * @since       1.8
 * @return      void
 */
function edd_stripe_process_refund($payment_id, $new_status, $old_status)
{
    global $edd_options;
    if (empty($_POST['edd_refund_in_stripe'])) {
        return;
    }
    if ('publish' != $old_status && 'revoked' != $old_status) {
        return;
    }
    if ('refunded' != $new_status) {
        return;
    }
    $charge_id = false;
    $notes = edd_get_payment_notes($payment_id);
    foreach ($notes as $note) {
        if (preg_match('/^Stripe Charge ID: ([^\\s]+)/', $note->comment_content, $match)) {
            $charge_id = $match[1];
            break;
        }
    }
    // Bail if no charge ID was found
    if (empty($charge_id)) {
        return;
    }
    if (!class_exists('Stripe')) {
        require_once EDDS_PLUGIN_DIR . '/Stripe/Stripe.php';
    }
    $secret_key = edd_is_test_mode() ? trim($edd_options['test_secret_key']) : trim($edd_options['live_secret_key']);
    Stripe::setApiKey($secret_key);
    $ch = Stripe_Charge::retrieve($charge_id);
    try {
        $ch->refund();
        edd_insert_payment_note($payment_id, __('Charge refunded in Stripe', 'edds'));
    } catch (Exception $e) {
        // some sort of other error
        $body = $e->getJsonBody();
        $err = $body['error'];
        if (isset($err['message'])) {
            $error = $err['message'];
        } else {
            $error = __('Something went wrong while refunding the Charge in Stripe.', 'edds');
        }
        wp_die($error);
    }
}
Esempio n. 25
0
    /**
     * Process a partial or full refund
     *
     * @param string $id_transaction_stripe Stripe Transaction ID (token)
     * @param float $amount Amount to refund
     * @param array $original_transaction Original transaction details
     */
    public function processRefund($id_transaction_stripe, $amount, $original_transaction)
    {
        /* If 1.4 and no backward, then leave */
        if (!$this->backward) {
            return;
        }
        include dirname(__FILE__) . '/lib/Stripe.php';
        Stripe::setApiKey(Configuration::get('STRIPE_MODE') ? Configuration::get('STRIPE_PRIVATE_KEY_LIVE') : Configuration::get('STRIPE_PRIVATE_KEY_TEST'));
        /* Try to process the refund and catch any error message */
        try {
            $charge = Stripe_Charge::retrieve($id_transaction_stripe);
            $result_json = Tools::jsonDecode($charge->refund(array('amount' => $amount * 100)));
        } catch (Exception $e) {
            $this->_errors['stripe_refund_error'] = $e->getMessage();
            if (class_exists('Logger')) {
                Logger::addLog($this->l('Stripe - Refund transaction failed') . ' ' . $e->getMessage(), 2, null, 'Cart', (int) $this->context->cart->id, true);
            }
        }
        /* Store the refund details */
        Db::getInstance()->Execute('
		INSERT INTO ' . _DB_PREFIX_ . 'stripe_transaction (type, id_stripe_customer, id_cart, id_order,
		id_transaction, amount, status, currency, cc_type, cc_exp, cc_last_digits, fee, mode, date_add)
		VALUES (\'refund\', ' . (int) $original_transaction['id_stripe_customer'] . ', ' . (int) $original_transaction['id_cart'] . ', ' . (int) $original_transaction['id_order'] . ', \'' . pSQL($id_transaction_stripe) . '\',
		\'' . (double) $amount . '\', \'' . (!isset($this->_errors['stripe_refund_error']) ? 'paid' : 'unpaid') . '\', \'' . pSQL($result_json->currency) . '\',
		\'\', \'\', 0, 0, \'' . (Configuration::get('STRIPE_MODE') ? 'live' : 'test') . '\', NOW())');
    }
Esempio n. 26
0
 public function capture($auth, $feed, $submission_data, $form, $entry)
 {
     $charge = Stripe_Charge::retrieve($auth['charge_id']);
     try {
         $charge->description = $this->get_payment_description($entry, $submission_data);
         $charge->save();
         $charge = $charge->capture();
         $payment = array('is_success' => true, 'transaction_id' => $charge['id'], 'amount' => $charge['amount'] / 100, 'payment_method' => rgpost('stripe_credit_card_type'));
     } catch (Stripe_Error $e) {
         $payment = array('is_success' => false, 'error_message' => $e->getMessage());
     }
     return $payment;
 }
Esempio n. 27
0
/**
 * Process stripe payment.
 */
function fwd_stripe_process($data, $settings)
{
    // Prepare stripe payment first.
    $data = fwd_stripe_prepare($data, $settings);
    // Prepare returned error?
    if (isset($data['_error'])) {
        return $data;
    }
    // Default action is charge.
    $data['action'] = $data['action'] ?: 'charge';
    // Get customer token from order id.
    $order = get("/orders/{$data['order_id']}");
    $customer = $order['billing']['stripe'];
    $data['card'] = $order['billing']['card'];
    if ($customer['object'] != 'customer') {
        throw new Exception('Stripe customer ID missing');
    }
    // Amount default? If it's the first payment and order has balance.
    if ($data['amount'] == null && !$order['payments'] && $order['payment_balance']) {
        $data['amount'] = $order['payment_balance'];
    }
    // Amount is absolute.
    $data['amount'] = abs($data['amount']);
    // Perform action.
    switch ($data['action']) {
        case 'charge':
            $charge = Stripe_Charge::create(array('amount' => round($data['amount'] * 100), 'currency' => $order['billing']['currency'] ?: 'usd', 'customer' => $customer['id'], 'description' => 'Order #' . $data['order_id'] . ': ' . $data['reason']));
            if ($charge['paid']) {
                $data['amount_refundable'] = $data['amount'];
                $data['charge_id'] = $charge['id'];
                $data['status'] = 'success';
            }
            break;
        case 'refund':
            if ($data['action'] == 'refund' && !$data['charge_id']) {
                throw new Exception('Stripe refund requires charge_id');
            }
            $charge = Stripe_Charge::retrieve($data['charge_id']);
            $charge->refund(array('amount' => round($data['amount'] * 100)));
            // Record as negative number.
            $data['amount'] = -$data['amount'];
            // Refund succeeded.
            $data['status'] = 'success';
            // Update status of last charge payment.
            $payment = get("/payments/:one", array('order_id' => $data['order_id'], 'charge_id' => $data['charge_id'], 'action' => 'charge'));
            if ($payment) {
                put($payment, array('amount_refundable' => $payment['amount'] - $payment['amount_refunded'] + $data['amount'], 'amount_refunded' => $payment['amount_refunded'] - $data['amount'], 'status' => 'refunded'));
            }
            break;
        default:
            throw new Exception("Stripe does not understand this action: {$data['action']}");
    }
    return $data;
}
Esempio n. 28
0
function sc_show_payment_details($content)
{
    global $sc_options;
    // TODO $html out once finalized.
    $html = '';
    $test_mode = isset($_GET['test_mode']) ? 'true' : 'false';
    sc_set_stripe_key($test_mode);
    // Successful charge output.
    if (isset($_GET['charge']) && !isset($_GET['charge_failed'])) {
        if (empty($sc_options['disable_success_message'])) {
            $charge_id = esc_html($_GET['charge']);
            // https://stripe.com/docs/api/php#charges
            $charge_response = Stripe_Charge::retrieve($charge_id);
            $html = '<div class="sc-payment-details-wrap">';
            $html .= '<p>' . __('Congratulations. Your payment went through!', 'sc') . '</p>' . "\n";
            if (!empty($charge_response->description)) {
                $html .= '<p>' . __("Here's what you bought:", 'sc') . '</p>';
                $html .= $charge_response->description . '<br>' . "\n";
            }
            if (isset($_GET['store_name']) && !empty($_GET['store_name'])) {
                $html .= 'From: ' . esc_html($_GET['store_name']) . '<br/>' . "\n";
            }
            $html .= '<br><strong>' . __('Total Paid: ', 'sc') . sc_stripe_to_formatted_amount($charge_response->amount, $charge_response->currency) . ' ' . strtoupper($charge_response->currency) . '</strong>' . "\n";
            $html .= '<p>' . sprintf(__('Your transaction ID is: %s', 'sc'), $charge_id) . '</p>';
            $html .= '</div>';
            return apply_filters('sc_payment_details', $html, $charge_response) . $content;
        } else {
            return $content;
        }
    } elseif (isset($_GET['charge_failed'])) {
        // TODO Failed charge output.
        $html = '<div class="sc-payment-details-wrap sc-payment-details-error">';
        $html .= __('Sorry, but your card was declined and your payment was not processed.', 'sc');
        $html .= '<br><br>' . sprintf(__('Transaction ID: %s', 'sc'), esc_html($_GET['charge']));
        $html .= '</div>';
        return apply_filters('sc_payment_details_error', $html) . $content;
    }
    return $content;
}
Esempio n. 29
0
 public function Refund($client_id, $gateway, $charge, $authorization)
 {
     $CI =& get_instance();
     $key = $gateway[$gateway['mode'] . '_api_key'];
     Stripe::setApiKey($key);
     try {
         $charge = Stripe_Charge::retrieve($authorization->tran_id);
         $charge->Refund();
         return TRUE;
     } catch (Exception $e) {
         return FALSE;
     }
 }
Esempio n. 30
0
 /**
  * Refund the transaction
  */
 static function refund($id, $force_refund = FALSE)
 {
     $transaction = Transaction::find($id);
     // Get Plan data
     $plan = Plan::where('id', '=', $transaction->plan_id)->first();
     // Get purchase data
     $purchase = Purchase::where('id', '=', $transaction->purchase_id)->first();
     if ($transaction->purchase->pay_method == 1) {
         // Add Stripe library
         require_once app_path() . "/libraries/stripe-php-1.9.0/lib/Stripe.php";
         // Add Stripe library
         Stripe::setApiKey(Config::get('project.stripe_secret_key'));
         try {
             $ch = Stripe_Charge::retrieve($transaction->pay_id);
             $ch->refund();
         } catch (Exception $e) {
             $error = TRUE;
         }
         // If Split pay then cancel subscription as well
         if ($plan->has_split_pay) {
             $at_period_end = FALSE;
             $customer = $purchase->stripe_token;
             $subscription_id = NULL;
             try {
                 $cu = Stripe_Customer::retrieve($customer);
                 $subscriptions = $cu->subscriptions->all(array('count' => 100));
                 foreach ($subscriptions->data as $subscription) {
                     if ($subscription->plan->id == $plan_id) {
                         if ($subscription->status == 'active') {
                             $subscription_id = $subscription->id;
                             break;
                         }
                     }
                 }
                 $cu->subscriptions->retrieve($subscription_id)->cancel(array('at_period_end' => $at_period_end));
             } catch (Exception $e) {
                 $error = TRUE;
             }
         }
     } elseif ($transaction->purchase->pay_method == 2) {
         $config = array('mode' => Config::get('project.paypal_mode'), 'acct1.UserName' => Config::get('project.paypal_api_username'), 'acct1.Password' => Config::get('project.paypal_api_password'), 'acct1.Signature' => Config::get('project.paypal_api_signature'));
         /*
         * The RefundTransaction API operation issues a refund to the PayPal account holder associated with a transaction. 
         This sample code uses Merchant PHP SDK to make API call
         */
         $refundReqest = new PayPal\PayPalAPI\RefundTransactionRequestType();
         /*
         *          Type of refund you are making. It is one of the following values:
                        
                         * `Full` - Full refund (default).
                         * `Partial` - Partial refund.
                         * `ExternalDispute` - External dispute. (Value available since
                         version
                         82.0)
                         * `Other` - Other type of refund. (Value available since version
                         82.0)
         */
         $refundReqest->RefundType = 'Full';
         /*
         *  Either the `transaction ID` or the `payer ID` must be specified.
                         PayerID is unique encrypted merchant identification number
                         For setting `payerId`,
                         `refundTransactionRequest.setPayerID("A9BVYX8XCR9ZQ");`
         
                         Unique identifier of the transaction to be refunded.
         */
         $refundReqest->TransactionID = $transaction->pay_id;
         /*
                      *  (Optional)Type of PayPal funding source (balance or eCheck) that can be used for auto refund. It is one of the following values:
            any – The merchant does not have a preference. Use any available funding source.
            default – Use the merchant's preferred funding source, as configured in the merchant's profile.
            instant – Use the merchant's balance as the funding source.
            eCheck – The merchant prefers using the eCheck funding source. If the merchant's PayPal balance can cover the refund amount, use the PayPal balance.
         */
         //$refundReqest->RefundSource = $_REQUEST['refundSource'];
         $refundReqest->Memo = "Refunded from Digital Kickstart App";
         /*
         * 
           (Optional) Maximum time until you must retry the refund. 
         */
         //$refundReqest->RetryUntil = $_REQUEST['retryUntil'];
         $refundReq = new PayPal\PayPalAPI\RefundTransactionReq();
         $refundReq->RefundTransactionRequest = $refundReqest;
         /*
          *          ## Creating service wrapper object
         Creating service wrapper object to make API call and loading
         Configuration::getAcctAndConfig() returns array that contains credential and config parameters
         */
         $paypalService = new PayPal\Service\PayPalAPIInterfaceServiceService($config);
         try {
             /* wrap API method calls on the service object with a try catch */
             $refundResponse = $paypalService->RefundTransaction($refundReq);
         } catch (Exception $ex) {
             $error = TRUE;
         }
         // If Split pay then cancel subscription as well
         if ($plan->has_split_pay) {
             $paypal_sub_id = $purchase->paypal_sub_id;
             /*
              * The ManageRecurringPaymentsProfileStatus API operation cancels, suspends, or reactivates a recurring payments profile. 
              */
             $manageRPPStatusReqestDetails = new ManageRecurringPaymentsProfileStatusRequestDetailsType();
             /*
                              *  (Required) The action to be performed to the recurring payments profile. Must be one of the following:
                Cancel – Only profiles in Active or Suspended state can be canceled.
                Suspend – Only profiles in Active state can be suspended.
                Reactivate – Only profiles in a suspended state can be reactivated.
             */
             $manageRPPStatusReqestDetails->Action = 'Cancel';
             /*
              * (Required) Recurring payments profile ID returned in the CreateRecurringPaymentsProfile response.
              */
             $manageRPPStatusReqestDetails->ProfileID = $paypal_sub_id;
             $manageRPPStatusReqest = new ManageRecurringPaymentsProfileStatusRequestType();
             $manageRPPStatusReqest->ManageRecurringPaymentsProfileStatusRequestDetails = $manageRPPStatusReqestDetails;
             $manageRPPStatusReq = new ManageRecurringPaymentsProfileStatusReq();
             $manageRPPStatusReq->ManageRecurringPaymentsProfileStatusRequest = $manageRPPStatusReqest;
             /*
              *   ## Creating service wrapper object
             Creating service wrapper object to make API call and loading
             Configuration::getAcctAndConfig() returns array that contains credential and config parameters
             */
             $paypalService = new PayPalAPIInterfaceServiceService($config);
             try {
                 /* wrap API method calls on the service object with a try catch */
                 $manageRPPStatusResponse = $paypalService->ManageRecurringPaymentsProfileStatus($manageRPPStatusReq);
             } catch (Exception $ex) {
                 $error = TRUE;
             }
             if (isset($manageRPPStatusResponse) and $manageRPPStatusResponse->Ack == 'Success') {
                 // Do nothing
             } else {
                 $error = TRUE;
             }
         }
     }
     if (empty($error) or $force_refund) {
         self::completeRefund($transaction);
         return TRUE;
     }
 }