function handle_multisafepay_ipn() { ob_end_clean(); ini_set('display_errors', false); include 'MultiSafepay.combined.php'; $msp = new MultiSafepay(); // transaction id (same as the transaction->id given in the transaction request) $transactionid = isset($_GET['transactionid']) ? $_GET['transactionid'] : false; if (!$transactionid) { send_error('No MultiSafepay transaction ID'); } $multisafepay_bits = explode("|", $transactionid); $user_id = $multisafepay_bits[0]; $payment_id = (int) $multisafepay_bits[1]; $invoice_id = (int) $multisafepay_bits[2]; //send_error('bad?'); //send_error($payment_id.' multisafepay IPN check started',var_export($_REQUEST,true)); if ($payment_id && $invoice_id) { $hash = $this->multisafepay_custom($user_id, $payment_id, $invoice_id); if ($hash != $transactionid) { send_error("Multisafepay IPN Error (incorrect hash)"); exit; } $user_id = (int) $user_id; // sometimes userid is '' $paymetn_history = get_single('invoice_payment', 'invoice_payment_id', $payment_id); if (!$paymetn_history) { send_error("Unknown Multisafe Payment - maybe a history was deleted?"); exit; } // (notify.php?type=initial is used as notification_url and should output a link) $initial = isset($_GET['type']) && $_GET['type'] == "initial"; /* * Merchant Settings */ // $msp->test = MSP_TEST_API; // $msp->merchant['account_id'] = MSP_ACCOUNT_ID; // $msp->merchant['site_id'] = MSP_SITE_ID; // $msp->merchant['site_code'] = MSP_SITE_CODE; $msp->test = self::is_sandbox(); $msp->merchant['account_id'] = module_config::c('payment_method_multisafepay_account', ''); $msp->merchant['site_id'] = module_config::c('payment_method_multisafepay_site_id', ''); $msp->merchant['site_code'] = module_config::c('payment_method_multisafepay_side_code', ''); /* * Transaction Details */ $msp->transaction['id'] = $transactionid; // returns the status $status = $msp->getStatus(); if ($msp->error && !$initial) { // only show error if we dont need to display the link echo "Error " . $msp->error_code . ": " . $msp->error; exit; } //send_error($payment_id.' MultiSafepay Status of '.$status,var_export($_REQUEST,true)); $payment_history_data = isset($paymetn_history['data']) && strlen($paymetn_history['data']) ? unserialize($paymetn_history['data']) : array(); if (!is_array($payment_history_data)) { $payment_history_data = array(); } if (!isset($payment_history_data['log'])) { $payment_history_data['log'] = array(); } $payment_history_data['log'][] = 'Payment ' . $status . ' at ' . print_date(time(), true); update_insert("invoice_payment_id", $payment_id, "invoice_payment", array('data' => serialize($payment_history_data))); switch ($status) { case "initialized": // waiting break; case "completed": // payment complete update_insert("invoice_payment_id", $payment_id, "invoice_payment", array('date_paid' => date('Y-m-d'), 'method' => 'MultiSafepay')); module_invoice::save_invoice($invoice_id, array()); break; case "uncleared": // waiting (credit cards or direct debit) break; case "void": // canceled break; case "declined": // declined break; case "refunded": // refunded send_error("Multisafepay Error! The payment {$payment_id} has been refunded or reversed! BAD BAD! You have to follup up customer for money manually now."); break; case "expired": // expired break; default: } if ($initial) { // displayed at the last page of the transaction proces (if no redirect_url is set) echo '<a href="' . module_invoice::link_public($invoice_id) . '">Return to Invoice</a>'; } else { // link to notify.php for MultiSafepay back-end (for delayed payment notifications) // backend expects an "ok" if no error occurred echo "ok"; } } else { send_error('No bits in transaction id'); } exit; $multisafepay_bits = explode("|", $_REQUEST['custom']); $user_id = (int) $multisafepay_bits[0]; $payment_id = (int) $multisafepay_bits[1]; $invoice_id = (int) $multisafepay_bits[2]; //send_error('bad?'); if ($user_id && $payment_id && $invoice_id) { $hash = $this->multisafepay_custom($user_id, $payment_id, $invoice_id); if ($hash != $_REQUEST['custom']) { send_error("Multisafepay IPN Error (incorrect hash)"); exit; } $sql = "SELECT * FROM `" . _DB_PREFIX . "user` WHERE user_id = '{$user_id}' LIMIT 1"; $res = qa($sql); if ($res) { $user = array_shift($res); if ($user && $user['user_id'] == $user_id) { // check for payment exists $payment = module_invoice::get_invoice_payment($payment_id); $invoice = module_invoice::get_invoice($invoice_id); if ($payment && $invoice) { $invoice_currency = module_config::get_currency($invoice['currency_id']); $invoice_currency_code = $invoice_currency['code']; // check correct business if (!$_REQUEST['business'] && $_REQUEST['receiver_email']) { $_REQUEST['business'] = $_REQUEST['receiver_email']; } if ($_REQUEST['business'] != module_config::c('payment_method_multisafepay_email', _ERROR_EMAIL)) { send_error('Multisafepay error! Paid the wrong business name. ' . $_REQUEST['business'] . ' instead of ' . module_config::c('payment_method_multisafepay_email', _ERROR_EMAIL)); exit; } // check correct currency if ($invoice_currency_code && $_REQUEST['mc_currency'] != $invoice_currency_code) { send_error('Multisafepay error! Paid the wrong currency code. ' . $_REQUEST['mc_currency'] . ' instead of ' . $invoice_currency_code); exit; } if ($_REQUEST['payment_status'] == "Canceled_Reversal" || $_REQUEST['payment_status'] == "Refunded") { // funky refund!! oh noes!! // TODO: store this in the database as a negative payment... should be easy. // populate $_REQUEST vars then do something like $payment_history_id = update_insert("payment_history_id","new","payment_history"); send_error("Multisafepay Error! The payment {$payment_id} has been refunded or reversed! BAD BAD! You have to follup up customer for money manually now."); } else { if ($_REQUEST['payment_status'] == "Completed") { // payment is completed! yeye getting closer... switch ($_REQUEST['txn_type']) { case "web_accept": // running in multisafepay sandbox or not? //$sandbox = (self::is_sandbox())?"sandbox.":''; // quick check we're not getting a fake payment request. $url = 'https://www.' . (self::is_sandbox() ? 'sandbox.' : '') . 'multisafepay.com/cgi-bin/webscr'; $result = self::fsockPost($url, $_POST); //send_error('multisafepay sock post: '.$url."\n\n".var_export($result,true)); if (eregi("VERIFIED", $result)) { // finally have everything. // mark the payment as completed. update_insert("invoice_payment_id", $payment_id, "invoice_payment", array('date_paid' => date('Y-m-d'), 'amount' => $_REQUEST['mc_gross'], 'method' => 'Multisafepay (IPN)')); module_invoice::save_invoice($invoice_id, array()); echo "Successful Payment!"; } else { send_error("Multisafepay IPN Error (multisafepay rejected the payment!) " . var_export($result, true)); } break; case "subscr_signup": default: // TODO: support different payment methods later? like a monthly hosting fee.. send_error("Multisafepay IPN Error (we dont currently support this payment method: " . $_REQUEST['txn_type'] . ")"); break; } } else { send_error("Multisafepay info: This payment is not yet completed, this usually means it's an e-cheque, follow it up in a few days if you dont hear anything. This also means you may have to login to multisafepay and 'Accept' the payment. So check there first."); } } } else { send_error("Multisafepay IPN Error (no payment found in database!)"); } } else { send_error("Multisafepay IPN Error (error with user that was found in database..)"); } } else { send_error("Multisafepay IPN Error (no user found in database #1)"); } } else { send_error("Multisafepay IPN Error (no user id found)"); } exit; }
public static function start_payment($invoice_id, $payment_amount, $invoice_payment_id, $user_id = false) { if ($invoice_id && $payment_amount && $invoice_payment_id) { // we are starting a payment via paynl! // setup a pending payment and redirect to paynl. $invoice_data = module_invoice::get_invoice($invoice_id); if (!$user_id) { $user_id = $invoice_data['user_id']; } if (!$user_id) { $user_id = isset($invoice_data['primary_user_id']) ? $invoice_data['primary_user_id'] : 0; } $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); // we add the fee details to the invoice payment record so that the new invoice total can be calculated. $fee_percent = module_config::c('payment_method_paynl_charge_percent', 0); $fee_amount = module_config::c('payment_method_paynl_charge_amount', 0); $fee_description = module_config::c('payment_method_paynl_charge_description', 'paynl Fee'); $fee_total = 0; if ($fee_percent != 0 || $fee_amount != 0) { $fee_total = module_invoice::calculate_fee($invoice_id, $invoice_data, $payment_amount, array('percent' => $fee_percent, 'amount' => $fee_amount, 'description' => $fee_description)); if ($fee_total != 0) { // add this percent/amount to the invoice payment $payment_amount = $payment_amount + $fee_total; update_insert('invoice_payment_id', $invoice_payment_id, 'invoice_payment', array('fee_percent' => $fee_percent, 'fee_amount' => $fee_amount, 'fee_description' => $fee_description, 'fee_total' => $fee_total, 'amount' => $payment_amount)); } } $description = _l('Payment for Invoice %s', $invoice_data['name']); self::paynl_redirect($description, $payment_amount, $user_id, $invoice_payment_id, $invoice_id, $invoice_payment_data['currency_id']); return true; } return false; }
public static function create_new_invoice_for_subscription_payment($invoice_id, $invoice_payment_id, $invoice_payment_subscription_id) { // we have an inbound subscription payment for an invoice. // we have to generate a new invoice (or find the generated invoice if one exists) // first we have to check if this payment is for this invoice (ie: the first subscription payment) $invoice_data = self::get_invoice($invoice_id); if ($invoice_data['total_amount_due'] > 0) { // this invoice is unpaid, we apply this subscription payment against thsi invoice return array('invoice_id' => $invoice_id, 'invoice_payment_id' => $invoice_payment_id); } // first we look for a generated invoice, this is easiest. if (class_exists('module_subscription', false)) { // check if this invoice is part of a subscription. // if it is we hunt through the subscription history until we find a recent unpaid invoice // THIS CODE IS SIMILAR TO module_invoice::is_automatic_paying_invoice($invoice_id) $subscription_history_item = get_single('subscription_history', 'invoice_id', $invoice_id); if ($subscription_history_item && $subscription_history_item['subscription_owner_id']) { // we have an invoice that is on a subscription! $subscription_owner = module_subscription::get_subscription_owner($subscription_history_item['subscription_owner_id']); // check if there are unpaid invoices that were generated after this invoice. if ($subscription_owner['subscription_owner_id'] == $subscription_history_item['subscription_owner_id']) { $subscription_history = get_multiple('subscription_history', array('subscription_owner_id' => $subscription_owner['subscription_owner_id'])); foreach ($subscription_history as $h) { if ($h['invoice_id'] > $invoice_id && $h['paid_date'] == '0000-00-00') { // found an invoice for this subscription that was generated after the initial invoice that is unpaid. // apply subscription payment to this one. $invoice_data = module_invoice::get_invoice($h['invoice_id']); if ($invoice_data['total_amount_due'] > 0) { $invoice_payment_id = update_insert('invoice_payment_id', false, 'invoice_payment', array('invoice_id' => $h['invoice_id'], 'payment_type' => _INVOICE_PAYMENT_TYPE_NORMAL, 'method' => _l('Pending Subscription'), 'currency_id' => $invoice_data['currency_id'], 'invoice_payment_subscription_id' => $invoice_payment_subscription_id)); return array('invoice_id' => $h['invoice_id'], 'invoice_payment_id' => $invoice_payment_id); } } } // if we get here it means we have a subscription invoice that hasn't been renewed yet. $subscription = module_subscription::get_subscription($subscription_owner['subscription_id']); // we force the renewal of the next invoice in this subscription lot and mark it as paid. $invoice_id = module_subscription::generate_subscription_invoice($subscription_owner['subscription_id'], $subscription_owner['owner_table'], $subscription_owner['owner_id'], date('Y-m-d'), $subscription['amount']); if ($invoice_id) { $invoice_data = module_invoice::get_invoice($invoice_id); $invoice_payment_id = update_insert('invoice_payment_id', false, 'invoice_payment', array('invoice_id' => $invoice_id, 'payment_type' => _INVOICE_PAYMENT_TYPE_NORMAL, 'method' => _l('Pending Subscription'), 'currency_id' => $invoice_data['currency_id'], 'invoice_payment_subscription_id' => $invoice_payment_subscription_id)); if ($subscription['automatic_email'] && module_config::c('invoice_subscription_send_due_email_before_payment', 1)) { if (module_invoice::email_invoice_to_customer($invoice_id)) { } else { echo " - failed to send subscription invoice " . module_invoice::link_open($invoice_id, true) . " to customer <br>\n"; } exit; } return array('invoice_id' => $invoice_id, 'invoice_payment_id' => $invoice_payment_id); } } } } }
<div class="content_box_wheader" style="padding-bottom: 20px"> <p> <?php _e('We found %s other invoices from this customer that can be merged.', count($merge_invoice_ids)); ?> <?php _h('You can generate invoices from multiple jobs (eg: a Hosting Setup job and a Web Development job) then you can combine them together here and send them as a single invoice to the customer, rather than sending multiple invoices.'); ?> </p> <ul> <?php foreach ($merge_invoice_ids as $merge_invoice) { $merge_invoice = module_invoice::get_invoice($merge_invoice['invoice_id']); ?> <li> <?php if ($merge_invoice['total_amount_paid']) { echo module_invoice::link_open($merge_invoice['invoice_id'], true); echo ' '; _e('(cannot merge, invoice already has payment)'); } else { ?> <input type="checkbox" name="merge_invoice[<?php echo $merge_invoice['invoice_id']; ?> ]" value="1">
public static function run_cron($debug = false) { // we only want to perform these cron actions if we're after a certain time of day // because we dont want to be generating these renewals and sending them at midnight, can get confusing $after_time = module_config::c('invoice_automatic_after_time', 7); $time_of_day = date('G'); if ($time_of_day < $after_time) { if ($debug) { echo "Not performing automatic subscription operations until after {$after_time}:00 - it is currently {$time_of_day}:" . date('i') . "<br>\n"; } return; } // find all automatic subscriptions and renew them (if applicable) $sql = "SELECT * FROM `" . _DB_PREFIX . "subscription` s "; $sql .= " WHERE s.automatic_renew = 1"; $subscriptions = qa($sql); foreach ($subscriptions as $subscription) { if ($subscription['automatic_renew']) { if ($debug) { echo "<br>\nProcessing subscription renewals for subscription " . module_subscription::link_open($subscription['subscription_id'], true) . "<br>\n<br>\n"; } // find all the members/customers from this subscription //$members = module_subscription::get_subscribed_members($subscription['subscription_id']); //$customers = module_subscription::get_subscribed_customers($subscription['subscription_id']); $owners = module_subscription::get_subscribed_owners($subscription['subscription_id']); foreach ($owners as $member) { if (!$member['next_generation_date'] || $member['next_generation_date'] == '0000-00-00') { continue; } if (!$member['next_due_date'] || $member['next_due_date'] == '0000-00-00') { continue; } if ($debug) { echo "Doing: " . $member['owner_table'] . " " . $member['owner_id'] . "<br>\n"; } // check permissions for logged in users, dont want the cron to run when someone is logged in and no access to this account. if (module_security::is_logged_in()) { switch ($member['owner_table']) { case 'website': $website_perm_check = module_website::get_website($member['owner_id']); if (!$website_perm_check || $website_perm_check['website_id'] != $member['owner_id']) { continue 2; } if ($debug) { echo "permission pass for website: " . $website_perm_check['website_id']; } break; case 'customer': $customer_perm_check = module_customer::get_customer($member['owner_id']); if (!$customer_perm_check || $customer_perm_check['customer_id'] != $member['owner_id']) { continue 2; } if ($debug) { echo "permission pass for customer: " . $customer_perm_check['customer_id']; } break; } } // is the last invoice unpaid? $history = self::get_subscription_history($subscription['subscription_id'], $member['owner_table'], $member['owner_id']); $next_due_time_invoice_created = false; $invoice_unpaid = false; if (isset($member['recur_limit']) && (int) $member['recur_limit'] > 0 && count($history) >= (int) $member['recur_limit']) { if ($debug) { echo " - not renewing this one because it has hit our recur limit of " . $member['recur_limit'] . "<br>\n"; } continue; } foreach ($history as $h) { $last_invoice = module_invoice::get_invoice($h['invoice_id']); if (!$last_invoice || $last_invoice['date_cancel'] != '0000-00-00') { continue; } // check the new 'next_due_date' entry in the db table if (isset($h['from_next_due_date']) && $h['from_next_due_date'] && $h['from_next_due_date'] != '0000-00-00') { // we're using the new method of checking when an invoice was generated, rather than the confusing invoice 'date_create' check below if ($debug) { echo " - checking if next_due_date " . print_date($member['next_due_date']) . " matches subscription history from_next_due_date for invoice " . module_invoice::link_open($h['invoice_id'], true, $last_invoice) . " from_next_due_date: " . print_date($h['from_next_due_date']) . " (invoice create_date: " . print_date($last_invoice['date_create']) . ")<br>\n"; } if (print_date($member['next_due_date']) == print_date($h['from_next_due_date'])) { //print_date($last_invoice['date_create'])){ // this invoice is for the next due date. $next_due_time_invoice_created = $last_invoice; } } else { if ($debug) { echo " - checking if next_generation_date (" . print_date($member['next_generation_date']) . ") or next_due_date (" . print_date($member['next_due_date']) . ") matches invoice " . module_invoice::link_open($h['invoice_id'], true, $last_invoice) . " created date (" . print_date($last_invoice['date_create']) . ") <br>\n"; } if (print_date($member['next_generation_date']) == print_date($last_invoice['date_create']) || print_date($member['next_due_date']) == print_date($last_invoice['date_create'])) { //print_date($last_invoice['date_create'])){ // this invoice is for the next due date. $next_due_time_invoice_created = $last_invoice; } } if ($last_invoice['total_amount_due'] > 0) { $invoice_unpaid = true; } } //self::generate_subscription_invoice($subscription_id, $customer_hack, $member_id, $date, $amount) $next_due_time = strtotime($member['next_generation_date']); if ($debug) { echo " - next subscription time is " . $member['next_generation_date'] . " <br>\n"; } if ($next_due_time <= strtotime(date('Y-m-d')) && !$next_due_time_invoice_created) { if ($debug) { echo " - Yes its time to generate an invoice!<br>\n"; } if (module_config::c('invoice_auto_renew_only_paid_invoices', 1) && $invoice_unpaid) { if ($debug) { echo " - skipping generating renewal for " . $member['owner_table'] . " " . $member['owner_id'] . " because a previous subscription is unpaid <br>\n"; } continue; } // time to generate! woo! if ($debug) { echo " - generating subscription renewal for " . $member['owner_table'] . " " . $member['owner_id'] . "<br>\n"; } $invoice_id = self::generate_subscription_invoice($subscription['subscription_id'], $member['owner_table'], $member['owner_id'], $member['next_generation_date'], $subscription['amount']); if ($debug) { echo " - generated invoice " . module_invoice::link_open($invoice_id, true) . " for subscription <br>\n"; } if ($subscription['automatic_email']) { if ($debug) { echo " - emailing invoice to " . $member['owner_table'] . "... <br>\n"; } if (module_invoice::email_invoice_to_customer($invoice_id, $debug)) { if ($debug) { echo "send successfully <br>\n"; } } else { echo " - failed to send invoice " . module_invoice::link_open($invoice_id, true) . " to " . $member['owner_table'] . " <br>\n"; } } } else { if ($debug) { echo " - skipping generating renewal for " . $member['owner_table'] . " " . $member['owner_id'] . " because the due date has already been generated <br>\n"; } } } } } }
public function external_hook($hook) { switch ($hook) { case 'event_ipn': $body = @file_get_contents('php://input'); $event_json = json_decode($body); ob_start(); echo "UCM coinbase DEBUG:<br><br>JSON: <br>\n"; print_r($event_json); echo "<br><br>\n"; $success = false; $bits = explode(':', isset($event_json->order->custom) ? $event_json->order->custom : ''); if (count($bits) == 4) { // we have our custom bits, invoice_id, invoice_payment_id and hash // check they are right $invoice_id = (int) $bits[0]; $invoice_payment_id = (int) $bits[1]; $invoice_payment_subscription_id = (int) $bits[2]; $hash = $bits[3]; $correct_hash = self::get_payment_key($invoice_id, $invoice_payment_id, $invoice_payment_subscription_id, true); if ($invoice_id && $invoice_payment_id && $hash == $correct_hash) { // This will send receipts on succesful invoices // todo - coinbase doesnt sent this callback correctly just yet if ($event_json && isset($event_json->recurring_payment) && $invoice_payment_subscription_id) { // status changes on a recurring payment. $invoice_payment_subscription = get_single('invoice_payment_subscription', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); if (!$invoice_payment_subscription['date_start'] || $invoice_payment_subscription['date_start'] == '0000-00-00') { // no start date yet, set the start date now. if ($event_json->recurring_payment->status == 'active') { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'))); } } if ($event_json->recurring_payment->status == 'paused' || $event_json->recurring_payment->status == 'canceled') { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_FAILED)); } } if ($event_json && isset($event_json->order->status) && $event_json->order->status == 'completed' && isset($event_json->order->total_native) && isset($event_json->order->custom)) { // crab out the custom bits so we know what to deal with. $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); $currency = module_config::get_currency($invoice_payment_data['currency_id']); if ($invoice_payment_subscription_id) { // this API result is for a subscription payment. $invoice_payment_subscription = get_single('invoice_payment_subscription', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); if ($invoice_payment_subscription && $invoice_payment_subscription['invoice_payment_subscription_id'] == $invoice_payment_subscription_id && $currency['code'] == $event_json->order->total_native->currency_iso) { if (!$invoice_payment_subscription['date_start'] || $invoice_payment_subscription['date_start'] == '0000-00-00') { // no start date yet, set the start date now (this should really happen in the above callback, but coinbase isn't working right now) update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'))); } // we have a subscription payment. woo! // this gets a bit tricky, we have to work out if the invoice has been generated for this subscription yet. // if this invoice hasn't been generated yet then we have to generate it. // pass this back to the invoice class so we can reuse this feature in the future. $data = module_invoice::create_new_invoice_for_subscription_payment($invoice_id, $invoice_payment_id, $invoice_payment_subscription_id); if ($data && $data['invoice_id'] && $data['invoice_payment_id']) { $next_time = time(); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['days']) . ' days', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['months']) . ' months', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['years']) . ' years', $next_time); update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('date_last_pay' => date('Y-m-d'), 'date_next' => date('Y-m-d', $next_time))); update_insert("invoice_payment_id", $data['invoice_payment_id'], "invoice_payment", array('date_paid' => date('Y-m-d'), 'amount' => $event_json->order->total_native->cents / 100, 'method' => self::get_payment_method_name() . ' (Subscription)', 'invoice_payment_subscription_id' => $invoice_payment_subscription_id)); self::add_payment_data($data['invoice_payment_id'], 'log', "Invoice Payment Subscription Received!"); self::add_payment_data($data['invoice_payment_id'], 'log', "API IP is " . $_SERVER['REMOTE_ADDR']); self::add_payment_data($data['invoice_payment_id'], 'log', "Received BTC: " . $event_json->order->total_btc->cents / 10000000); self::add_payment_data($data['invoice_payment_id'], 'log', "Received " . $event_json->order->total_native->currency_iso . ': ' . $event_json->order->total_native->cents / 100); self::add_payment_data($data['invoice_payment_id'], 'log', "Destination Address: " . $event_json->order->receive_address); self::add_payment_data($data['invoice_payment_id'], 'log', "Currency code matches, marking invoice as paid."); self::add_payment_data($data['invoice_payment_id'], 'log', "Raw Event Data: \n" . json_encode($event_json)); module_invoice::save_invoice($data['invoice_id'], array()); echo "Successful Subscription Payment!"; } else { send_error("Coinbase Subscription Error (failed to generate new invoice!) " . var_export($data, true)); } } else { send_error('Currency code missmatch on coinbase subscription payment'); } } else { // this is a normal once off payment. self::add_payment_data($invoice_payment_id, 'log', "API IP is " . $_SERVER['REMOTE_ADDR']); self::add_payment_data($invoice_payment_id, 'log', "Received BTC: " . $event_json->order->total_btc->cents / 10000000); self::add_payment_data($invoice_payment_id, 'log', "Received " . $event_json->order->total_native->currency_iso . ': ' . $event_json->order->total_native->cents / 100); self::add_payment_data($invoice_payment_id, 'log', "Destination Address: " . $event_json->order->receive_address); if ($currency['code'] == $event_json->order->total_native->currency_iso) { self::add_payment_data($invoice_payment_id, 'log', "Currency code matches, marking invoice as paid."); update_insert("invoice_payment_id", $invoice_payment_id, "invoice_payment", array('date_paid' => date('Y-m-d'), 'amount' => $event_json->order->total_native->cents / 100)); module_invoice::save_invoice($invoice_id, array()); echo "Successful Payment!"; $success = true; } else { self::add_payment_data($invoice_payment_id, 'log', "Currency code missmatch, please check settings!"); } self::add_payment_data($invoice_payment_id, 'log', "Raw Event Data: \n" . json_encode($event_json)); } } } } $debug = ob_get_clean(); if (module_config::c('coinbase_payment_debug', 0)) { send_error("Coinbase Debug: {$debug}"); } exit; break; case 'pay_subscription': $invoice_id = isset($_REQUEST['invoice_id']) ? $_REQUEST['invoice_id'] : false; $invoice_payment_id = isset($_REQUEST['invoice_payment_id']) ? $_REQUEST['invoice_payment_id'] : false; $invoice_payment_subscription_id = isset($_REQUEST['invoice_payment_subscription_id']) ? $_REQUEST['invoice_payment_subscription_id'] : false; $coinbase_plan_id = isset($_REQUEST['coinbase_plan_id']) ? $_REQUEST['coinbase_plan_id'] : false; $user_id = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : false; if ($invoice_id && $invoice_payment_id && $coinbase_plan_id && $invoice_payment_subscription_id && $user_id && isset($_POST['coinbaseToken'])) { $user_data = module_user::get_user($user_id); $email = isset($_REQUEST['coinbaseEmail']) && strlen($_REQUEST['coinbaseEmail']) ? $_REQUEST['coinbaseEmail'] : $user_data['email']; if (!$email || !strpos($email, '@')) { die('Please ensure your user account has a valid email address before paying with coinbase'); } $invoice_payment = get_single('invoice_payment', 'invoice_payment_id', $invoice_payment_id); $invoice_payment_subscription = get_single('invoice_payment_subscription', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); if (!$invoice_payment || !$invoice_payment_subscription || $invoice_payment['invoice_id'] != $invoice_id || $invoice_payment['invoice_payment_subscription_id'] != $invoice_payment_subscription_id) { die('Invalid invoice payment subscription id'); } $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); $invoice_data = module_invoice::get_invoice($invoice_id); if ($invoice_payment_data && $invoice_data && $invoice_id == $invoice_data['invoice_id'] && $invoice_payment_data['invoice_id'] == $invoice_data['invoice_id']) { $currency = module_config::get_currency($invoice_payment_data['currency_id']); $currency_code = $currency['code']; $description = isset($_REQUEST['description']) ? $_REQUEST['description'] : 'N/A'; $template = new module_template(); ob_start(); require_once 'includes/plugin_paymethod_coinbase/coinbase-php/lib/coinbase.php'; $coinbase = array("secret_key" => module_config::c('payment_method_coinbase_api_key'), "publishable_key" => module_config::c('payment_method_coinbase_secret_key')); coinbase::setApiKey($coinbase['secret_key']); try { // todo- search for existing customer based on email address??? // todo: check if adding new plan to existing customer work?? $coinbase_customer = coinbase_Customer::create(array("card" => $_POST['coinbaseToken'], "email" => $email, 'metadata' => array('user_id' => $user_id))); if ($coinbase_customer && $coinbase_customer->id) { //} && $coinbase_customer->subscriptions){ $coinbase_subscription = $coinbase_customer->subscriptions->create(array('plan' => $coinbase_plan_id)); if ($coinbase_subscription && $coinbase_subscription->id) { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'), 'coinbase_customer' => $coinbase_customer->id, 'coinbase_subscription' => $coinbase_subscription->id)); module_paymethod_coinbase::add_payment_data($invoice_payment_id, 'log', "Started coinbase Subscription: " . var_export(array('customer.id' => $coinbase_customer->id, 'plan.id' => $coinbase_plan_id, 'subscription.id' => $coinbase_subscription->id), true)); // success! // redirect to receipt page. redirect_browser(module_invoice::link_public_payment_complete($invoice_id)); } else { echo 'Failed to create subscription with coinbase'; } } $error = "Something went wrong during coinbase payment. Please confirm invoice payment went through: " . htmlspecialchars($description); send_error($error); echo $error; } catch (coinbase_CardError $e) { // The card has been declined $body = $e->getJsonBody(); $err = $body['error']; $error = "Sorry: Payment failed. <br><br>\n\n" . htmlspecialchars($description) . ". <br><br>\n\n"; $error .= $err['message']; echo $error; $error .= "\n\n\n" . var_export($err, true); send_error($error); } catch (Exception $e) { $body = $e->getJsonBody(); $err = $body['error']; $error = "Sorry: Payment failed. <br><br>\n\n" . htmlspecialchars($description) . ". <br><br>\n\n"; $error .= $err['message']; echo $error; $error .= "\n\n\n" . var_export($err, true); send_error($error); } $template->content = ob_get_clean(); echo $template->render('pretty_html'); exit; } } echo 'Error paying via coinbase'; exit; } }
?> <td valign="top"> <span class="<?php echo $percentage >= 1 ? 'success_text' : 'error_text'; ?> "> <?php echo $percentage * 100; ?> % </span> </td> <td align="center" valign="top"> <?php if ($task_data['invoiced'] && $task_data['invoice_id']) { $invoice = module_invoice::get_invoice($task_data['invoice_id']); ?> <a href="<?php echo module_invoice::link_public($invoice['invoice_id']); ?> "><?php echo $invoice['name']; ?> </a> <?php } else { if ($percentage >= 1) { echo '<span class="success_text">' . _l('Pending') . '</span>'; } else { echo _l('N/A'); } }
function handle_paypal_ipn() { ob_end_clean(); if (!isset($_REQUEST['custom'])) { return; } $paypal_bits = explode("|", $_REQUEST['custom']); $user_id = (int) $paypal_bits[0]; $payment_id = (int) $paypal_bits[1]; $invoice_id = (int) $paypal_bits[2]; $invoice_payment_subscription_id = false; if (count($paypal_bits) == 4) { // normal IPN, single payment. } else { if (count($paypal_bits) == 5) { // subscription IPN, with subscription id. $invoice_payment_subscription_id = (int) $paypal_bits[3]; $invoice_payment_subscription = get_single('invoice_payment_subscription', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); } } //send_error('bad?'); if ($payment_id && $invoice_id) { $hash = $this->paypal_custom($user_id, $payment_id, $invoice_id, $invoice_payment_subscription_id); if ($hash != $_REQUEST['custom']) { send_error("PayPal IPN Error (incorrect hash) it should be " . $hash); exit; } /*$sql = "SELECT * FROM `"._DB_PREFIX."user` WHERE user_id = '$user_id' LIMIT 1"; $res = qa($sql); if($res){ $user = array_shift($res); if($user && $user['user_id'] == $user_id){*/ // check for payment exists $payment = module_invoice::get_invoice_payment($payment_id); $invoice = module_invoice::get_invoice($invoice_id); if ($payment && $invoice) { /*if(isset($_REQUEST['fakepay'])){ if($invoice_payment_subscription_id){ // we have a subscription payment. woo! // this gets a bit tricky, we have to work out if the invoice has been generated for this subscription yet. // if this invoice hasn't been generated yet then we have to generate it. // pass this back to the invoice class so we can reuse this feature in the future. $data = module_invoice::create_new_invoice_for_subscription_payment($invoice_id, $payment_id, $invoice_payment_subscription_id); if($data && $data['invoice_id'] && $data['invoice_payment_id']){ $next_time = time(); $next_time = strtotime('+'.abs((int)$invoice_payment_subscription['days']).' days',$next_time); $next_time = strtotime('+'.abs((int)$invoice_payment_subscription['months']).' months',$next_time); $next_time = strtotime('+'.abs((int)$invoice_payment_subscription['years']).' years',$next_time); update_insert('invoice_payment_subscription_id',$invoice_payment_subscription_id,'invoice_payment_subscription',array( 'date_last_pay' => date('Y-m-d'), 'date_next' => date('Y-m-d',$next_time), )); $new_payment_details = array( 'date_paid' => date('Y-m-d'), 'amount' => $_REQUEST['mc_gross'], 'method' => 'PayPal (Subscription)', 'invoice_payment_subscription_id' => $invoice_payment_subscription_id, ); foreach(array('fee_percent','fee_amount','fee_description','fee_total') as $fee_field){ if(isset($payment[$fee_field])) { $new_payment_details[ $fee_field ] = $payment[ $fee_field ]; } } update_insert("invoice_payment_id",$data['invoice_payment_id'],"invoice_payment",$new_payment_details); module_invoice::save_invoice($data['invoice_id'],array()); echo "Successful Subscription Payment!"; }else{ send_error("PayPal IPN Subscription Error (failed to generate new invoice!) ".var_export($result,true)); } }else{ // mark a normal payment as paid update_insert("invoice_payment_id",$payment_id,"invoice_payment",array( 'date_paid' => date('Y-m-d'), 'amount' => $_REQUEST['mc_gross'], 'method' => 'PayPal (IPN)', )); module_invoice::save_invoice($invoice_id,array()); echo "Successful Payment!"; } echo 'fakepay done';exit; }*/ $invoice_currency = module_config::get_currency($invoice['currency_id']); $invoice_currency_code = $invoice_currency['code']; // check correct business if (!$_REQUEST['business'] && $_REQUEST['receiver_email']) { $_REQUEST['business'] = $_REQUEST['receiver_email']; } if ($_REQUEST['business'] != module_config::c('payment_method_paypal_email', _ERROR_EMAIL)) { send_error('PayPal error! Paid the wrong business name. ' . $_REQUEST['business'] . ' instead of ' . module_config::c('payment_method_paypal_email', _ERROR_EMAIL)); exit; } // check correct currency if ($invoice_currency_code && $_REQUEST['mc_currency'] != $invoice_currency_code) { send_error('PayPal error! Paid the wrong currency code. ' . $_REQUEST['mc_currency'] . ' instead of ' . $invoice_currency_code); exit; } switch ($_REQUEST['txn_type']) { // handle subscriptions first. // https://www.paypal.com/au/cgi-bin/webscr?cmd=p/acc/ipn-subscriptions-outside case "subscr_signup": // started! we update the start date of this one. if ($invoice_payment_subscription_id) { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'))); } break; case "subscr_cancel": case "subscr_failed": case "subscr_eot": if ($invoice_payment_subscription_id) { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_FAILED)); } break; break; case "subscr_payment": case "web_accept": if ($_REQUEST['payment_status'] == "Canceled_Reversal" || $_REQUEST['payment_status'] == "Refunded") { // funky refund!! oh noes!! // TODO: store this in the database as a negative payment... should be easy. // populate $_REQUEST vars then do something like $payment_history_id = update_insert("payment_history_id","new","payment_history"); send_error("PayPal Error! The payment {$payment_id} has been refunded or reversed! BAD BAD! You have to follup up customer for money manually now."); } else { if ($_REQUEST['payment_status'] == "Completed") { // payment is completed! yeye getting closer... // running in paypal sandbox or not? //$sandbox = (self::is_sandbox())?"sandbox.":''; // quick check we're not getting a fake payment request. $url = 'https://www.' . (self::is_sandbox() ? 'sandbox.' : '') . 'paypal.com/cgi-bin/webscr'; $result = self::fsockPost($url, $_POST); //send_error('paypal sock post: '.$url."\n\n".var_export($result,true)); if (eregi("VERIFIED", $result)) { // finally have everything. // mark the payment as completed. if ($invoice_payment_subscription_id) { // we have a subscription payment. woo! // this gets a bit tricky, we have to work out if the invoice has been generated for this subscription yet. // if this invoice hasn't been generated yet then we have to generate it. // pass this back to the invoice class so we can reuse this feature in the future. $data = module_invoice::create_new_invoice_for_subscription_payment($invoice_id, $payment_id, $invoice_payment_subscription_id); if ($data && $data['invoice_id'] && $data['invoice_payment_id']) { $next_time = time(); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['days']) . ' days', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['months']) . ' months', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['years']) . ' years', $next_time); update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('date_last_pay' => date('Y-m-d'), 'date_next' => date('Y-m-d', $next_time))); $new_payment_details = array('date_paid' => date('Y-m-d'), 'amount' => $_REQUEST['mc_gross'], 'method' => 'PayPal (Subscription)', 'invoice_payment_subscription_id' => $invoice_payment_subscription_id); foreach (array('fee_percent', 'fee_amount', 'fee_description', 'fee_total') as $fee_field) { if (isset($payment[$fee_field])) { $new_payment_details[$fee_field] = $payment[$fee_field]; } } update_insert("invoice_payment_id", $data['invoice_payment_id'], "invoice_payment", $new_payment_details); module_invoice::save_invoice($data['invoice_id'], array()); echo "Successful Subscription Payment!"; } else { send_error("PayPal IPN Subscription Error (failed to generate new invoice!) " . var_export($result, true)); } } else { // mark a normal payment as paid update_insert("invoice_payment_id", $payment_id, "invoice_payment", array('date_paid' => date('Y-m-d'), 'amount' => $_REQUEST['mc_gross'], 'method' => 'PayPal (IPN)')); module_invoice::save_invoice($invoice_id, array()); echo "Successful Payment!"; } /*// send customer an email thanking them for their payment. $sql = "SELECT * FROM "._DB_PREFIX."users WHERE user_id = '"._ADMIN_USER_ID."'"; $res = qa($sql); $admin = array_shift($res); $from_email = $admin['email']; $from_name = $admin['real_name']; $mail_content = "Dear ".$user['real_name'].", \n\n"; $mail_content .= "Your ".dollar($payment['outstanding'])." payment for '".$payment['description']."' has been processed. \n\n"; $mail_content .= "We have successfully recorded your ".dollar($_REQUEST['mc_gross'])." payment in our system.\n\n"; $mail_content .= "You will receive another email shortly from PayPal with details of the transaction.\n\n"; $mail_content .= "Kind Regards,\n\n"; $mail_content .= $from_name."\n".$from_email; send_error("PayPal SUCCESS!! User has paid you ".$_REQUEST['mc_gross']." we have recorded this against the payment and sent them an email"); //$this->send_email( $payment_id, $user['email'], $mail_content, "Payment Successful", $from_email, $from_name ); send_email($user['email'], "Payment Successful", $mail_content, array("FROM"=>$from_email,"FROM_NAME"=>$from_name)); */ // check if it's been paid in full.. } else { send_error("PayPal IPN Error (paypal rejected the payment!) " . var_export($result, true)); } } else { send_error("PayPal info: This payment is not yet completed, this usually means it's an e-cheque, follow it up in a few days if you dont hear anything. This also means you may have to login to paypal and 'Accept' the payment. So check there first."); } } break; default: send_error("PayPal IPN Error (unknown transaction t ype!) "); break; } } else { send_error("PayPal IPN Error (no payment found in database!)"); } /*}else{ send_error("PayPal IPN Error (error with user that was found in database..)"); } }else{ send_error("PayPal IPN Error (no user found in database #1)"); }*/ } else { send_error("PayPal IPN Error (no payment or invoice id found)"); } exit; }
// get a list of unpaid ticket invoices $sql = "SELECT t.ticket_id, i.invoice_id FROM "; $sql .= " `" . _DB_PREFIX . "ticket` t "; $sql .= " LEFT JOIN `" . _DB_PREFIX . "invoice` i ON t.invoice_id = i.invoice_id "; $sql .= " WHERE i.invoice_id IS NOT NULL "; $sql .= " AND i.date_paid = '0000-00-00' "; $sql .= " AND i.date_create < '" . date('Y-m-d', strtotime('-10 days')) . "' "; module_debug::log(array('title' => 'Finding invoices...', 'data' => '')); $invoices = qa($sql); module_debug::log(array('title' => 'Found ' . count($invoices) . ' invoices...', 'data' => '')); foreach ($invoices as $invoice) { if (!$invoice['invoice_id']) { continue; } module_debug::log(array('title' => 'Removing invoice: ', 'data' => $invoice['invoice_id'])); $invoice_check = module_invoice::get_invoice($invoice['invoice_id']); module_debug::log(array('title' => 'Removing invoice: (2) ', 'data' => $invoice['invoice_id'])); if ($invoice_check['invoice_id'] != $invoice['invoice_id']) { continue; } if ($invoice_check['total_amount_paid'] <= 0) { // remove this invoice module_debug::log(array('title' => 'Removing invoice: (3) ', 'data' => $invoice['invoice_id'])); echo "Deleting invoice " . $invoice_check['name'] . " for " . dollar($invoice_check['total_amount_due'], true, $invoice_check['currency_id']) . " from " . print_date($invoice_check['date_create']) . " and ticket " . module_ticket::link_open($invoice['ticket_id'], true, $invoice_check) . " <br>\n"; module_invoice::delete_invoice($invoice['invoice_id']); module_debug::log(array('title' => 'Removing invoice: (done)', 'data' => $invoice['invoice_id'])); } } echo "Done"; } else { if (isset($_POST['bulk_process_go']) && $_POST['bulk_process_go'] == 'true') {
public function external_hook($hook) { switch ($hook) { case 'event_ipn': require_once 'includes/plugin_paymethod_stripe/stripe-php/lib/Stripe.php'; $stripe = array("secret_key" => module_config::c('payment_method_stripe_secret_key'), "publishable_key" => module_config::c('payment_method_stripe_publishable_key')); Stripe::setApiKey($stripe['secret_key']); $body = @file_get_contents('php://input'); $event_json = json_decode($body); ob_start(); // echo "INPUT: <br>\n"; // print_r($body); // echo "<br><br>\n"; echo "UCM STRIPE DEBUG:<br><br>JSON: <br>\n"; print_r($event_json); echo "<br><br>\n"; $event_id = $event_json->id; try { $event = Stripe_Event::retrieve($event_id); // This will send receipts on succesful invoices if ($event->type == 'charge.succeeded' && $event->data->object->invoice) { $paid_amount = $event->data->object->amount / 100; // get the invoice. $invoice = Stripe_Invoice::retrieve($event->data->object->invoice); echo "INVOICE: <br>\n"; print_r($invoice); echo "<br><br>\n"; if ($invoice && $invoice->subscription && $invoice->paid) { // this payment was for a subscription! which one though? $customer = Stripe_Customer::retrieve($invoice->customer); echo "CUSTOMER: <br>\n"; print_r($customer); echo "<br><br>\n"; $subscription = $customer->subscriptions->retrieve($invoice->subscription); echo "SUBSCRIPTION: <br>\n"; print_r($subscription); echo "<br><br>\n"; // now we have the Customer and Subscription we can look through our invoice_payment_subscription table for those values. /*update_insert('invoice_payment_subscription_id',$invoice_payment_subscription_id,'invoice_payment_subscription',array( 'status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'), // we also have to store the stripe details here so we can easily search for them later on. 'stripe_customer' => $stripe_customer->id, 'stripe_subscription' => $stripe_subscription->id, ));*/ $invoice_payment_subscription = get_single('invoice_payment_subscription', array('stripe_customer', 'stripe_subscription'), array($customer->id, $subscription->id)); if ($invoice_payment_subscription) { // FIND THE linked invoice_payment for this original invoice payment subscription, this allows us to perform the same creatE_new_invoice as paypal below: $invoice_payment_subscription_id = $invoice_payment_subscription['invoice_payment_subscription_id']; $invoice_payment = get_single('invoice_payment', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); if ($invoice_payment) { $payment_id = $invoice_payment['invoice_payment_id']; $invoice_id = $invoice_payment['invoice_id']; // we have a subscription payment. woo! // this gets a bit tricky, we have to work out if the invoice has been generated for this subscription yet. // if this invoice hasn't been generated yet then we have to generate it. // pass this back to the invoice class so we can reuse this feature in the future. $data = module_invoice::create_new_invoice_for_subscription_payment($invoice_id, $payment_id, $invoice_payment_subscription_id); if ($data && $data['invoice_id'] && $data['invoice_payment_id']) { $next_time = time(); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['days']) . ' days', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['months']) . ' months', $next_time); $next_time = strtotime('+' . abs((int) $invoice_payment_subscription['years']) . ' years', $next_time); update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('date_last_pay' => date('Y-m-d'), 'date_next' => date('Y-m-d', $next_time))); update_insert("invoice_payment_id", $data['invoice_payment_id'], "invoice_payment", array('date_paid' => date('Y-m-d'), 'amount' => $paid_amount, 'method' => 'Stripe (Subscription)', 'invoice_payment_subscription_id' => $invoice_payment_subscription_id)); module_paymethod_stripe::add_payment_data($data['invoice_payment_id'], 'log', "Payment Received via Webhook: " . var_export(array('event.type' => $event->type, 'invoice.id' => $invoice->id, 'subscription.id' => $subscription->id, 'customer.id' => $customer->id, '$invoice_payment_subscription_id' => $invoice_payment_subscription_id, '$invoice_payment_id' => $payment_id), true)); module_invoice::save_invoice($data['invoice_id'], array()); echo "Successful Subscription Payment For Invoice " . $data['invoice_id']; } else { send_error("Stripe Webhook Subscription Error (failed to generate new invoice!) " . var_export($data, true)); } } else { echo 'Failed to find matching invoice payment in db'; } } else { echo 'Failed to find matching subscription payment in db'; } } } } catch (Exception $e) { $body = $e->getJsonBody(); $err = $body['error']; $error = "Sorry: Webhook failed. <br><br>\n\n"; $error .= $err['message']; $error .= "\n\n\n" . var_export($e, true); echo $error; } $debug = ob_get_clean(); //mail('*****@*****.**','Stripe Webhook debug',$debug); if (module_config::c('stripe_payment_debug', 0)) { echo $debug; } echo "Thanks! (set stripe_payment_debug to 1 in UCM to see more data here)"; exit; break; case 'pay_subscription': $invoice_id = isset($_REQUEST['invoice_id']) ? $_REQUEST['invoice_id'] : false; $invoice_payment_id = isset($_REQUEST['invoice_payment_id']) ? $_REQUEST['invoice_payment_id'] : false; $invoice_payment_subscription_id = isset($_REQUEST['invoice_payment_subscription_id']) ? $_REQUEST['invoice_payment_subscription_id'] : false; $stripe_plan_id = isset($_REQUEST['stripe_plan_id']) ? $_REQUEST['stripe_plan_id'] : false; $user_id = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : false; if ($invoice_id && $invoice_payment_id && $stripe_plan_id && $invoice_payment_subscription_id && $user_id && isset($_POST['stripeToken'])) { $user_data = module_user::get_user($user_id); $email = isset($_REQUEST['stripeEmail']) && strlen($_REQUEST['stripeEmail']) ? $_REQUEST['stripeEmail'] : $user_data['email']; if (!$email || !strpos($email, '@')) { die('Please ensure your user account has a valid email address before paying with stripe'); } $invoice_payment = get_single('invoice_payment', 'invoice_payment_id', $invoice_payment_id); $invoice_payment_subscription = get_single('invoice_payment_subscription', 'invoice_payment_subscription_id', $invoice_payment_subscription_id); if (!$invoice_payment || !$invoice_payment_subscription || $invoice_payment['invoice_id'] != $invoice_id || $invoice_payment['invoice_payment_subscription_id'] != $invoice_payment_subscription_id) { die('Invalid invoice payment subscription id'); } $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); $invoice_data = module_invoice::get_invoice($invoice_id); if ($invoice_payment_data && $invoice_data && $invoice_id == $invoice_data['invoice_id'] && $invoice_payment_data['invoice_id'] == $invoice_data['invoice_id']) { $currency = module_config::get_currency($invoice_payment_data['currency_id']); $currency_code = $currency['code']; $description = isset($_REQUEST['description']) ? $_REQUEST['description'] : 'N/A'; $template = new module_template(); ob_start(); require_once 'includes/plugin_paymethod_stripe/stripe-php/lib/Stripe.php'; $stripe = array("secret_key" => module_config::c('payment_method_stripe_secret_key'), "publishable_key" => module_config::c('payment_method_stripe_publishable_key')); Stripe::setApiKey($stripe['secret_key']); try { // todo- search for existing customer based on email address??? // todo: check if adding new plan to existing customer work?? $stripe_customer = Stripe_Customer::create(array("card" => $_POST['stripeToken'], "email" => $email, 'metadata' => array('user_id' => $user_id))); if ($stripe_customer && $stripe_customer->id) { //} && $stripe_customer->subscriptions){ $stripe_subscription = $stripe_customer->subscriptions->create(array('plan' => $stripe_plan_id)); if ($stripe_subscription && $stripe_subscription->id) { update_insert('invoice_payment_subscription_id', $invoice_payment_subscription_id, 'invoice_payment_subscription', array('status' => _INVOICE_SUBSCRIPTION_ACTIVE, 'date_start' => date('Y-m-d'), 'stripe_customer' => $stripe_customer->id, 'stripe_subscription' => $stripe_subscription->id)); module_paymethod_stripe::add_payment_data($invoice_payment_id, 'log', "Started Stripe Subscription: " . var_export(array('customer.id' => $stripe_customer->id, 'plan.id' => $stripe_plan_id, 'subscription.id' => $stripe_subscription->id), true)); // success! // redirect to receipt page. redirect_browser(module_invoice::link_public_payment_complete($invoice_id)); } else { echo 'Failed to create subscription with stripe'; } } $error = "Something went wrong during stripe payment. Please confirm invoice payment went through: " . htmlspecialchars($description); send_error($error); echo $error; } catch (Stripe_CardError $e) { // The card has been declined $body = $e->getJsonBody(); $err = $body['error']; $error = "Sorry: Payment failed. <br><br>\n\n" . htmlspecialchars($description) . ". <br><br>\n\n"; $error .= $err['message']; echo $error; $error .= "\n\n\n" . var_export($err, true); send_error($error); } catch (Exception $e) { $body = $e->getJsonBody(); $err = $body['error']; $error = "Sorry: Payment failed. <br><br>\n\n" . htmlspecialchars($description) . ". <br><br>\n\n"; $error .= $err['message']; echo $error; $error .= "\n\n\n" . var_export($err, true); send_error($error); } $template->content = ob_get_clean(); echo $template->render('pretty_html'); exit; } } echo 'Error paying via Stripe'; exit; case 'pay': $invoice_id = isset($_REQUEST['invoice_id']) ? $_REQUEST['invoice_id'] : false; $invoice_payment_id = isset($_REQUEST['invoice_payment_id']) ? $_REQUEST['invoice_payment_id'] : false; if ($invoice_id && $invoice_payment_id && isset($_POST['stripeToken'])) { $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); $invoice_data = module_invoice::get_invoice($invoice_id); if ($invoice_payment_data && $invoice_data && $invoice_id == $invoice_data['invoice_id'] && $invoice_payment_data['invoice_id'] == $invoice_data['invoice_id']) { $currency = module_config::get_currency($invoice_payment_data['currency_id']); $currency_code = $currency['code']; $description = _l('Payment for invoice %s', $invoice_data['name']); $template = new module_template(); ob_start(); include module_theme::include_ucm('includes/plugin_paymethod_stripe/pages/stripe_form.php'); $template->content = ob_get_clean(); echo $template->render('pretty_html'); exit; } } echo 'Error paying via Stripe'; exit; } }
<tbody> <tr> <td> <?php if ($ticket['priority'] != _TICKET_PRIORITY_STATUS_ID) { echo '<p>'; _e("Current ticket position is: <strong>%s of %s</strong>.", ordinal($ticket['position']), $ticket['total_pending']); echo '<br/>'; $x = module_ticket::get_ticket_count($ticket['faq_product_id']); _e('Priority Support will change this to: <strong>%s of %s</strong>.', ordinal($x['priority'] + 1), $ticket['total_pending']); echo '<br/>'; _e('This means your question will be answered faster.'); echo '</p>'; } if ($ticket['invoice_id']) { $invoice_data = module_invoice::get_invoice($ticket['invoice_id']); if (!$invoice_data || $invoice_data['invoice_id'] != $ticket['invoice_id']) { // ticket invoice has been deleted. // unlink it from this ticket. if ($ticket['ticket_id']) { update_insert('ticket_id', $ticket['ticket_id'], 'ticket', array('invoice_id' => 0)); } echo 'invoice removed... please refresh'; } else { if ($invoice_data['total_amount_due'] > 0) { $responsive_summary[] = _l("Please pay <strong>%s</strong>.", dollar($invoice_data['total_amount_due'], true, $invoice_data['currency_id'])); echo '<p>'; echo _l("Please pay <strong>%s</strong> to receive Priority Support. To make payment please click the button below.", dollar($invoice_data['total_amount_due'], true, $invoice_data['currency_id'])); echo '</p>'; echo '<p align="center">'; echo '<a href="' . module_invoice::link_public($ticket['invoice_id']) . '" target="_blank" class="uibutton small_button">' . _l('Pay Now') . '</a>';
if ($invoice_payment_data) { // we make sure this NEW invoice payment record hasn't already been recorded somewhere. $existing = module_finance::get_finances(array('invoice_payment_id' => $invoice_payment_data['invoice_payment_id'])); if (count($existing)) { foreach ($existing as $e) { if (isset($e['finance_id']) && (int) $e['finance_id'] > 0) { $link = module_finance::link_open($e['finance_id']); if ($link) { redirect_browser($link); } } } } } $linked_invoice_payments[] = $invoice_payment_data; $invoice_data = module_invoice::get_invoice($invoice_payment_data['invoice_id']); $finance['customer_id'] = $invoice_data['customer_id']; if ($invoice_data['job_ids']) { foreach ($invoice_data['job_ids'] as $job_id) { $finance['job_id'] = $job_id; // meh! pick last one. } } $locked = true; } } else { $linked_invoice_payments = $finance['linked_invoice_payments']; $linked_finances = $finance['linked_finances']; $module->page_title = $finance['name']; } // check permissions.
public function generate_priority_invoice($ticket_id) { // call the invoice module and create an invoice for this ticket. // once this invoice is paid it will do a callback to the ticket. $ticket_data = $this->get_ticket($ticket_id); // check if no invoice exists. if (!$ticket_data['invoice_id']) { $task_name = module_config::c('ticket_priority_invoice_task', 'Priority Support Ticket'); $task_cost = module_config::c('ticket_priority_cost', 10); $task_currency = module_config::c('ticket_priority_currency', 1); // we do this hack so that the customer can have different invoice templates for support tickets. $old_customer_id = isset($_REQUEST['customer_id']) ? $_REQUEST['customer_id'] : false; $_REQUEST['customer_id'] = $ticket_data['customer_id']; $invoice_data = module_invoice::get_invoice('new', true); $_REQUEST['customer_id'] = $old_customer_id; // todo - if the ticket customer_id changes (a feature for later on) then we have to update any of these invoices. // maybe it's best we don't have a customer_id here? hmmmmmmmmmmmmmmmmmm // the user will have to enter their own invoice details anyway. // maybe we can read the customer_id from the user table if there is no customer_id in the invoice table? that might fix some things. $invoice_data['customer_id'] = $ticket_data['customer_id']; $invoice_data['user_id'] = $ticket_data['user_id']; $invoice_data['currency_id'] = $task_currency; $invoice_data['date_sent'] = date('Y-m-d'); $invoice_data['name'] = 'T' . $this->ticket_number($ticket_id); // don't set an automatic reminder on invoices $invoice_data['overdue_email_auto'] = module_config::c('ticket_priority_auto_overdue_email', 0); // pick a tax rate for this automatic invoice. //if(module_config::c('ticket_priority_tax_name','')){ $invoice_data['total_tax_name'] = module_config::c('ticket_priority_tax_name', ''); //} //if(module_config::c('ticket_priority_tax_rate','')){ $invoice_data['total_tax_rate'] = module_config::c('ticket_priority_tax_rate', ''); //} $invoice_data['invoice_invoice_item'] = array('new' => array('description' => $task_name . ' - ' . _l('Ticket #' . $this->ticket_number($ticket_id)), 'hourly_rate' => $task_cost, 'manual_task_type' => _TASK_TYPE_AMOUNT_ONLY, 'completed' => 1)); $invoice_id = module_invoice::save_invoice('new', $invoice_data); update_insert('ticket_id', $ticket_id, 'ticket', array('invoice_id' => $invoice_id)); module_invoice::add_history($invoice_id, 'Created invoice from support ticket #' . $this->ticket_number($ticket_id)); return $invoice_id; } return $ticket_data['invoice_id']; }
<th><?php _e('Invoice'); ?> </th> <th><?php _e('Amount'); ?> </th> </tr> </thead> <tbody> <?php foreach ($res as $r) { $invoice_data = array(); if (isset($r['invoice_id']) && $r['invoice_id'] > 0) { $invoice_data = module_invoice::get_invoice($r['invoice_id']); } ?> <tr> <td> <?php echo print_date($r['date_paid']); ?> </td> <?php if (isset($r['website_id']) || isset($r['job_id']) || isset($r['invoice_id'])) { ?> <td> <?php if (isset($r['website_id']) && $r['website_id'] > 0) { echo module_website::link_open($r['website_id'], true);
public static function banktransfer_redirect($description, $amount, $user_id, $payment_id, $invoice_id) { $invoice_data = module_invoice::get_invoice($invoice_id); $invoice_replace = module_invoice::get_replace_fields($invoice_id, $invoice_data); $bank_details = module_template::get_template_by_key('paymethod_banktransfer_details'); $bank_details->assign_values($invoice_data + array('amount' => dollar($amount, true, $invoice_data['currency_id']))); $bank_details->assign_values($invoice_replace); $bank_details_html = $bank_details->render('html'); // display a template with the bank details in it. $template = module_template::get_template_by_key('paymethod_banktransfer'); $template->assign_values(array('bank_details' => $bank_details_html, 'link' => module_invoice::link_open($invoice_id))); $template->assign_values($invoice_replace); echo $template->render('pretty_html'); exit; }
<td> <a href="<?php echo $finance['url']; ?> "><?php echo !trim($finance['name']) ? 'N/A' : htmlspecialchars($finance['name']); ?> </a> </td> <td><?php echo $finance['customer_id'] ? module_customer::link_open($finance['customer_id'], true) : _l('N/A'); ?> </td> <td><?php if ($finance['invoice_id']) { $invoice_data = module_invoice::get_invoice($finance['invoice_id']); echo module_invoice::link_open($finance['invoice_id'], true, $invoice_data); } else { _e('N/A'); } ?> </td> <td><?php if (isset($finance['job_id']) && $finance['job_id']) { echo module_job::link_open($finance['job_id'], true); } else { if ($finance['invoice_id'] && count($invoice_data['job_ids'])) { foreach ($invoice_data['job_ids'] as $job_id) { echo module_job::link_open($job_id, true) . ' '; } } else {
$table_manager->display_extra('invoice', function ($invoice) { module_extra::print_table_data('invoice', $invoice['invoice_id']); }); } if (module_invoice::can_i('edit', 'Invoices')) { $colspan2++; // used in the footer $columns['row_bulk_action'] = array('title' => ' ', 'callback' => function ($invoice) { echo '<input type="checkbox" name="invoice_bulk_operation[' . $invoice['invoice_id'] . ']" value="yes">'; }); } $table_manager->set_columns($columns); $table_manager->row_callback = function ($row_data) { // load the full vendor data before displaying each row so we have access to more details if (isset($row_data['invoice_id']) && (int) $row_data['invoice_id'] > 0) { return module_invoice::get_invoice($row_data['invoice_id']); } return array(); }; $table_manager->set_rows($invoices); if (module_config::c('invoice_list_show_totals', 1)) { $footer_rows = array(); foreach ($invoice_total + $invoice_total_due as $currency_id => $foo) { $currency = get_single('currency', 'currency_id', $currency_id); $footer_rows[] = array('invoice_number' => array('data' => '<strong>' . _l('%s Totals:', $currency && isset($currency['code']) ? $currency['code'] : '') . '</strong>', 'cell_colspan' => $colspan - 2, 'cell_class' => 'text-right'), 'c_invoice_total' => array('data' => '<strong>' . dollar(isset($invoice_total[$currency_id]) ? $invoice_total[$currency_id] : 0, true, $currency_id) . '</strong>'), 'c_invoice_total_due' => array('data' => '<strong>' . dollar(isset($invoice_total_due[$currency_id]) ? $invoice_total_due[$currency_id] : 0, true, $currency_id) . '</strong>'), 'row_bulk_action' => array('data' => ' ', 'cell_colspan' => $colspan2)); } $table_manager->set_footer_rows($footer_rows); } $table_manager->pagination = true; $table_manager->print_table(); ?>
public function run_cron($debug = false) { // we only want to perform these cron actions if we're after a certain time of day // because we dont want to be generating these renewals and sending them at midnight, can get confusing $after_time = module_config::c('invoice_automatic_after_time', 7); $time_of_day = date('G'); if ($time_of_day < $after_time) { if ($debug) { echo "Not performing automatic invoice operations until after {$after_time}:00 - it is currently {$time_of_day}:" . date('i') . "<br>\n"; } return; } // find automatic job renewals $sql = "SELECT p.* FROM `" . _DB_PREFIX . "job` p "; $sql .= " WHERE p.date_renew != '0000-00-00'"; $sql .= " AND p.date_start != '0000-00-00'"; $sql .= " AND p.date_renew <= '" . date('Y-m-d') . "'"; $sql .= " AND (p.renew_job_id IS NULL OR p.renew_job_id = 0)"; $sql .= " AND (p.renew_auto = 1)"; $renew_jobs = qa($sql); foreach ($renew_jobs as $renew_job) { // time to automatically renew this job! woo! if ($debug) { echo "Automatically Renewing Job " . module_job::link_open($renew_job['job_id'], true) . "<br>\n"; } //$job_details = $this->get_job($renew_job['job_id']); $job_invoices = module_invoice::get_invoices(array('job_id' => $renew_job['job_id'])); $unpaid_invoice = false; foreach ($job_invoices as $job_invoice) { $job_invoice = module_invoice::get_invoice($job_invoice['invoice_id']); if ($job_invoice['total_amount_due'] > 0) { $unpaid_invoice = true; } } if (module_config::c('invoice_auto_renew_only_paid_invoices', 1) && $unpaid_invoice) { if ($debug) { echo "Not automatically renewing this job because it has unpaid invoices. <br>\n"; } } else { $new_job_id = $this->renew_job($renew_job['job_id'], true); if ($new_job_id) { //module_cache::clear_cache(); if ($debug) { echo "Job Automatically Renewed: " . module_job::link_open($new_job_id, true) . "<br>\n"; } if ($renew_job['renew_invoice']) { // we want to tick all these tasks off and invoice this job, then send this invoice to the customer. $job_tasks = module_job::get_tasks($new_job_id); foreach ($job_tasks as $job_task_id => $job_task) { $job_tasks[$job_task_id]['fully_completed_t'] = 1; $job_tasks[$job_task_id]['fully_completed'] = 1; } $this->save_job_tasks($new_job_id, array('job_task' => $job_tasks)); //module_cache::clear_cache(); // generate an invoice for this job. $_REQUEST['job_id'] = $new_job_id; $new_invoice = module_invoice::get_invoice('new'); $new_invoice['date_create'] = $renew_job['date_renew']; $new_invoice['invoice_invoice_item'] = module_invoice::get_invoice_items('new', $new_invoice); $new_invoice_id = module_invoice::save_invoice('new', $new_invoice); //module_cache::clear_cache(); if ($debug) { echo "Generated new invoice for renewed job: " . module_invoice::link_open($new_invoice_id, true) . "<br/>"; } if ($debug) { echo "Emailing invoice to customer..."; } if (module_invoice::email_invoice_to_customer($new_invoice_id)) { if ($debug) { echo "send successfully"; } } else { if ($debug) { echo "send failed"; } } if ($debug) { echo "<br>\n"; } } } } } }
public function external_hook($hook) { switch ($hook) { case 'public_signup_form': $signup_form = module_template::get_template_by_key('customer_signup_form_wrapper'); $signup_form->page_title = $signup_form->description; $signup_form->assign_values(array('signup_form' => self::get_customer_signup_form_html())); echo $signup_form->render('pretty_html'); exit; case 'public_signup': // sign out if testing. if (module_security::is_logged_in()) { set_message('Logged out due to signup'); module_security::logout(); } $result = array('messages' => array()); function customer_signup_complete($result) { if (isset($_REQUEST['via_ajax'])) { echo json_encode($result); } else { echo implode('<br/>', $result['messages']); } exit; } if (!module_config::c('customer_signup_allowed', 0)) { $result['error'] = 1; $result['messages'][] = 'Customer signup disabled'; customer_signup_complete($result); } //recaptcha on signup form. if (module_config::c('captcha_on_signup_form', 0)) { if (!module_captcha::check_captcha_form()) { $result['error'] = 1; $result['messages'][] = 'Captcha fail, please go back and enter correct captcha code.'; customer_signup_complete($result); } } $customer = isset($_POST['customer']) && is_array($_POST['customer']) ? $_POST['customer'] : array(); $contact = isset($_POST['contact']) && is_array($_POST['contact']) ? $_POST['contact'] : array(); $contact_extra = isset($contact['extra']) && is_array($contact['extra']) ? $contact['extra'] : array(); $contact_group = isset($contact['group_ids']) && is_array($contact['group_ids']) ? $contact['group_ids'] : array(); $customer_extra = isset($customer['extra']) ? $customer['extra'] : array(); $customer_group = isset($customer['group_ids']) && is_array($customer['group_ids']) ? $customer['group_ids'] : array(); $address = isset($_POST['address']) ? $_POST['address'] : array(); $website = isset($_POST['website']) ? $_POST['website'] : array(); $website_extra = isset($website['extra']) ? $website['extra'] : array(); $website_group = isset($website['group_ids']) && is_array($website['group_ids']) ? $website['group_ids'] : array(); $job = isset($_POST['job']) ? $_POST['job'] : array(); $job_extra = isset($job['extra']) ? $job['extra'] : array(); $subscription = isset($_POST['subscription']) ? $_POST['subscription'] : array(); // sanatise possibly problematic fields: // customer: $allowed = array('name', 'last_name', 'customer_name', 'email', 'phone', 'mobile', 'extra', 'type'); foreach ($customer as $key => $val) { if (!in_array($key, $allowed)) { unset($customer[$key]); } } if (isset($customer['type']) && $customer['type'] != _CUSTOMER_TYPE_NORMAL && $customer['type'] != _CUSTOMER_TYPE_LEAD) { unset($customer['type']); } // added multiple contact support in the form of arrays. $contact_fields = array('name', 'last_name', 'email', 'phone'); if (module_config::c('customer_signup_password', 0)) { $contact_fields[] = 'password'; } foreach ($contact_fields as $multi_value) { if (isset($contact[$multi_value])) { if (!is_array($contact[$multi_value])) { $contact[$multi_value] = array($contact[$multi_value]); } } else { if (isset($customer[$multi_value])) { $contact[$multi_value] = array($customer[$multi_value]); } else { $contact[$multi_value] = array(); } } } $valid_contact_email = false; $name_fallback = false; $primary_email = false; foreach ($contact['email'] as $contact_key => $email) { if (!$name_fallback && isset($contact['name'][$contact_key])) { $name_fallback = $contact['name'][$contact_key]; } $contact['email'][$contact_key] = filter_var(strtolower(trim($email)), FILTER_VALIDATE_EMAIL); if ($contact['email'][$contact_key]) { $valid_contact_email = true; if (!$primary_email) { $primary_email = $contact['email'][$contact_key]; // set the primary contact details here by adding them to the master customer array foreach ($contact_fields as $primary_contact_field) { $customer[$primary_contact_field] = isset($contact[$primary_contact_field][$contact_key]) ? $contact[$primary_contact_field][$contact_key] : ''; unset($contact[$primary_contact_field][$contact_key]); } } } } // start error checking / required fields if (!isset($customer['customer_name']) || !strlen($customer['customer_name'])) { $customer['customer_name'] = $name_fallback; } if (!strlen($customer['customer_name'])) { $result['error'] = 1; $result['messages'][] = "Failed, please go back and provide a customer name."; } if (!$valid_contact_email || !$primary_email) { $result['error'] = 1; $result['messages'][] = "Failed, please go back and provide an email address."; } // check all posted required fields. function check_required($postdata, $messages = array()) { if (is_array($postdata)) { foreach ($postdata as $key => $val) { if (strpos($key, '_required') && strlen($val)) { $required_key = str_replace('_required', '', $key); if (!isset($postdata[$required_key]) || !$postdata[$required_key]) { $messages[] = 'Required field missing: ' . htmlspecialchars($val); } } if (is_array($val)) { $messages = check_required($val, $messages); } } } return $messages; } $messages = check_required($_POST); if (count($messages)) { $result['error'] = 1; $result['messages'] = array_merge($result['messages'], $messages); } if (isset($result['error'])) { customer_signup_complete($result); } // end error checking / required fields. // check if this customer already exists in the system, based on email address $customer_id = false; $creating_new = true; $_REQUEST['user_id'] = 0; if (isset($customer['email']) && strlen($customer['email']) && !module_config::c('customer_signup_always_new', 0)) { $users = module_user::get_contacts(array('email' => $customer['email'])); foreach ($users as $user) { if (isset($user['customer_id']) && (int) $user['customer_id'] > 0) { // this user exists as a customer! yey! // add them to this listing. $customer_id = $user['customer_id']; $creating_new = false; $_REQUEST['user_id'] = $user['user_id']; // dont let signups update existing passwords. if (isset($customer['password'])) { unset($customer['password']); } if (isset($customer['new_password'])) { unset($customer['new_password']); } } } } $_REQUEST['extra_customer_field'] = array(); $_REQUEST['extra_user_field'] = array(); module_extra::$config['allow_new_keys'] = false; module_extra::$config['delete_existing_empties'] = false; // save customer extra fields. if (count($customer_extra)) { // format the address so "save_customer" handles the save for us foreach ($customer_extra as $key => $val) { $_REQUEST['extra_customer_field'][] = array('key' => $key, 'val' => $val); } } // save customer and customer contact details: $customer_id = $this->save_customer($customer_id, $customer); if (!$customer_id) { $result['error'] = 1; $result['messages'][] = 'System error: failed to create customer.'; customer_signup_complete($result); } $customer_data = module_customer::get_customer($customer_id); // todo - merge primary and secondary contact/extra/group saving into a single loop if (!$customer_data['primary_user_id']) { $result['error'] = 1; $result['messages'][] = 'System error: Failed to create customer contact.'; customer_signup_complete($result); } else { $role_id = module_config::c('customer_signup_role', 0); if ($role_id > 0) { module_user::add_user_to_role($customer_data['primary_user_id'], $role_id); } // save contact extra data (repeated below for additional contacts) if (isset($contact_extra[0]) && count($contact_extra[0])) { $_REQUEST['extra_user_field'] = array(); foreach ($contact_extra[0] as $key => $val) { $_REQUEST['extra_user_field'][] = array('key' => $key, 'val' => $val); } module_extra::save_extras('user', 'user_id', $customer_data['primary_user_id']); } // save contact groups if (isset($contact_group[0]) && count($contact_group[0])) { foreach ($contact_group[0] as $group_id => $tf) { if ($tf) { module_group::add_to_group($group_id, $customer_data['primary_user_id'], 'user'); } } } } foreach ($contact['email'] as $contact_key => $email) { // add any additional contacts to the customer. $users = module_user::get_contacts(array('email' => $email, 'customer_id' => $customer_id)); if (count($users)) { // this contact already exists for this customer, dont update/change it. continue; } $new_contact = array('customer_id' => $customer_id); foreach ($contact_fields as $primary_contact_field) { $new_contact[$primary_contact_field] = isset($contact[$primary_contact_field][$contact_key]) ? $contact[$primary_contact_field][$contact_key] : ''; } // dont let additional contacts have passwords. if (isset($new_contact['password'])) { unset($new_contact['password']); } if (isset($new_contact['new_password'])) { unset($new_contact['new_password']); } global $plugins; $contact_user_id = $plugins['user']->create_user($new_contact, 'signup'); if ($contact_user_id) { $role_id = module_config::c('customer_signup_role', 0); if ($role_id > 0) { module_user::add_user_to_role($contact_user_id, $role_id); } // save contact extra data (repeated below for primary contacts) if (isset($contact_extra[$contact_key]) && count($contact_extra[$contact_key])) { $_REQUEST['extra_user_field'] = array(); foreach ($contact_extra[$contact_key] as $key => $val) { $_REQUEST['extra_user_field'][] = array('key' => $key, 'val' => $val); } module_extra::save_extras('user', 'user_id', $contact_user_id); } // save contact groups if (isset($contact_group[$contact_key]) && count($contact_group[$contact_key])) { foreach ($contact_group[$contact_key] as $group_id => $tf) { if ($tf) { module_group::add_to_group($group_id, $contact_user_id, 'user'); } } } } } if (count($customer_group)) { // format the address so "save_customer" handles the save for us foreach ($customer_group as $group_id => $tf) { if ($tf) { module_group::add_to_group($group_id, $customer_id, 'customer'); } } } $note_keys = array('customer', 'website', 'job', 'address', 'subscription'); $note_text = _l('Customer signed up from Signup Form:'); $note_text .= "\n\n"; foreach ($note_keys as $note_key) { $note_text .= "\n" . ucwords(_l($note_key)) . "\n"; if (isset($_POST[$note_key]) && is_array($_POST[$note_key])) { foreach ($_POST[$note_key] as $post_key => $post_val) { $note_text .= "\n - " . _l($post_key) . ": "; if (is_array($post_val)) { foreach ($post_val as $p => $v) { $note_text .= "\n - - " . _l($p) . ': ' . $v; } } else { $note_text .= $post_val; } } } } $note_data = array('note_id' => false, 'owner_id' => $customer_id, 'owner_table' => 'customer', 'note_time' => time(), 'note' => $note_text, 'rel_data' => module_customer::link_open($customer_id), 'reminder' => 0, 'user_id' => 0); update_insert('note_id', false, 'note', $note_data); // save customer address fields. if (count($address)) { $address_db = module_address::get_address($customer_id, 'customer', 'physical'); $address_id = $address_db && isset($address_db['address_id']) ? (int) $address_db['address_id'] : false; $address['owner_id'] = $customer_id; $address['owner_table'] = 'customer'; $address['address_type'] = 'physical'; // we have post data to save, write it to the table!! module_address::save_address($address_id, $address); } // website: $allowed = array('url', 'name', 'extra', 'notes'); foreach ($website as $key => $val) { if (!in_array($key, $allowed)) { unset($website[$key]); } } $website['url'] = isset($website['url']) ? strtolower(trim($website['url'])) : ''; $website_id = 0; if (count($website) && class_exists('module_website', false) && module_website::is_plugin_enabled()) { if (strlen($website['url'])) { // see if website already exists, don't create or update existing one for now. $existing_websites = module_website::get_websites(array('customer_id' => $customer_id, 'url' => $website['url'])); foreach ($existing_websites as $existing_website) { $website_id = $existing_website['website_id']; } } // echo $website_id;echo $website['url']; print_r($website_extra);exit; if (!$website_id) { $website_data = module_website::get_website($website_id); $website_data['url'] = isset($website['url']) ? $website['url'] : 'N/A'; $website_data['name'] = isset($website['url']) ? $website['url'] : 'N/A'; $website_data['customer_id'] = $customer_id; $website_id = update_insert('website_id', false, 'website', $website_data); // save website extra data. if ($website_id && count($website_extra)) { $_REQUEST['extra_website_field'] = array(); foreach ($website_extra as $key => $val) { $_REQUEST['extra_website_field'][] = array('key' => $key, 'val' => $val); } module_extra::save_extras('website', 'website_id', $website_id); } if ($website_id && isset($website['notes']) && strlen($website['notes'])) { // add notes to this website. $note_data = array('note_id' => false, 'owner_id' => $website_id, 'owner_table' => 'website', 'note_time' => time(), 'note' => $website['notes'], 'rel_data' => module_website::link_open($website_id), 'reminder' => 0, 'user_id' => $customer_data['primary_user_id']); $note_id = update_insert('note_id', false, 'note', $note_data); } } if ($website_id) { if (count($website_group)) { // format the address so "save_customer" handles the save for us foreach ($website_group as $group_id => $tf) { if ($tf) { module_group::add_to_group($group_id, $website_id, 'website'); } } } } } // generate jobs for this customer. $job_created = array(); if ($job && isset($job['type']) && is_array($job['type'])) { if (module_config::c('customer_signup_any_job_type', 0)) { foreach ($job['type'] as $type_name) { // we have a match in our system. create the job. $job_data = module_job::get_job(false); $job_data['type'] = $type_name; if (!$job_data['name']) { $job_data['name'] = $type_name; } $job_data['website_id'] = $website_id; $job_data['customer_id'] = $customer_id; $job_id = update_insert('job_id', false, 'job', $job_data); // todo: add default tasks for this job type. $job_created[] = $job_id; } } else { foreach (module_job::get_types() as $type_id => $type) { foreach ($job['type'] as $type_name) { if ($type_name == $type) { // we have a match in our system. create the job. $job_data = module_job::get_job(false); $job_data['type'] = $type; if (!$job_data['name']) { $job_data['name'] = $type; } $job_data['website_id'] = $website_id; $job_data['customer_id'] = $customer_id; $job_id = update_insert('job_id', false, 'job', $job_data); // todo: add default tasks for this job type. $job_created[] = $job_id; } } } } if (count($job_created) && count($job_extra)) { // save job extra data. foreach ($job_created as $job_created_id) { if ($job_created_id && count($job_extra)) { $_REQUEST['extra_job_field'] = array(); foreach ($job_extra as $key => $val) { $_REQUEST['extra_job_field'][] = array('key' => $key, 'val' => $val); } module_extra::save_extras('job', 'job_id', $job_created_id); } } } } // save files against customer $uploaded_files = array(); if (isset($_FILES['customerfiles']) && isset($_FILES['customerfiles']['tmp_name'])) { foreach ($_FILES['customerfiles']['tmp_name'] as $file_id => $tmp_file) { if (is_uploaded_file($tmp_file)) { // save to file module for this customer $file_name = basename($_FILES['customerfiles']['name'][$file_id]); if (strlen($file_name)) { $file_path = 'includes/plugin_file/upload/' . md5(time() . $file_name); if (move_uploaded_file($tmp_file, $file_path)) { // success! write to db. $file_data = array('customer_id' => $customer_id, 'job_id' => current($job_created), 'website_id' => $website_id, 'status' => module_config::c('file_default_status', 'Uploaded'), 'pointers' => false, 'description' => "Uploaded from Customer Signup form", 'file_time' => time(), 'file_name' => $file_name, 'file_path' => $file_path, 'file_url' => false); $file_id = update_insert('file_id', false, 'file', $file_data); $uploaded_files[] = $file_id; } } } } } // we create subscriptions for this customer/website (if none already exist) $subscription['subscription_name'] = array(); $subscription['subscription_invoice'] = array(); if (class_exists('module_subscription', false) && module_subscription::is_plugin_enabled() && isset($subscription['for']) && isset($subscription['subscriptions'])) { if ($subscription['for'] == 'website' && $website_id > 0) { $owner_table = 'website'; $owner_id = $website_id; } else { $owner_table = 'customer'; $owner_id = $customer_id; } $available_subscriptions = module_subscription::get_subscriptions(); $members_subscriptions = module_subscription::get_subscriptions_by($owner_table, $owner_id); foreach ($subscription['subscriptions'] as $subscription_id => $tf) { if (isset($available_subscriptions[$subscription_id])) { if (isset($members_subscriptions[$subscription_id])) { // we don't allow a member to sign up to the same subscription twice (just yet) } else { $subscription['subscription_name'][$subscription_id] = $available_subscriptions[$subscription_id]['name']; $start_date = date('Y-m-d'); $start_modifications = module_config::c('customer_signup_subscription_start', ''); if ($start_modifications == 'hidden') { $start_modifications = isset($_REQUEST['customer_signup_subscription_start']) ? $_REQUEST['customer_signup_subscription_start'] : ''; } if (!empty($start_modifications)) { $start_date = date('Y-m-d', strtotime($start_modifications)); } $sql = "INSERT INTO `" . _DB_PREFIX . "subscription_owner` SET "; $sql .= " owner_id = '" . (int) $owner_id . "'"; $sql .= ", owner_table = '" . mysql_real_escape_string($owner_table) . "'"; $sql .= ", subscription_id = '" . (int) $subscription_id . "'"; $sql .= ", start_date = '{$start_date}'"; query($sql); module_subscription::update_next_due_date($subscription_id, $owner_table, $owner_id, true); // and the same option here to send a subscription straight away upon signup if (module_config::c('subscription_send_invoice_straight_away', 0)) { global $plugins; $plugins['subscription']->run_cron(); // check if there are any invoices for this subscription $history = module_subscription::get_subscription_history($subscription_id, $owner_table, $owner_id); if (count($history) > 0) { foreach ($history as $h) { if ($h['invoice_id']) { $invoice_data = module_invoice::get_invoice($h['invoice_id']); if ($invoice_data['date_cancel'] != '0000-00-00') { continue; } $subscription['subscription_invoice'][] = '<a href="' . module_invoice::link_public($h['invoice_id']) . '">' . _l('Invoice #%s for %s', htmlspecialchars($invoice_data['name']), dollar($invoice_data['total_amount'], true, $invoice_data['currency_id'])) . '</a>'; } } } } } } } } if (!count($subscription['subscription_name'])) { $subscription['subscription_name'][] = _l('N/A'); } if (!count($subscription['subscription_invoice'])) { $subscription['subscription_invoice'][] = _l('N/A'); } $subscription['subscription_name'] = implode(', ', $subscription['subscription_name']); $subscription['subscription_invoice'] = implode(', ', $subscription['subscription_invoice']); // email the admin when a customer signs up. $values = array_merge($customer, $customer_extra, $website, $website_extra, $address, $subscription); $values['customer_name'] = $customer['customer_name']; $values['CUSTOMER_LINK'] = module_customer::link_open($customer_id); $values['CUSTOMER_NAME_LINK'] = module_customer::link_open($customer_id, true); if ($website_id) { $values['WEBSITE_LINK'] = module_website::link_open($website_id); $values['WEBSITE_NAME_LINK'] = module_website::link_open($website_id, true); } else { $values['WEBSITE_LINK'] = _l('N/A'); $values['WEBSITE_NAME_LINK'] = _l('N/A'); } $values['JOB_LINKS'] = ''; if (count($job_created)) { $values['JOB_LINKS'] .= 'The customer created ' . count($job_created) . ' jobs in the system: <br>'; foreach ($job_created as $job_created_id) { $values['JOB_LINKS'] .= module_job::link_open($job_created_id, true) . "<br>\n"; } } else { $values['JOB_LINKS'] = _l('N/A'); } if (count($uploaded_files)) { $values['uploaded_files'] = 'The customer uploaded ' . count($uploaded_files) . " files:<br>\n"; foreach ($uploaded_files as $uploaded_file) { $values['uploaded_files'] .= module_file::link_open($uploaded_file, true) . "<br>\n"; } } else { $values['uploaded_files'] = 'No files were uploaded'; } $values['WEBSITE_NAME'] = isset($website['url']) ? $website['url'] : 'N/A'; if (!$creating_new) { $values['system_note'] = "Note: this signup updated the existing customer record in the system."; } else { $values['system_note'] = "Note: this signup created a new customer record in the system."; } $customer_signup_template = module_config::c('customer_signup_email_admin_template', 'customer_signup_email_admin'); if (isset($_REQUEST['customer_signup_email_admin_template'])) { $customer_signup_template = $_REQUEST['customer_signup_email_admin_template']; } if ($customer_signup_template) { $template = module_template::get_template_by_key($customer_signup_template); if ($template->template_id) { $template->assign_values($values); $html = $template->render('html'); $email = module_email::new_email(); $email->replace_values = $values; $email->set_subject($template->description); $email->set_to_manual(module_config::c('customer_signup_admin_email', module_config::c('admin_email_address'))); // do we send images inline? $email->set_html($html); if ($email->send()) { // it worked successfully!! } else { /// log err? } } } $customer_signup_template = module_config::c('customer_signup_email_welcome_template', 'customer_signup_email_welcome'); if (isset($_REQUEST['customer_signup_email_welcome_template'])) { $customer_signup_template = $_REQUEST['customer_signup_email_welcome_template']; } if ($customer_signup_template) { $template = module_template::get_template_by_key($customer_signup_template); if ($template->template_id) { $template->assign_values($values); $html = $template->render('html'); $email = module_email::new_email(); $email->customer_id = $customer_id; $email->replace_values = $values; $email->set_subject($template->description); $email->set_to('user', $customer_data['primary_user_id']); // do we send images inline? $email->set_html($html); if ($email->send()) { // it worked successfully!! } else { /// log err? } } } //todo: optional redirect to url if (isset($_REQUEST['via_ajax'])) { echo json_encode(array('success' => 1, 'customer_id' => $customer_id)); exit; } if (module_config::c('customer_signup_redirect', '')) { redirect_browser(module_config::c('customer_signup_redirect', '')); } // load up the thank you template. $template = module_template::get_template_by_key('customer_signup_thank_you_page'); $template->page_title = _l("Customer Signup"); foreach ($values as $key => $val) { if (!is_array($val)) { $values[$key] = htmlspecialchars($val); } } $template->assign_values($values); echo $template->render('pretty_html'); exit; break; } }
public static function get_statistics_subscription($search) { $subscriptions = module_subscription::get_subscriptions(); $return = array(); foreach ($subscriptions as $subscription) { $return[$subscription['subscription_id']] = $subscription; $return[$subscription['subscription_id']]['total_received'] = 0; $return[$subscription['subscription_id']]['total_received_count'] = 0; $return[$subscription['subscription_id']]['total_unpaid'] = 0; $return[$subscription['subscription_id']]['total_unpaid_count'] = 0; $return[$subscription['subscription_id']]['members'] = array(); $return[$subscription['subscription_id']]['customers'] = array(); // find all subscription_history's between these days $sql = "SELECT * "; $sql .= " FROM `" . _DB_PREFIX . "invoice` i"; $sql .= " RIGHT JOIN `" . _DB_PREFIX . "subscription_history` sh ON i.invoice_id = sh.invoice_id "; $sql .= " WHERE sh.subscription_id = " . (int) $subscription['subscription_id']; if (isset($search['date_from']) && $search['date_from']) { $sql .= " AND i.date_create >= '" . input_date($search['date_from']) . "'"; } if (isset($search['date_to']) && $search['date_to']) { $sql .= " AND i.date_create <= '" . input_date($search['date_to']) . "'"; } $res = qa($sql); // this is a list of invoices for these subscriptions from these date periods. //print_r($res); return; foreach ($res as $r) { $invoice = module_invoice::get_invoice($r['invoice_id']); $return[$subscription['subscription_id']]['total_received'] += $invoice['total_amount_paid']; if ($invoice['total_amount_paid'] > 0) { $return[$subscription['subscription_id']]['total_received_count']++; } $return[$subscription['subscription_id']]['total_unpaid'] += $invoice['total_amount_due']; if ($invoice['total_amount_due'] > 0) { $return[$subscription['subscription_id']]['total_unpaid_count']++; } if ($r['customer_id']) { if (!isset($return[$subscription['subscription_id']]['customers'][$r['customer_id']])) { $return[$subscription['subscription_id']]['customers'][$r['customer_id']] = array('customer_id' => $r['customer_id'], 'received_payments' => 0, 'unpaid_payments' => 0, 'received_total' => 0, 'unpaid_total' => 0); } if ($invoice['total_amount_paid'] > 0) { $return[$subscription['subscription_id']]['customers'][$r['customer_id']]['received_payments']++; } if ($invoice['total_amount_due'] > 0) { $return[$subscription['subscription_id']]['customers'][$r['customer_id']]['unpaid_payments']++; } $return[$subscription['subscription_id']]['customers'][$r['customer_id']]['received_total'] += $invoice['total_amount_paid']; $return[$subscription['subscription_id']]['customers'][$r['customer_id']]['unpaid_total'] += $invoice['total_amount_due']; } if ($r['member_id']) { if (!isset($return[$subscription['subscription_id']]['members'][$r['member_id']])) { $return[$subscription['subscription_id']]['members'][$r['member_id']] = array('member_id' => $r['member_id'], 'received_payments' => 0, 'unpaid_payments' => 0, 'received_total' => 0, 'unpaid_total' => 0); } if ($invoice['total_amount_paid'] > 0) { $return[$subscription['subscription_id']]['members'][$r['member_id']]['received_payments']++; } if ($invoice['total_amount_due'] > 0) { $return[$subscription['subscription_id']]['members'][$r['member_id']]['unpaid_payments']++; } $return[$subscription['subscription_id']]['members'][$r['member_id']]['received_total'] += $invoice['total_amount_paid']; $return[$subscription['subscription_id']]['members'][$r['member_id']]['unpaid_total'] += $invoice['total_amount_due']; } } } return $return; }
public static function start_payment($invoice_id, $payment_amount, $invoice_payment_id, $user_id = false) { if ($invoice_id && $payment_amount && $invoice_payment_id) { // we are starting a payment via google! // setup a pending payment and redirect to google. // save some initial data into this payment record. self::add_payment_data($invoice_payment_id, 'redirect_time', time()); $invoice_data = module_invoice::get_invoice($invoice_id); if (!$user_id) { $user_id = $invoice_data['user_id']; } if (!$user_id) { $user_id = module_security::get_loggedin_id(); } $description = _l('Payment for invoice %s', $invoice_data['name']); self::google_redirect($description, $payment_amount, $user_id, $invoice_payment_id, $invoice_id, $invoice_data['currency_id']); return true; } return false; }
<?php /** * Copyright: dtbaker 2012 * Licence: Please check CodeCanyon.net for licence details. * More licence clarification available here: http://codecanyon.net/wiki/support/legal-terms/licensing-terms/ * Deploy: 9809 f200f46c2a19bb98d112f2d32a8de0c4 * Envato: 4ffca17e-861e-4921-86c3-8931978c40ca * Package Date: 2015-11-25 02:55:20 * IP Address: 67.79.165.254 */ if (!$invoice_safe) { die('failed'); } $invoice_id = (int) $_REQUEST['invoice_id']; $invoice = module_invoice::get_invoice($invoice_id); if (class_exists('module_company', false) && isset($invoice['company_id']) && (int) $invoice['company_id'] > 0) { module_company::set_current_company_id($invoice['company_id']); } // template for sending emails. // are we sending the paid one? or the dueone. $original_template_name = $template_name = ''; $template_name = ''; $template_prefix = isset($invoice['invoice_template_email']) && strlen($invoice['invoice_template_email']) ? $invoice['invoice_template_email'] : 'invoice_email'; if (isset($invoice['credit_note_id']) && $invoice['credit_note_id']) { $original_template_name = $template_name = 'credit_note_email'; } else { if ($invoice['date_paid'] && $invoice['date_paid'] != '0000-00-00') { $original_template_name = $template_name = $template_prefix . '_paid'; } else { if ($invoice['overdue'] && $invoice['date_sent'] && $invoice['date_sent'] != '0000-00-00') {
_e('Total Received'); ?> </th> <th><?php _e('Total Unpaid'); ?> </th> </tr> </thead> <?php foreach ($subscribed_owners as $subscribed_customer) { $history = module_subscription::get_subscription_history($subscription_id, $subscribed_customer['owner_table'], $subscribed_customer['owner_id']); $total_paid = $total_unpaid = array(); foreach ($history as $h_id => $h) { if ($h['invoice_id']) { $invoice = module_invoice::get_invoice($h['invoice_id'], true); if ($invoice['date_cancel'] && $invoice['date_cancel'] != '0000-00-00') { // invoice cancelled, ignore from listing unset($history[$h_id]); continue; } if ($h['paid_date'] && $h['paid_date'] != '0000-00-00') { if (!isset($total_paid[$invoice['currency_id']])) { $total_paid[$invoice['currency_id']] = 0; } $total_paid[$invoice['currency_id']] += $h['amount']; } } if (!$h['paid_date'] || $h['paid_date'] == '0000-00-00') { if (!isset($total_unpaid[$subscription['currency_id']])) { $total_unpaid[$subscription['currency_id']] = 0;
private static function _format_invoice_payment($invoice_payment_data, $finance_data) { if (isset($invoice_payment_data['invoice_payment_id']) && $invoice_payment_data['invoice_payment_id'] > 0 && isset($invoice_payment_data['invoice_id']) && $invoice_payment_data['invoice_id'] > 0) { $invoice_data = module_invoice::get_invoice($invoice_payment_data['invoice_id']); $invoice_payment_data['url'] = module_finance::link_open('new', false) . '&invoice_payment_id=' . $invoice_payment_data['invoice_payment_id']; if ($invoice_payment_data['amount'] < 0 && (isset($invoice_payment_data['payment_type']) && $invoice_payment_data['payment_type'] == _INVOICE_PAYMENT_TYPE_OVERPAYMENT_CREDIT)) { $invoice_payment_data['name'] = !isset($invoice_payment_data['name']) ? _l('Assigning Credit') : $invoice_payment_data['name']; $invoice_payment_data['description'] = !isset($invoice_payment_data['description']) ? _l('Assigning Overpayment Credit from invoice <a href="%s">#%s</a>', module_invoice::link_open($invoice_payment_data['invoice_id'], false), $invoice_data['name'], $invoice_payment_data['method']) : $invoice_payment_data['description']; // refund $invoice_payment_data['amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['debit'] = abs($invoice_payment_data['amount']); $invoice_payment_data['sub_amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['taxable_amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['credit'] = 0; $invoice_payment_data['type'] = 'e'; } else { if ($invoice_payment_data['amount'] < 0 || isset($invoice_payment_data['payment_type']) && $invoice_payment_data['payment_type'] == _INVOICE_PAYMENT_TYPE_REFUND) { $invoice_payment_data['name'] = !isset($invoice_payment_data['name']) ? _l('Invoice Refund') : $invoice_payment_data['name']; $invoice_payment_data['description'] = !isset($invoice_payment_data['description']) ? _l('Refund against invoice <a href="%s">#%s</a> via "%s" method', module_invoice::link_open($invoice_payment_data['invoice_id'], false), $invoice_data['name'], $invoice_payment_data['method']) : $invoice_payment_data['description']; // refund $invoice_payment_data['amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['debit'] = abs($invoice_payment_data['amount']); $invoice_payment_data['sub_amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['taxable_amount'] = abs($invoice_payment_data['amount']); $invoice_payment_data['credit'] = 0; $invoice_payment_data['type'] = 'e'; } else { $invoice_payment_data['name'] = !isset($invoice_payment_data['name']) ? _l('Invoice Payment') : $invoice_payment_data['name']; $invoice_payment_data['description'] = !isset($invoice_payment_data['description']) ? _l('Payment against invoice <a href="%s">#%s</a> via "%s" method', module_invoice::link_open($invoice_payment_data['invoice_id'], false), $invoice_data['name'], $invoice_payment_data['method']) : $invoice_payment_data['description']; $invoice_payment_data['credit'] = $invoice_payment_data['amount']; $invoice_payment_data['sub_amount'] = $invoice_payment_data['amount']; $invoice_payment_data['taxable_amount'] = $invoice_payment_data['amount']; $invoice_payment_data['debit'] = 0; $invoice_payment_data['type'] = 'i'; } } if (isset($invoice_payment_data['data']) && strlen($invoice_payment_data['data'])) { $details = @unserialize($invoice_payment_data['data']); if ($details && isset($details['custom_notes']) && strlen($details['custom_notes'])) { $invoice_payment_data['description'] .= " \n(" . $details['custom_notes'] . ')'; } } $invoice_payment_data['account_name'] = ''; $invoice_payment_data['categories'] = ''; if (module_config::c('finance_date_type', 'payment') == 'invoice') { $invoice_payment_data['transaction_date'] = $invoice_data['date_create']; } else { $invoice_payment_data['transaction_date'] = $invoice_payment_data['date_paid']; } $invoice_payment_data['invoice_name'] = $invoice_data['name']; $invoice_payment_data['taxes'] = $invoice_data['taxes']; // calculate the sub amount based on taxes. if ($invoice_payment_data['amount'] >= $invoice_data['total_amount']) { // user overpaid this invoice amount. // check if there hasn't been any refunds or anything or assigning deposits. } else { if ($invoice_payment_data['amount'] == $invoice_data['total_amount']) { // then we can work out any sub non taxable items. if ($invoice_data['total_tax'] > 0) { //$finance['sub_amount'] = $finance['amount'] - $invoice_data['total_tax']; // todo: cache these and do a get_invoice basic above so we don't calculate each time. $invoice_payment_data['sub_amount'] = $invoice_data['total_sub_amount']; $invoice_payment_data['taxable_amount'] = $invoice_data['total_sub_amount_taxable']; } } else { // todo: average out the difference between invoice payments and the total amount? spread the tax over all payments maybe? if (count($invoice_payment_data['taxes'])) { $tax_percents = 0; $increment = false; foreach ($invoice_payment_data['taxes'] as $tax_id => $tax) { if ($tax['increment']) { $increment = true; } } foreach ($invoice_payment_data['taxes'] as $tax_id => $tax) { // the 'amount' of tax here will be incorrect, because this is a part payment against an invoice // the 'amount' in here is the FULL amount of tax that has been charged against the invoice $invoice_payment_data['taxes'][$tax_id]['amount'] = 0; if ($increment) { $invoice_payment_data['taxable_amount'] = $invoice_payment_data['taxable_amount'] / (1 + $tax['percent'] / 100); } else { $tax_percents += $tax['percent'] / 100; } } $invoice_payment_data['taxable_amount'] = round($invoice_payment_data['taxable_amount'] / (1 + $tax_percents) * 100, 2) / 100; $invoice_payment_data['sub_amount'] = $invoice_payment_data['taxable_amount']; } } } $new_finance = hook_handle_callback('finance_invoice_listing', $invoice_payment_data['invoice_id'], $finance_data); if (is_array($new_finance) && count($new_finance)) { foreach ($new_finance as $n) { $invoice_payment_data = array_merge($invoice_payment_data, $n); } } } return $invoice_payment_data; }
function customer_admin_email_generate_invoice_list($invoices, $customer_id) { ob_start(); $colspan = 9; $colspan2 = 0; $invoice_total = array(); $invoice_total_due = array(); foreach ($invoices as $invoice) { if (!isset($invoice_total[$invoice['currency_id']])) { $invoice_total[$invoice['currency_id']] = 0; } if ($invoice['c_total_amount'] == 0) { $invoice = module_invoice::get_invoice($invoice['invoice_id']); } $invoice_total[$invoice['currency_id']] += $invoice['c_total_amount']; if (!isset($invoice_total_due[$invoice['currency_id']])) { $invoice_total_due[$invoice['currency_id']] = 0; } $invoice_total_due[$invoice['currency_id']] += $invoice['c_total_amount_due']; } $table_manager = module_theme::new_table_manager(); $columns = array(); $columns['invoice_number'] = array('title' => 'Invoice Number', 'callback' => function ($invoice) { //echo module_invoice::link_open($invoice['invoice_id'],true,$invoice); echo '<a href="' . module_invoice::link_public($invoice['invoice_id']) . '">' . htmlspecialchars($invoice['name']) . '</a>'; }, 'cell_class' => 'row_action'); $columns['invoice_status'] = array('title' => 'Status', 'callback' => function ($invoice) { echo htmlspecialchars($invoice['status']); }); $columns['invoice_create_date'] = array('title' => 'Create Date', 'callback' => function ($invoice) { if (!$invoice['date_create'] || $invoice['date_create'] == '0000-00-00') { //echo print_date($invoice['date_created']); } else { echo print_date($invoice['date_create']); } }); $columns['invoice_due_date'] = array('title' => 'Due Date', 'callback' => function ($invoice) { if ((!$invoice['date_paid'] || $invoice['date_paid'] == '0000-00-00') && strtotime($invoice['date_due']) < time()) { echo '<span class="error_text">'; echo print_date($invoice['date_due']); echo '</span>'; } else { echo print_date($invoice['date_due']); } }); $columns['invoice_sent_date'] = array('title' => 'Sent Date', 'callback' => function ($invoice) { if ($invoice['date_sent'] && $invoice['date_sent'] != '0000-00-00') { ?> <?php echo print_date($invoice['date_sent']); ?> <?php } else { ?> <span class="error_text"><?php _e('Not sent'); ?> </span> <?php } }); $columns['invoice_paid_date'] = array('title' => 'Paid Date', 'callback' => function ($invoice) { if ($invoice['date_paid'] && $invoice['date_paid'] != '0000-00-00') { ?> <?php echo print_date($invoice['date_paid']); ?> <?php } else { if ($invoice['date_cancel'] && $invoice['date_cancel'] != '0000-00-00') { ?> <span class="error_text"><?php _e('Cancelled'); ?> </span> <?php } else { if ($invoice['overdue']) { ?> <span class="error_text" style="font-weight: bold; text-decoration: underline;"><?php _e('Overdue'); ?> </span> <?php } else { ?> <span class="error_text"><?php _e('Not paid'); ?> </span> <?php } } } }); if (class_exists('module_website', false) && module_website::is_plugin_enabled() && module_website::can_i('view', module_config::c('project_name_plural', 'Websites'))) { $colspan++; $columns['invoice_website'] = array('title' => module_config::c('project_name_single', 'Website'), 'callback' => function ($invoice) { if (isset($invoice['website_ids'])) { foreach ($invoice['website_ids'] as $website_id) { if ((int) $website_id > 0) { echo module_website::link_open($website_id, true); echo '<br/>'; } } } }); } $columns['invoice_job'] = array('title' => 'Job', 'callback' => function ($invoice) { foreach ($invoice['job_ids'] as $job_id) { if ((int) $job_id > 0) { //echo module_job::link_open($job_id,true); $job_data = module_job::get_job($job_id); echo '<a href="' . module_job::link_public($job_id) . '">' . htmlspecialchars($job_data['name']) . '</a>'; if ($job_data['date_start'] && $job_data['date_start'] != '0000-00-00' && $job_data['date_renew'] && $job_data['date_renew'] != '0000-00-00') { _e(' (%s to %s)', print_date($job_data['date_start']), print_date(strtotime("-1 day", strtotime($job_data['date_renew'])))); } echo "<br/>\n"; } } hook_handle_callback('invoice_admin_list_job', $invoice['invoice_id']); }); if (!isset($_REQUEST['customer_id']) && module_customer::can_i('view', 'Customers')) { $colspan++; $columns['invoice_customer'] = array('title' => 'Customer', 'callback' => function ($invoice) { echo module_customer::link_open($invoice['customer_id'], true); }); } $columns['c_invoice_total'] = array('title' => 'Invoice Total', 'callback' => function ($invoice) { echo dollar($invoice['total_amount'], true, $invoice['currency_id']); }); $columns['c_invoice_total_due'] = array('title' => 'Amount Due', 'callback' => function ($invoice) { echo dollar($invoice['total_amount_due'], true, $invoice['currency_id']); ?> <?php if ($invoice['total_amount_credit'] > 0) { ?> <span class="success_text"><?php echo _l('Credit: %s', dollar($invoice['total_amount_credit'], true, $invoice['currency_id'])); ?> </span> <?php } }); if (class_exists('module_extra', false)) { ob_start(); $colspan2 += module_extra::print_table_header('invoice'); // used in the footer calc. ob_end_clean(); $table_manager->display_extra('invoice', function ($invoice) { module_extra::print_table_data('invoice', $invoice['invoice_id']); }); } $table_manager->set_columns($columns); $table_manager->row_callback = function ($row_data) { // load the full vendor data before displaying each row so we have access to more details if (isset($row_data['invoice_id']) && (int) $row_data['invoice_id'] > 0) { return module_invoice::get_invoice($row_data['invoice_id']); } return array(); }; $table_manager->set_rows($invoices); if (module_config::c('invoice_list_show_totals', 1)) { $footer_rows = array(); foreach ($invoice_total + $invoice_total_due as $currency_id => $foo) { $currency = get_single('currency', 'currency_id', $currency_id); $footer_rows[] = array('invoice_number' => array('data' => '<strong>' . _l('%s Totals:', $currency && isset($currency['code']) ? $currency['code'] : '') . '</strong>', 'cell_colspan' => $colspan - 2, 'cell_class' => 'text-right'), 'c_invoice_total' => array('data' => '<strong>' . dollar(isset($invoice_total[$currency_id]) ? $invoice_total[$currency_id] : 0, true, $currency_id) . '</strong>'), 'c_invoice_total_due' => array('data' => '<strong>' . dollar(isset($invoice_total_due[$currency_id]) ? $invoice_total_due[$currency_id] : 0, true, $currency_id) . '</strong>'), 'row_bulk_action' => array('data' => ' ', 'cell_colspan' => $colspan2)); } $table_manager->set_footer_rows($footer_rows); } $table_manager->pagination = false; $table_manager->print_table(); return ob_get_clean(); }
function handle_hook($hook, $calling_module = false, $owner_table = false, $key_name = false, $key_value = false, $rel_data = false) { switch ($hook) { case "home_alerts": $alerts = array(); if (module_config::c('allow_note_reminders', 1)) { // find any jobs that are past the due date and dont have a finished date. $key = _l('Note Reminder'); if (class_exists('module_dashboard', false)) { module_dashboard::register_group($key, array('columns' => array('name' => _l('Reminder'), 'type' => _l('Type'), 'full_link' => _l('Link'), 'date' => _l('Date'), 'days' => _l('Date')))); } $sql = "SELECT * FROM `" . _DB_PREFIX . "note` n "; $sql .= " WHERE n.`reminder` = 1 AND n.note_time < " . (int) strtotime('+' . module_config::c('alert_days_in_future', 5) . ' days') . ""; $sql .= " AND ( n.`user_id` = 0 OR n.`user_id` = " . module_security::get_loggedin_id() . ")"; $sql .= " ORDER BY n.note_time ASC"; $tasks = qa($sql); foreach ($tasks as $task) { $alert_res = process_alert(date('Y-m-d', $task['note_time']), $key); if ($alert_res) { $alert_res['link'] = $task['rel_data']; // fix for linking when changing folder. $alert_res['type'] = _l(ucwords($task['owner_table'])); switch ($task['owner_table']) { case 'user': $user = module_user::get_user($task['owner_id']); if ($user['customer_id'] || $user['vendor_id']) { $alert_res['link'] = module_user::link_open_contact($task['owner_id'], false, $user); $alert_res['full_link'] = module_user::link_open_contact($task['owner_id'], true, $user); $alert_res['type'] = _l('Contact'); } else { $alert_res['link'] = module_user::link_open($task['owner_id'], false, $user); $alert_res['full_link'] = module_user::link_open($task['owner_id'], true, $user); } break; case 'invoice': $invoice_data = module_invoice::get_invoice($task['owner_id'], true); if (!$invoice_data || !isset($invoice_data['invoice_id']) || $invoice_data['invoice_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_invoice::link_open($task['owner_id'], false, $invoice_data); $alert_res['full_link'] = module_invoice::link_open($task['owner_id'], true, $invoice_data); break; case 'quote': $quote_data = module_quote::get_quote($task['owner_id'], true); if (!$quote_data || !isset($quote_data['quote_id']) || $quote_data['quote_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_quote::link_open($task['owner_id'], false, $quote_data); $alert_res['full_link'] = module_quote::link_open($task['owner_id'], true, $quote_data); break; case 'website': $website_data = module_website::get_website($task['owner_id']); if (!$website_data || !isset($website_data['website_id']) || $website_data['website_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_website::link_open($task['owner_id'], false); $alert_res['full_link'] = module_website::link_open($task['owner_id'], true); break; case 'customer': $customer_data = module_customer::get_customer($task['owner_id']); if (!$customer_data || !isset($customer_data['customer_id']) || $customer_data['customer_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_customer::link_open($task['owner_id'], false, $customer_data); $alert_res['full_link'] = module_customer::link_open($task['owner_id'], true, $customer_data); break; case 'vendor': $vendor_data = module_vendor::get_vendor($task['owner_id']); if (!$vendor_data || !isset($vendor_data['vendor_id']) || $vendor_data['vendor_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_vendor::link_open($task['owner_id'], false, $vendor_data); $alert_res['full_link'] = module_vendor::link_open($task['owner_id'], true, $vendor_data); break; case 'job': $job_data = module_job::get_job($task['owner_id']); if (!$job_data || !isset($job_data['job_id']) || $job_data['job_id'] != $task['owner_id']) { continue 2; } $alert_res['link'] = module_job::link_open($task['owner_id'], false, $job_data); $alert_res['full_link'] = module_job::link_open($task['owner_id'], true, $job_data); break; // todo - add others. } $alert_res['name'] = $task['note']; $alert_res['date'] = print_date($alert_res['date']); $alert_res['time'] = $task['note_time']; $alerts[] = $alert_res; } } } return $alerts; break; /*case "note_list": if($owner_id && $owner_id != 'new'){ $note_items = $this->get_notes(array("owner_table"=>$owner_table,"owner_id"=>$owner_id)); foreach($note_items as &$note_item){ // do it in loop here because of $this issues in static method below. // instead of include file below. $note_item['html'] = $this->print_note($note_item['note_id']); } include("pages/note_list.php"); }else{ echo 'Please save first before creating notes.'; } break;*/ /*case "note_list": if($owner_id && $owner_id != 'new'){ $note_items = $this->get_notes(array("owner_table"=>$owner_table,"owner_id"=>$owner_id)); foreach($note_items as &$note_item){ // do it in loop here because of $this issues in static method below. // instead of include file below. $note_item['html'] = $this->print_note($note_item['note_id']); } include("pages/note_list.php"); }else{ echo 'Please save first before creating notes.'; } break;*/ case "note_delete": // find the key we are saving this address against. $owner_id = (int) $key_value; if (!$owner_id || $owner_id == 'new') { // find one in the post data. if (isset($_REQUEST[$key_name])) { $owner_id = $_REQUEST[$key_name]; } } $note_hash = md5($owner_id . '|' . $owner_table); // just for posting unique arrays. if ($owner_table && $owner_id) { $this->note_delete($owner_table, $owner_id); } break; } }
public function external_hook($hook) { switch ($hook) { case 'pay': // result is retured via ajax and displayed on the page. $invoice_id = isset($_REQUEST['invoice_id']) ? $_REQUEST['invoice_id'] : false; $invoice_payment_id = isset($_REQUEST['invoice_payment_id']) ? $_REQUEST['invoice_payment_id'] : false; if ($invoice_id && $invoice_payment_id) { $invoice_payment_data = module_invoice::get_invoice_payment($invoice_payment_id); $invoice_data = module_invoice::get_invoice($invoice_id); if ($invoice_payment_data && $invoice_data && $invoice_id == $invoice_data['invoice_id'] && $invoice_payment_data['invoice_id'] == $invoice_data['invoice_id']) { $currency = module_config::get_currency($invoice_payment_data['currency_id']); $currency_code = $currency['code']; $description = _l('Payment for invoice %s', $invoice_data['name']); require_once 'includes/plugin_paymethod_authorize/anet_php_1.1.8/AuthorizeNet.php'; $transaction = new AuthorizeNetAIM(module_config::c('payment_method_authorize_api_login_id', ''), module_config::c('payment_method_authorize_transaction_key', '')); $transaction->setSandbox(module_config::c('payment_method_authorize_sandbox', 0)); $transaction->VERIFY_PEER = module_config::c('payment_method_authorize_ssl_verify', 1); $transaction->amount = $invoice_payment_data['amount']; // USD ONLY foreach (array("address", "allow_partial_auth", "amount", "auth_code", "authentication_indicator", "bank_aba_code", "bank_acct_name", "bank_acct_num", "bank_acct_type", "bank_check_number", "bank_name", "card_code", "card_num", "cardholder_authentication_value", "city", "company", "country", "cust_id", "customer_ip", "delim_char", "delim_data", "description", "duplicate_window", "duty", "echeck_type", "email", "email_customer", "encap_char", "exp_date", "fax", "first_name", "footer_email_receipt", "freight", "header_email_receipt", "invoice_num", "last_name", "line_item", "login", "method", "phone", "po_num", "recurring_billing", "relay_response", "ship_to_address", "ship_to_city", "ship_to_company", "ship_to_country", "ship_to_first_name", "ship_to_last_name", "ship_to_state", "ship_to_zip", "split_tender_id", "state", "tax", "tax_exempt", "test_request", "tran_key", "trans_id", "type", "version", "zip") as $possible_value) { if (isset($_POST[$possible_value])) { $transaction->setField($possible_value, $_POST[$possible_value]); } } $transaction->setField('card_num', isset($_POST['number']) ? $_POST['number'] : ''); $transaction->setField('exp_date', $_POST['month'] . '/' . $_POST['year']); $transaction->setField('card_code', $_POST['cvv']); //$transaction->card_num = isset($_POST['number']) ? $_POST['number'] : ''; //$transaction->exp_date = $_POST['month'].'/'.$_POST['year']; //$transaction->card_code = $_POST['cvv']; $response = $transaction->authorizeAndCapture(); if ($response->approved) { // echo "<h1>Success! The test credit card has been charged!</h1>"; // echo "Transaction ID: " . $response->transaction_id; update_insert("invoice_payment_id", $invoice_payment_id, "invoice_payment", array('date_paid' => date('Y-m-d'))); module_paymethod_stripe::add_payment_data($invoice_payment_id, 'log', "Successfully paid: " . var_export($response, true)); module_invoice::save_invoice($invoice_id, array()); // success! // redirect to receipt page. redirect_browser(module_invoice::link_receipt($invoice_payment_id)); } else { echo isset($response->error_message) ? $response->error_message : (isset($response->response_reason_text) ? $response->response_reason_text : var_export($response, true)); } exit; } } echo 'Error paying via Authorize'; exit; } }