function get_competitor_products($json) { $json = json_decode($json, true); $i = 0; foreach ($json['items'] as $item) { $query = build_query($item); $price = $item['price']; $competitor = find_product($query, $price); $json['items'][$i] = array_merge($item, $competitor); $i++; } return json_encode($json); }
/** * Show my invoices. * * @return tempcode The interface. */ function pay() { $id = get_param_integer('id'); if (!tacit_https() && !ecommerce_test_mode()) { warn_exit(do_lang_tempcode('NO_SSL_SETUP')); } $title = get_page_title('MAKE_PAYMENT'); $post_url = build_url(array('page' => 'purchase', 'type' => 'finish'), get_module_zone('purchase')); $rows = $GLOBALS['SITE_DB']->query_select('invoices', array('*'), array('id' => $id), '', 1); if (!array_key_exists(0, $rows)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $row = $rows[0]; $product = $row['i_type_code']; $object = find_product($product); $products = $object->get_products(false, $product); $invoice_title = $products[$product][4]; list($fields, $hidden) = get_transaction_form_fields(NULL, strval($id), $invoice_title, float_to_raw_string($row['i_amount']), NULL, ''); $text = do_lang_tempcode('TRANSACT_INFO'); return do_template('FORM_SCREEN', array('_GUID' => 'e90a4019b37c8bf5bcb64086416bcfb3', 'TITLE' => $title, 'SKIP_VALIDATION' => '1', 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => $text, 'HIDDEN' => $hidden, 'SUBMIT_NAME' => do_lang_tempcode('MAKE_PAYMENT'))); }
/** * Actualiser to add an invoice. * * @return tempcode The interface. */ function _ad() { $title = get_page_title('CREATE_INVOICE'); breadcrumb_set_self(do_lang_tempcode('DONE')); breadcrumb_set_parents(array(array('_SEARCH:admin_ecommerce:ecom_usage', do_lang_tempcode('ECOMMERCE')), array('_SELF:_SELF:misc', do_lang_tempcode('INVOICES')), array('_SELF:_SELF:ad', do_lang_tempcode('CREATE_INVOICE')))); $product = post_param('product'); $object = find_product($product); $amount = post_param('amount', ''); if ($amount == '') { $products = $object->get_products(false, $product); $amount = $products[$product][1]; if ($amount == '?') { warn_exit(do_lang_tempcode('INVOICE_REQUIRED_AMOUNT')); } } $to = post_param('to'); $member_id = $GLOBALS['FORUM_DRIVER']->get_member_from_username($to); if (is_null($member_id)) { warn_exit(do_lang_tempcode('_USER_NO_EXIST', $to)); } $id = $GLOBALS['SITE_DB']->query_insert('invoices', array('i_type_code' => $product, 'i_member_id' => $member_id, 'i_state' => 'new', 'i_amount' => $amount, 'i_special' => post_param('special'), 'i_time' => time(), 'i_note' => post_param('note')), true); log_it('CREATE_INVOICE', strval($id), $product); send_invoice_mail($member_id, $id); $url = build_url(array('page' => '_SELF', 'type' => 'outstanding'), '_SELF'); return redirect_screen($title, $url, do_lang_tempcode('SUCCESS')); }
/** * Finish step. * * @return tempcode The result of execution. */ function finish() { $title = get_page_title('_PURCHASE_FINISHED'); breadcrumb_set_parents(array(array('_SELF:catalogues:misc:ecommerce=1', do_lang_tempcode('CATALOGUES')), array('_SELF:_SELF:misc', do_lang_tempcode('SHOPPING')))); $message = get_param('message', NULL, true); // TODO: Assumption, needs to really go through the payment gateway API if (get_param_integer('cancel', 0) == 0) { //Empty cart. $where = array(); if (is_guest()) { $where['session_id'] = get_session_id(); } else { $where['ordered_by'] = get_member(); } $GLOBALS['SITE_DB']->query_delete('shopping_cart', $where); log_cart_actions('Completed payment'); if (perform_local_payment()) { $trans_id = post_param('trans_id'); $transaction_rows = $GLOBALS['SITE_DB']->query_select('trans_expecting', array('*'), array('id' => $trans_id), '', 1); if (!array_key_exists(0, $transaction_rows)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $transaction_row = $transaction_rows[0]; $amount = $transaction_row['e_amount']; $length = $transaction_row['e_length']; $length_units = $transaction_row['e_length_units']; $via = get_option('payment_gateway'); require_code('hooks/systems/ecommerce_via/' . filter_naughty_harsh($via)); $object = object_factory('Hook_' . $via); $name = post_param('name'); $card_number = post_param('card_number'); $expiry_date = str_replace('/', '', post_param('expiry_date')); $issue_number = post_param_integer('issue_number', NULL); $start_date = str_replace('/', '', post_param('start_date')); $card_type = post_param('card_type'); $cv2 = post_param('cv2'); list($success, , $message, $message_raw) = $object->do_transaction($trans_id, $name, $card_number, $amount, $expiry_date, $issue_number, $start_date, $card_type, $cv2, $length, $length_units); if ($success || !is_null($length)) { $status = !is_null($length) && !$success ? 'SCancelled' : 'Completed'; handle_confirmed_transaction($transaction_row['e_purchase_id'], $transaction_row['e_item_name'], $status, $message_raw, '', '', $amount, get_option('currency'), $trans_id, '', $via, is_null($length) ? '' : strtolower(strval($length) . ' ' . $length_units)); } if ($success) { $member_id = $transaction_row['e_member_id']; require_code('notifications'); dispatch_notification('payment_received', NULL, do_lang('PAYMENT_RECEIVED_SUBJECT', $trans_id), do_lang('PAYMENT_RECEIVED_BODY', float_format(floatval($amount)), get_option('currency'), get_site_name()), array($member_id), A_FROM_SYSTEM_PRIVILEGED); } } attach_message(do_lang_tempcode('SUCCESS'), 'inform'); if (count($_POST) != 0) { $order_id = handle_transaction_script(); $object = find_product(do_lang('CART-ORDER', $order_id)); if (method_exists($object, 'get_finish_url')) { return redirect_screen($title, $object->get_finish_url(), $message); } } return $this->wrap(do_template('PURCHASE_WIZARD_STAGE_FINISH', array('TITLE' => $title, 'MESSAGE' => $message)), $title, NULL); } if (!is_null($message)) { return $this->wrap(do_template('PURCHASE_WIZARD_STAGE_FINISH', array('TITLE' => $title, 'MESSAGE' => $message)), $title, NULL); } warn_exit(do_lang_tempcode('PRODUCT_PURCHASE_CANCEL')); return new ocp_tempcode(); // Will never get here }
/** * Display a catalogue entry * * @param AUTO_LINK Entry ID * @param boolean Whether to skip rendering a title * @return tempcode Tempcode interface to display an entry */ function render_catalogue_entry_screen($id, $no_title = false) { require_code('feedback'); if (addon_installed('ecommerce')) { require_code('ecommerce'); } require_code('images'); require_css('catalogues'); require_lang('catalogues'); $entries = $GLOBALS['SITE_DB']->query_select('catalogue_entries', array('*'), array('id' => $id), '', 1); if (!array_key_exists(0, $entries)) { return warn_screen(get_page_title('CATALOGUES'), do_lang_tempcode('MISSING_RESOURCE')); } $entry = $entries[0]; $categories = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('*'), array('id' => $entry['cc_id']), '', 1); if (!array_key_exists(0, $categories)) { warn_exit(do_lang_tempcode('CAT_NOT_FOUND', strval($entry['cc_id']))); } $category = $categories[0]; $GLOBALS['FEED_URL'] = find_script('backend') . '?mode=catalogues&filter=' . strval($entry['cc_id']); $catalogue_name = $category['c_name']; $catalogues = $GLOBALS['SITE_DB']->query_select('catalogues', array('*'), array('c_name' => $catalogue_name), '', 1); if (!array_key_exists(0, $catalogues)) { warn_exit(do_lang_tempcode('CATALOGUE_NOT_FOUND', $catalogue_name)); } $catalogue = $catalogues[0]; // Permission for here? if (!has_category_access(get_member(), 'catalogues_catalogue', $catalogue_name)) { access_denied('CATALOGUE_ACCESS'); } if (get_value('disable_cat_cat_perms') !== '1' && !has_category_access(get_member(), 'catalogues_category', strval($entry['cc_id']))) { access_denied('CATEGORY_ACCESS'); } $ecommerce = is_ecommerce_catalogue($catalogue_name); if ($ecommerce) { $tpl_set = 'products'; } else { $tpl_set = $catalogue_name; } $root = get_param_integer('root', NULL); $map = get_catalogue_entry_map($entry, $catalogue, 'PAGE', $tpl_set, $root, NULL, NULL, true, true); if (get_db_type() != 'xml') { $entry['ce_views']++; $GLOBALS['SITE_DB']->query_update('catalogue_entries', array('ce_views' => $entry['ce_views']), array('id' => $id), '', 1, NULL, false, true); } // Validation if ($entry['ce_validated'] == 0) { if (!has_specific_permission(get_member(), 'jump_to_unvalidated')) { access_denied('SPECIFIC_PERMISSION', 'jump_to_unvalidated'); } $map['WARNINGS'] = do_template('WARNING_TABLE', array('_GUID' => 'bf604859a572ca53e969bec3d91f9cfb', 'WARNING' => do_lang_tempcode(get_param_integer('redirected', 0) == 1 ? 'UNVALIDATED_TEXT_NON_DIRECT' : 'UNVALIDATED_TEXT'))); } else { $map['WARNINGS'] = ''; } //Finding any hook exists for this product-------------------- if (addon_installed('ecommerce')) { $object = find_product(strval($id)); if (is_object($object) && method_exists($object, 'get_custom_product_map_fields')) { $object->get_custom_product_map_fields($id, $map); } } //------------------------------------------------------------ $map['ENTRY'] = do_template('CATALOGUE_' . $tpl_set . '_ENTRY', $map, NULL, false, 'CATALOGUE_DEFAULT_ENTRY'); $map['ADD_DATE'] = get_timezoned_date($entry['ce_add_date']); $map['ADD_DATE_RAW'] = strval($entry['ce_add_date']); $map['EDIT_DATE'] = is_null($entry['ce_edit_date']) ? '' : get_timezoned_date($entry['ce_edit_date']); $map['EDIT_DATE_RAW'] = is_null($entry['ce_edit_date']) ? '' : strval($entry['ce_edit_date']); $map['VIEWS'] = integer_format($entry['ce_views']); $title_to_use = do_lang_tempcode($catalogue_name . '__CATALOGUE_ENTRY', $map['FIELD_0']); $title_to_use_2 = do_lang($catalogue_name . '__CATALOGUE_ENTRY', $map['FIELD_0_PLAIN'], NULL, NULL, NULL, false); if (is_null($title_to_use_2)) { $title_to_use = do_lang_tempcode('DEFAULT__CATALOGUE_ENTRY', $map['FIELD_0']); $title_to_use_2 = do_lang('DEFAULT__CATALOGUE_ENTRY', $map['FIELD_0_PLAIN']); } if ($no_title) { $map['TITLE'] = new ocp_tempcode(); } else { if (addon_installed('awards')) { require_code('awards'); $awards = find_awards_for('catalogue_entry', strval($id)); } else { $awards = array(); } $map['TITLE'] = get_page_title($title_to_use, false, NULL, NULL, $awards); } $map['SUBMITTER'] = strval($entry['ce_submitter']); require_code('seo2'); if (is_object($title_to_use_2)) { $title_to_use_2 = $title_to_use_2->evaluate(); } seo_meta_load_for('catalogue_entry', strval($id), strip_tags($title_to_use_2)); if ($map['TREE'] === '') { $map['TREE'] = new ocp_tempcode(); $url = build_url(array('page' => '_SELF', 'type' => 'index', 'id' => $catalogue_name), '_SELF'); $map['TREE']->attach(hyperlink($url, escape_html(get_translated_text($catalogue['c_title'])), false, false, do_lang('INDEX'))); $map['TREE']->attach(do_template('BREADCRUMB_ESCAPED')); $url = build_url(array('page' => '_SELF', 'type' => 'category', 'id' => $category['id']), '_SELF'); $map['TREE']->attach(hyperlink($url, escape_html(get_translated_text($category['cc_title'])), false, false, do_lang('GO_BACKWARDS_TO', get_translated_text($category['cc_title'])), NULL, NULL, 'up')); } $map['CATEGORY_TITLE'] = get_translated_text($category['cc_title']); $map['CAT'] = strval($entry['cc_id']); $map['TAGS'] = get_loaded_tags('catalogue_entries'); breadcrumb_add_segment($map['TREE'], $title_to_use); if (is_null($root)) { breadcrumb_set_parents(array(array('_SELF:_SELF:misc' . ($ecommerce ? ':ecommerce=1' : ''), do_lang('CATALOGUES')))); } $GLOBALS['META_DATA'] += array('created' => date('Y-m-d', $entry['ce_add_date']), 'creator' => $GLOBALS['FORUM_DRIVER']->get_username($entry['ce_submitter']), 'publisher' => '', 'modified' => is_null($entry['ce_edit_date']) ? '' : date('Y-m-d', $entry['ce_edit_date']), 'type' => get_translated_text($catalogue['c_title']) . ' entry', 'title' => comcode_escape($title_to_use_2), 'identifier' => '_SEARCH:catalogues:entry:' . strval($id), 'description' => ''); return do_template('CATALOGUE_' . $tpl_set . '_ENTRY_SCREEN', $map, NULL, false, 'CATALOGUE_DEFAULT_ENTRY_SCREEN'); }
/** * Show my subscriptions. * * @return tempcode The interface. */ function my() { $title = get_page_title('MY_SUBSCRIPTIONS'); $member_id = get_member(); if (has_specific_permission(get_member(), 'assume_any_member')) { $member_id = get_param_integer('id', $member_id); } $subscriptions = array(); $rows = $GLOBALS['SITE_DB']->query_select('subscriptions', array('*'), array('s_member_id' => $member_id)); foreach ($rows as $row) { $product = $row['s_type_code']; $object = find_product($product); if (is_null($object)) { continue; } $products = $object->get_products(false, $product); $subscription_title = $products[$product][4]; $time = get_timezoned_date($row['s_time'], true, false, false, true); $state = do_lang_tempcode('PAYMENT_STATE_' . $row['s_state']); $cancel_button = make_cancel_button($row['s_auto_fund_key'], $row['s_via']); $per = do_lang('_LENGTH_UNIT_' . $products[$product][3]['length_units'], integer_format($products[$product][3]['length'])); $subscriptions[] = array('SUBSCRIPTION_TITLE' => $subscription_title, 'ID' => strval($row['id']), 'PER' => $per, 'AMOUNT' => $row['s_amount'], 'TIME' => $time, 'STATE' => $state, 'TYPE_CODE' => $row['s_type_code'], 'CANCEL_BUTTON' => $cancel_button); } if (count($subscriptions) == 0) { inform_exit(do_lang_tempcode('NO_ENTRIES')); } return do_template('ECOM_SUBSCRIPTIONS_SCREEN', array('_GUID' => 'e39cd1883ba7b87599314c1f8b67902d', 'TITLE' => $title, 'SUBSCRIPTIONS' => $subscriptions)); }
/** * Product info for all ecommerce items * * @param tempcode The page title. * @return tempcode The result of execution. */ function product_info($title) { $this->ensure_in(); require_code('form_templates'); $text = new ocp_tempcode(); $object = find_product(get_param('product')); if (is_null($object)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } if (method_exists($object, 'is_available') && !$object->is_available(get_param('product'), get_member())) { warn_exit(do_lang_tempcode('PRODUCT_UNAVAILABLE')); } $text->attach(paragraph($object->product_info(get_param('product')))); $licence = method_exists($object, 'get_agreement') ? $object->get_agreement(get_param('product')) : ''; $fields = method_exists($object, 'get_needed_fields') ? $object->get_needed_fields(get_param('product')) : NULL; $url = build_url(array('page' => '_SELF', 'type' => $licence == '' ? is_null($fields) ? 'pay' : 'details' : 'licence', 'product' => get_param('product'), 'id' => get_param_integer('id', -1)), '_SELF'); breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('PURCHASING')))); return $this->wrap(do_template('PURCHASE_WIZARD_STAGE_MESSAGE', array('_GUID' => '8667b6b544c4cea645a52bb4d087f816', 'TITLE' => $title, 'TEXT' => $text)), $title, $url); }
/** * Handling of a usergroup subscription. * * @param ID_TEXT The purchase ID. * @param array Details relating to the product. * @param ID_TEXT The product. */ function handle_usergroup_subscription($purchase_id, $details, $product) { $member_id = $GLOBALS['SITE_DB']->query_value_null_ok('subscriptions', 's_member_id', array('id' => intval($purchase_id))); if (is_null($member_id)) { return; } require_code('ocf_groups_action'); require_code('ocf_groups_action2'); require_code('ocf_members'); require_code('notifications'); $usergroup_subscription_id = intval(substr($product, 9)); $dbs_bak = $GLOBALS['NO_DB_SCOPE_CHECK']; $GLOBALS['NO_DB_SCOPE_CHECK'] = true; $rows = $GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_select('f_usergroup_subs', array('*'), array('id' => $usergroup_subscription_id), '', 1); $GLOBALS['NO_DB_SCOPE_CHECK'] = $dbs_bak; if (array_key_exists(0, $rows)) { $myrow = $rows[0]; $new_group = $myrow['s_group_id']; $object = find_product($product); } else { $object = NULL; } if (is_null($object)) { return; // The usergroup subscription has been deleted, and this was to remove the payment for it } $test = $GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT id FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'subscriptions WHERE (' . db_string_equal_to('s_state', 'cancelled') . ') AND ' . db_string_equal_to('id', $purchase_id)); if (!is_null($test)) { $test = in_array($new_group, $GLOBALS['FORUM_DRIVER']->get_members_groups($member_id)); if ($test) { // Remove them from the group if (is_null($GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_value_null_ok('f_group_member_timeouts', 'member_id', array('member_id' => $member_id, 'group_id' => $new_group)))) { if (get_value('unofficial_ecommerce') == '1' && get_forum_type() != 'ocf') { $GLOBALS['FORUM_DB']->remove_member_from_group($member_id, $new_group); } else { // if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id,'m_primary_group')==$new_group) if ($myrow['s_uses_primary'] == 1) { $GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_update('f_members', array('m_primary_group' => get_first_default_group()), array('id' => $member_id), '', 1); } else { $GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_delete('f_group_members', array('gm_group_id' => $new_group, 'gm_member_id' => $member_id)); // ,'',1 } } dispatch_notification('paid_subscription_ended', NULL, do_lang('PAID_SUBSCRIPTION_ENDED', NULL, NULL, NULL, get_lang($member_id)), get_translated_text($myrow['s_mail_end'], NULL, get_lang($member_id)), array($member_id), A_FROM_SYSTEM_PRIVILEGED); } } } else { $test = in_array($new_group, $GLOBALS['FORUM_DRIVER']->get_members_groups($member_id)); if (!$test) { // Add them to the group if (get_value('unofficial_ecommerce') == '1' && get_forum_type() != 'ocf') { $GLOBALS['FORUM_DB']->add_member_to_group($member_id, $new_group); } else { if ($myrow['s_uses_primary'] == 1) { $GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_update('f_members', array('m_primary_group' => $new_group), array('id' => $member_id), '', 1); } else { ocf_add_member_to_group($member_id, $new_group); } } $GLOBALS[get_forum_type() == 'ocf' ? 'FORUM_DB' : 'SITE_DB']->query_delete('f_group_member_timeouts', array('member_id' => $member_id, 'group_id' => $new_group)); dispatch_notification('paid_subscription_started', NULL, do_lang('PAID_SUBSCRIPTION_STARTED'), get_translated_text($myrow['s_mail_start'], NULL, get_lang($member_id)), array($member_id), A_FROM_SYSTEM_PRIVILEGED); } } }
/** * The actualiser for a manually triggered transaction. * * @return tempcode The result of execution. */ function _trigger() { $title = get_page_title('MANUAL_TRANSACTION'); $item_name = post_param('item_name'); breadcrumb_set_parents(array(array('_SELF:_SELF:ecom_usage', do_lang_tempcode('ECOMMERCE')), array('_SELF:_SELF:trigger', do_lang_tempcode('PRODUCT')), array('_SELF:_SELF:trigger:item_name=' . $item_name, do_lang_tempcode('MANUAL_TRANSACTION')))); $purchase_id = post_param('purchase_id', ''); $memo = post_param('memo'); $mc_gross = post_param('amount', ''); $object = find_product($item_name); $products = $object->get_products(true); if ($mc_gross == '') { $mc_gross = $products[$item_name][1]; } $payment_status = 'Completed'; $reason_code = ''; $pending_reason = ''; $mc_currency = get_option('currency'); $txn_id = 'manual-' . substr(uniqid('', true), 0, 10); $parent_txn_id = ''; /*if ($products[$item_name][0]==PRODUCT_SUBSCRIPTION) { $payment_status='SCancelled'; }*/ $_item_name = $products[$item_name][4]; if ($products[$item_name][0] == PRODUCT_SUBSCRIPTION) { if ($purchase_id == '') { $purchase_id = strval($GLOBALS['SITE_DB']->query_insert('subscriptions', array('s_type_code' => $item_name, 's_member_id' => get_member(), 's_state' => 'new', 's_amount' => $products[$item_name][1], 's_special' => $purchase_id, 's_time' => time(), 's_auto_fund_source' => '', 's_auto_fund_key' => '', 's_via' => 'manual'), true)); } $_item_name = ''; // Flag for handle_confirmed_transaction to know it's a subscription } handle_confirmed_transaction($purchase_id, $_item_name, $payment_status, $reason_code, $pending_reason, $memo, $mc_gross, $mc_currency, $txn_id, $parent_txn_id); $url = get_param('redirect', NULL); if (!is_null($url)) { return redirect_screen($title, $url, do_lang_tempcode('SUCCESS')); } return inform_screen($title, do_lang_tempcode('SUCCESS')); }
/** * Handle IPN's that have been confirmed as backed up by real money. * * @param ID_TEXT The ID of the purchase-type (meaning depends on item_name) * @param SHORT_TEXT The item being purchased (aka the product) (blank: subscription, so we need to look it up). One might wonder why we use $item_name instead of $product. This is because we pass human-readable-names (hopefully unique!!!) through payment gateways because they are visually shown to the user. (blank: it's a subscription, so look up via a key map across the subscriptions table) * @param SHORT_TEXT The status this transaction is telling of * @set SModified SCancelled Completed Pending Failed * @param SHORT_TEXT The code that gives reason to the status * @param SHORT_TEXT The reason it is in pending status (if it is) * @param SHORT_TEXT A note attached to the transaction * @param SHORT_TEXT The amount of money * @param SHORT_TEXT The currency the amount is in * @param SHORT_TEXT The transaction ID * @param SHORT_TEXT The ID of the parent transaction * @param ID_TEXT The ID of a special source for the transaction * @param string The subscription period (blank: N/A) */ function handle_confirmed_transaction($purchase_id, $item_name, $payment_status, $reason_code, $pending_reason, $memo, $mc_gross, $mc_currency, $txn_id, $parent_txn_id, $source = '', $period = '') { /*#####################################################################################*/ //Temporary setting - force payment setting to "completed" for test mode transactions if (get_option('ecommerce_test_mode') == "1") { $payment_status = 'Completed'; } /*#####################################################################################*/ // Try and locate the product if ($item_name == '') { $product = $GLOBALS['SITE_DB']->query_value_null_ok('subscriptions', 's_type_code', array('id' => intval($purchase_id))); // Note that s_type_code is not numeric, it is a $product if (is_null($product)) { warn_exit(do_lang_tempcode('NO_SUCH_SUBSCRIPTION', strval($purchase_id))); } $item_name = '_' . $product; // Check what we sold list($found, ) = find_product_row($product, true, false); if (!is_null($found)) { $item_name = $found[4]; } } else { // Check what we sold list($found, $product) = find_product_row($item_name, true, true); } if (is_null($found)) { my_exit(do_lang('PRODUCT_NO_SUCH') . ' - ' . $item_name); } // Check price if ($mc_gross != $found[1] && $found[1] != '?') { if ($payment_status == 'SModified') { $GLOBALS['SITE_DB']->query_update('subscriptions', array('s_state' => 'new'), array('id' => intval($purchase_id)), '', 1); } if ($payment_status != 'SCancelled' && substr($txn_id, 0, 6) != 'manual') { my_exit(do_lang('PURCHASE_WRONG_PRICE', $item_name)); } } if ($period != '') { $length = array_key_exists('length', $found[3]) ? strval($found[3]['length']) : '1'; $length_units = array_key_exists('length_units', $found[3]) ? $found[3]['length_units'] : 'm'; if (strtolower($period) != strtolower($length . ' ' . $length_units)) { my_exit(do_lang('IPN_SUB_PERIOD_WRONG')); } } // Store $GLOBALS['SITE_DB']->query_insert('transactions', array('id' => $txn_id, 't_memo' => $memo, 'purchase_id' => $purchase_id, 'status' => $payment_status, 'pending_reason' => $pending_reason, 'reason' => $reason_code, 'amount' => $mc_gross, 't_currency' => $mc_currency, 'linked' => $parent_txn_id, 't_time' => time(), 'item' => $product, 't_via' => $source)); $found['txn_id'] = $txn_id; // Check currency if ($mc_currency != get_option('currency')) { if ($payment_status == 'SModified') { $GLOBALS['SITE_DB']->query_update('subscriptions', array('s_state' => 'new'), array('id' => intval($purchase_id)), '', 1); } if ($payment_status != 'SCancelled' && substr($txn_id, 0, 6) != 'manual') { my_exit(do_lang('PURCHASE_WRONG_CURRENCY')); } } // Pending if ($payment_status == 'Pending' && $found[0] == PRODUCT_INVOICE) { $GLOBALS['SITE_DB']->query_update('invoices', array('i_state' => 'pending'), array('id' => intval($purchase_id)), '', 1); } elseif ($payment_status == 'Pending' && $found[0] == PRODUCT_SUBSCRIPTION) { $GLOBALS['SITE_DB']->query_update('subscriptions', array('s_state' => 'pending'), array('id' => intval($purchase_id)), '', 1); if ($found[2] != '') { call_user_func_array($found[2], array($purchase_id, $found, $product, true)); } // Run cancel code } elseif ($payment_status == 'Pending' && $item_name == do_lang('CART_ORDER', $purchase_id)) { $found['ORDER_STATUS'] = 'ORDER_STATUS_awaiting_payment'; if ($found[2] != '') { call_user_func_array($found[2], array($purchase_id, $found, $product, true)); } // Set order status } elseif ($payment_status == 'SCancelled' && $found[0] == PRODUCT_SUBSCRIPTION) { $GLOBALS['SITE_DB']->query_update('subscriptions', array('s_auto_fund_source' => $source, 's_auto_fund_key' => $txn_id, 's_state' => 'cancelled'), array('id' => intval($purchase_id)), '', 1); } elseif ($found[0] == PRODUCT_SUBSCRIPTION) { $GLOBALS['SITE_DB']->query_update('subscriptions', array('s_auto_fund_source' => $source, 's_auto_fund_key' => $txn_id, 's_state' => 'active'), array('id' => intval($purchase_id)), '', 1); } elseif ($payment_status != 'Completed' && $payment_status != 'SCancelled' && get_option('ecommerce_test_mode') != '1') { my_exit(do_lang('TRANSACTION_NOT_COMPLETE', $product . ':' . strval($purchase_id), $payment_status), true); } // Invoice: Check price if ($found[0] == PRODUCT_INVOICE) { $price = $GLOBALS['SITE_DB']->query_value('invoices', 'i_amount', array('id' => intval($purchase_id))); if ($price != $mc_gross) { if (substr($txn_id, 0, 6) != 'manual') { my_exit(do_lang('PURCHASE_WRONG_PRICE', $item_name)); } } } /* At this point we know our order (or subscription cancellation) is good */ // Dispatch if ($payment_status == 'Completed' || $payment_status == 'SCancelled') { //Find product hooks of this order to check dispatch type $object = find_product($product, true); if (is_object($object) && !method_exists($object, 'get_product_dispatch_type')) { //If hook does not have dispatch method setting take dispatch method as automatic $found['ORDER_STATUS'] = 'ORDER_STATUS_dispatched'; } elseif (is_object($object) && $object->get_product_dispatch_type($purchase_id) == 'automatic') { $found['ORDER_STATUS'] = 'ORDER_STATUS_dispatched'; } else { $found['ORDER_STATUS'] = 'ORDER_STATUS_payment_received'; } if ($found[2] != '') { call_user_func_array($found[2], array($purchase_id, $found, $product)); } // Send out notification to staff if ($found[0] == PRODUCT_SUBSCRIPTION) { require_code('notifications'); $member_id = $GLOBALS['SITE_DB']->query_value_null_ok('subscriptions', 's_member_id', array('id' => intval($purchase_id))); if (!is_null($member_id)) { $username = $GLOBALS['FORUM_DRIVER']->get_username($member_id); if (is_null($username)) { $username = do_lang('GUEST'); } if ($payment_status == 'Completed') { $subject = do_lang('SERVICE_PAID_FOR', $item_name, $username, get_site_name(), get_site_default_lang()); $body = do_lang('_SERVICE_PAID_FOR', $item_name, $username, get_site_name(), get_site_default_lang()); dispatch_notification('service_paid_for_staff', NULL, $subject, $body); } else { $subject = do_lang('SERVICE_CANCELLED', $item_name, $username, get_site_name(), get_site_default_lang()); $body = do_lang('_SERVICE_CANCELLED', $item_name, $username, get_site_name(), get_site_default_lang()); dispatch_notification('service_cancelled_staff', NULL, $subject, $body); } } } } // Invoice handling if ($found[0] == PRODUCT_INVOICE) { $GLOBALS['SITE_DB']->query_update('invoices', array('i_state' => 'paid'), array('id' => intval($purchase_id)), '', 1); } // Subscription: Delete if cancelled if ($payment_status == 'SCancelled' && $found[0] == PRODUCT_SUBSCRIPTION) { $GLOBALS['SITE_DB']->query_delete('subscriptions', array('id' => intval($purchase_id)), '', 1); } }