


Anyone who has used zen-cart knows that the steps for placing an order in zen-cart are as follows (the expressions in [] are not necessary):
1. Shopping cart
2. [delivery method]
3. Payment method
4. Order confirmation (confirmation)
5. [Third-party website payment]
6. Order processing (checkout process) - This step is more important because the information in the shopping cart will be written into the order here
7. Order successful (checkout success)
There is no problem with this process under normal circumstances. However, in the process from step 5 to step 6, the user may think that the payment is successful and close the web page directly, or the user may not be able to jump to the checkout_process page normally due to network reasons. The consequences of this are very serious, because the order Cannot be created normally.
Based on the above analysis, we hope to change the process slightly, that is, the order has been created before payment, so that even if the payment cannot be redirected from the third-party payment website, we will not have the user fail to pay successfully. There are no orders in the background. The modified blueprint basically looks like this:
1. After confirming the order on the checkour_confirmation page, you will directly proccess and enter the checkour_success page, where you can enter the payment page. As shown in the picture below:
2. If the customer fails to pay at that time, they can also enter their own backend to pay for historical orders. As shown below:
Let’s take a look at how to implement the above functions step by step.
1. First we need to transform the existing payment module. It is necessary to add a field paynow_action_url to the payment method class to represent the page URL for payment. In addition, a function, paynow_button($order_id), needs to be added to obtain the parameter hidden field code of the payment form.
To add the paynow_action_url field, please add the following code at the end of the constructor of class payment:
if ( (zen_not_null($module)) && (in_array($module.'.php', $this->modules)) && (isset($GLOBALS[$module]->paynow_action_url)) ) {
$this->paynow_action_url = $GLOBALS[$module]->paynow_action_url;
}
To add the paynow_button($order_id) function, please add it to the payment class Add the following code after the last function:
function paynow_button($order_id){
if (is_array($this->modules)) {
if (is_object($GLOBALS[$this->selected_module])) {
return $GLOBALS[$this->selected_module]- >paynow_button($order_id);
}
}
}
2. Take the paypal payment method as an example to explain how to implement it. In order not to destroy the original code of paypal, we will make a copy of the paypal.php file, name it paypalsimple.php, and make appropriate modifications to the code inside. The code is as shown below. You can see that the specification of form_action_url is removed here and paynow_action_url is given. Because we hope that the user will directly enter the checkout_process after clicking "Confirm Order", so if form_action_url is not specified, then the form to confirm the order will be It is submitted directly to the checkout_process page, and paynow_action_url is the value of the previous form_action_url. The implementation of the paynow_button function is also very simple. Here we just cut the content of the original process_button() function, but we do not use the global $order variable, but use $order = new order($order_id) to re- An object constructed in preparation for displaying the pay now button in historical orders.
paypalsimple.php
/**
* @package paypalsimple payment module
* @copyright Copyright 2003-2006 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: paypalsimple.php 4960 2009-12-29 11:46:46Z gary $
*/
// ensure dependencies are loaded
include_once((IS_ADMIN_FLAG === true ? DIR_FS_CATALOG_MODULES : DIR_WS_MODULES) . 'payment/paypal/paypal_functions.php');
class paypalsimple {
var $code, $title, $description, $enabled;
// class constructor
function paypalsimple() {
global $order;
$this->code = 'paypalsimple';
$this->title = MODULE_PAYMENT_PAYPAL_SIMPLE_TEXT_TITLE;
if(IS_ADMIN_FLAG === true){
$this->title = MODULE_PAYMENT_PAYPAL_SIMPLE_TEXT_ADMIN_TITLE;
}
$this->description = MODULE_PAYMENT_PAYPAL_SIMPLE_TEXT_DESCRIPTION;
$this->sort_order = MODULE_PAYMENT_PAYPAL_SIMPLE_SORT_ORDER;
$this->enabled = ((MODULE_PAYMENT_PAYPAL_SIMPLE_STATUS == 'True') ? true : false);
if ((int)MODULE_PAYMENT_PAYPAL_SIMPLE_ORDER_STATUS_ID > 0) {
$this->order_status = MODULE_PAYMENT_PAYPAL_SIMPLE_ORDER_STATUS_ID;
}
$this->paynow_action_url = 'https://' . MODULE_PAYMENT_PAYPAL_SIMPLE_HANDLER;
if (is_object($order)) $this->update_status();
}
// class methods
function update_status() {
global $order, $db;
if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE > 0) ) {
$check_flag = false;
$check = $db->Execute("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
while (!$check->EOF) {
if ($check->fields['zone_id'] $check_flag = true;
break;
} elseif ($check->fields['zone_id'] == $order->billing['zone_id']) {
$check_flag = true;
break;
}
$check->MoveNext();
}
if ($check_flag == false) {
$this->enabled = false;
}
}
}
function javascript_validation() {
return false;
}
function selection() {
$text = MODULE_PAYMENT_SIMPLE_PAYPAL_TEXT_CATALOG_LOGO.' '.MODULE_PAYMENT_PAYPAL_SIMPLE_TEXT_TITLE . '
' . MODULE_PAYMENT_PAYPAL_SIMPLE_ACCEPTANCE_MARK_TEXT . '
';
return array('id' => $this->code,
'module' => $text
);
}
function pre_confirmation_check() {
return false;
}
function confirmation() {
return false;
}
function process_button() {
return false;
}
function before_process() {
return false;
}
function after_process() {
return false;
}
function get_error() {
return false;
}
function check() {
global $db;
if (!isset($this->_check)) {
$check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPAL_SIMPLE_STATUS'");
$this->_check = $check_query->RecordCount();
}
return $this->_check;
}
function install() {
global $db;
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable PayPal-Simple Module', 'MODULE_PAYMENT_PAYPAL_SIMPLE_STATUS', 'True', 'Do you want to accept PayPal-Simple payments?', '6', '0', 'zen_cfg_select_option(array('True', 'False'), ', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_PAYPAL_SIMPLE_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '8', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Payment Zone', 'MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE', '0', 'If a zone is selected, only enable this payment method for that zone.', '6', '2', 'zen_get_zone_class_title', 'zen_cfg_pull_down_zone_classes(', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_PAYPAL_SIMPLE_ORDER_STATUS_ID', '0', 'Set the status of orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Mode for PayPal web services
Default:
www.paypal.com/cgi-bin/webscr
or
www.paypal.com/us/cgi-bin/webscr
or for the UK,
www.paypal.com/uk/cgi-bin/webscr
', 'MODULE_PAYMENT_PAYPAL_SIMPLE_HANDLER', 'www.paypal.com/cgi-bin/webscr', 'Choose the URL for PayPal live processing', '6', '73', '', now())"); }
function remove() {
global $db;
$db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}
function keys() {
return array('MODULE_PAYMENT_PAYPAL_SIMPLE_STATUS','MODULE_PAYMENT_PAYPAL_SIMPLE_SORT_ORDER','MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE','MODULE_PAYMENT_PAYPAL_SIMPLE_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_SIMPLE_HANDLER');
}
function paynow_button($order_id){
global $db, $order, $currencies, $currency;
require_once(DIR_WS_CLASSES . 'order.php');
$order = new order($order_id);
$options = array();
$optionsCore = array();
$optionsPhone = array();
$optionsShip = array();
$optionsLineItems = array();
$optionsAggregate = array();
$optionsTrans = array();
$buttonArray = array();
$this->totalsum = $order->info['total'];
// save the session stuff permanently in case paypal loses the session
$_SESSION['ppipn_key_to_remove'] = session_id();
$db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = '" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "'");
$sql = "insert into " . TABLE_PAYPAL_SESSION . " (session_id, saved_session, expiry) values (
'" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "',
'" . base64_encode(serialize($_SESSION)) . "',
'" . (time() + (1*60*60*24*2)) . "')";
$db->Execute($sql);
$my_currency = select_pp_currency();
$this->transaction_currency = $my_currency;
$this->transaction_amount = ($this->totalsum * $currencies->get_value($my_currency));
$telephone = preg_replace('/D/', '', $order->customer['telephone']);
if ($telephone != '') {
$optionsPhone['H_PhoneNumber'] = $telephone;
if (in_array($order->customer['country']['iso_code_2'], array('US','CA'))) {
$optionsPhone['night_phone_a'] = substr($telephone,0,3);
$optionsPhone['night_phone_b'] = substr($telephone,3,3);
$optionsPhone['night_phone_c'] = substr($telephone,6,4);
$optionsPhone['day_phone_a'] = substr($telephone,0,3);
$optionsPhone['day_phone_b'] = substr($telephone,3,3);
$optionsPhone['day_phone_c'] = substr($telephone,6,4);
} else {
$optionsPhone['night_phone_b'] = $telephone;
$optionsPhone['day_phone_b'] = $telephone;
}
}
$optionsCore = array(
'charset' => CHARSET,
'lc' => $order->customer['country']['iso_code_2'],
'page_style' => MODULE_PAYMENT_PAYPAL_PAGE_STYLE,
'custom' => zen_session_name() . '=' . zen_session_id(),
'business' => MODULE_PAYMENT_PAYPAL_BUSINESS_ID,
'return' => zen_href_link(FILENAME_PAY_SUCCESS, 'referer=paypal', 'SSL'),
'cancel_return' => zen_href_link(FILENAME_PAY_FAILED, '', 'SSL'),
'shopping_url' => zen_href_link(FILENAME_SHOPPING_CART, '', 'SSL'),
'notify_url' => zen_href_link('ipn_main_handler.php', '', 'SSL',false,false,true),
'redirect_cmd' => '_xclick',
'rm' => 2,
'bn' => 'zencart',
'mrb' => 'R-6C7952342H795591R',
'pal' => '9E82WJBKKGPLQ',
);
$optionsCust = array(
'first_name' => replace_accents($order->customer['firstname']),
'last_name' => replace_accents($order->customer['lastname']),
'address1' => replace_accents($order->customer['street_address']),
'city' => replace_accents($order->customer['city']),
'state' => zen_get_zone_code($order->customer['country']['id'], $order->customer['zone_id'], $order->customer['zone_id']),
'zip' => $order->customer['postcode'],
'country' => $order->customer['country']['iso_code_2'],
'email' => $order->customer['email_address'],
);
if ($order->customer['suburb'] != '') $optionsCust['address2'] = $order->customer['suburb'];
if (MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED == 2) $optionsCust = array(
'address_name' => replace_accents($order->customer['firstname'] . ' ' . $order->customer['lastname']),
'address_street' => replace_accents($order->customer['street_address']),
'address_city' => replace_accents($order->customer['city']),
'address_state' => zen_get_zone_code($order->customer['country']['id'], $order->customer['zone_id'], $order->customer['zone_id']),
'address_zip' => $order->customer['postcode'],
'address_country' => $order->customer['country']['title'],
'address_country_code' => $order->customer['country']['iso_code_2'],
'payer_email' => $order->customer['email_address'],
);
$optionsShip = array(
//'address_override' => MODULE_PAYMENT_PAYPAL_ADDRESS_OVERRIDE,
'no_shipping' => MODULE_PAYMENT_PAYPAL_ADDRESS_REQUIRED,
);
if (MODULE_PAYMENT_PAYPAL_DETAILED_CART == 'Yes') $optionsLineItems = ipn_getLineItemDetails();
if (sizeof($optionsLineItems) > 0) {
$optionsLineItems['cmd'] = '_cart';
// $optionsLineItems['num_cart_items'] = sizeof($order->products);
if (isset($optionsLineItems['shipping'])) {
$optionsLineItems['shipping_1'] = $optionsLineItems['shipping'];
unset($optionsLineItems['shipping']);
}
if (isset($optionsLineItems['handling'])) {
$optionsLineItems['handling_1'] = $optionsLineItems['handling'];
unset($optionsLineItems['handling']);
}
unset($optionsLineItems['subtotal']);
// if line-item details couldn't be kept due to calculation mismatches or discounts etc, default to aggregate mode
if (!isset($optionsLineItems['item_name_1'])) $optionsLineItems = array();
//if ($optionsLineItems['amount'] != $this->transaction_amount) $optionsLineItems = array();
ipn_debug_email('Line Item Details (if blank, this means there was a data mismatch, and thus bypassed): ' . "n" . print_r($optionsLineItems, true));
}
$products_name_display = "";
/*
for ($i=0, $n=sizeof($order->products); $iif(i > 0) {
$products_name_display.= ', ';
}
$products_name_display.= $order->products[$i]['name']. '('. $order->products[$i]['qty'] .','.$order->products[$i]['dhisys_web_order_number'].')';
}*/
$optionsAggregate = array(
'cmd' => '_ext-enter',
'item_name' => $products_name_display,
'item_number' => $order_id,
'num_cart_items' => sizeof($order->products),
'amount' => number_format($this->transaction_amount, $currencies->get_decimal_places($my_currency)),
'shipping' => '0.00',
);
if (MODULE_PAYMENT_PAYPAL_TAX_OVERRIDE == 'true') $optionsAggregate['tax'] = '0.00';
if (MODULE_PAYMENT_PAYPAL_TAX_OVERRIDE == 'true') $optionsAggregate['tax_cart'] = '0.00';
$optionsTrans = array(
'upload' => (int)(sizeof($order->products) > 0),
'currency_code' => $my_currency,
// 'paypal_order_id' => $paypal_order_id,
//'no_note' => '1',
//'invoice' => '',
);
// if line-item info is invalid, use aggregate:
if (sizeof($optionsLineItems) > 0) $optionsAggregate = $optionsLineItems;
// prepare submission
$options = array_merge($optionsCore, $optionsCust, $optionsPhone, $optionsShip, $optionsTrans, $optionsAggregate);
ipn_debug_email('Keys for submission: ' . print_r($options, true));
if(sizeof($order->products) > 0){
$options['cmd'] = '_cart';
for ($i=0, $n=sizeof($order->products); $i$options['item_name_'. (string)($i+1)] = $order->products[$i]['name'];
$options['item_number_'. (string)($i+1)] = $order->products[$i]['dhisys_web_order_number'];
$options['amount_'. (string)($i+1)] = number_format((float)$order->products[$i]['final_price'],2);
$options['quantity_'. (string)($i+1)] = $order->products[$i]['qty'];
}
}
// build the button fields
foreach ($options as $name => $value) {
// remove quotation marks
$value = str_replace('"', '', $value);
// check for invalid chars
if (preg_match('/[^a-zA-Z_0-9]/', $name)) {
ipn_debug_email('datacheck - ABORTING - preg_match found invalid submission key: ' . $name . ' (' . $value . ')');
break;
}
// do we need special handling for & and = symbols?
//if (strpos($value, '&') !== false || strpos($value, '=') !== false) $value = urlencode($value);
$buttonArray[] = zen_draw_hidden_field($name, $value);
}
$_SESSION['paypal_transaction_info'] = array($this->transaction_amount, $this->transaction_currency);
$process_button_string = implode("n", $buttonArray) . "n";
return $process_button_string;
}
}
?>
3. 在checkout_success页面中显示pay now按钮。打开文件"includes/modules/pages/checkout_success/header.php",在文件的末尾添加下面的代码(如果你已经掌握zen-cart中的通知者/观察者模式,并且又不想破坏zen-cart核心代码的话,也可以创建一个观察类来监听NOTIFY_HEADER_END_CHECKOUT_SUCCESS来实现)。
require_once(DIR_WS_CLASSES . 'order.php');
require_once(DIR_WS_CLASSES . 'payment.php');
$payment_modules = new payment($orders->fields['payment_module_code']);
打开文件"includes/modules/templates/template_default/templates/tpl_checkout_success_default.php",并在适当的位置加上如下的代码,这里对订单的状态进行了一个判断,当只有订单的状态在未付款状态,才显示该按钮,
//&& $orders->fields['orders_status'] == '1'
if(isset($payment_modules->paynow_action_url) && $payment_modules->paynow_action_url != ''&& $orders->fields['orders_status'] == '1'){
echo('');
}
?>
4. Display pay now button in historical orders. There are three pages that need to display the pay now button: account, account_history, and account_history_info. The implementation here is similar to the implementation of the checkout_success page, except that the parameters of the function paynow_button passed to $payment_modules are different, so I will not go into details here.
Summary:
After the above modifications, our process is as follows:
1. Shopping cart (shopping cart)
2. [delivery method]
3. Payment method ( payment method)
4. Order confirmation (confirmation)
5. Order processing (checkout process)
6. Order successful (checkout success)
7. [Third-party website payment]
Because everything from order confirmation to order processing is completed on our own website, and the order already exists before entering the payment website, this way there will be no dropped orders.

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

Atom editor mac version download
The most popular open source editor

Dreamweaver Mac version
Visual web development tools

Dreamweaver CS6
Visual web development tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software
