PHP は注文漏れを防ぐために zen-cart の注文と支払いプロセスを変更します

WBOY
リリース: 2016-06-13 12:18:30
オリジナル
1540 人が閲覧しました

zen-cart を使用したことがある人なら、zen-cart で注文する手順は次のとおりであることをご存知でしょう ([] 内の式は不要です)。

1. ショッピングカート

2.【配送方法】

3.支払い方法

4.注文確認(確認)

5. [サードパーティ Web サイトでの支払い]

6. 注文処理 (チェックアウトプロセス) - ショッピングカート内の情報がここでの注文に書き込まれるため、このステップはより重要です

7. 注文は成功しました (チェックアウトは成功しました)

通常の状況では、このプロセスに問題はありません。ただし、ステップ 5 からステップ 6 までのプロセスでは、ユーザーが支払いが成功したと考えて Web ページを直接閉じたり、ネットワーク上の理由によりユーザーが正常に checkout_process ページにジャンプできない可能性があります。注文を正常に作成できないため、これは非常に深刻です。

上記の分析に基づいて、私たちはプロセスを少し変更することを望んでいます。つまり、注文は支払い前に作成されるため、たとえ支払いがサードパーティの支払い Web サイトからリダイレクトされなかったとしても、ユーザーが正常に支払いに失敗しました。バックグラウンドでの注文はありません。変更されたブループリントは基本的に次のようになります:

1. checkour_confirmation ページで注文を確認した後、直接処理して checkour_success ページに入り、支払いページに入ることができます。以下に示すように:


2. 顧客がその時点で支払いを怠った場合は、独自のバックエンドにアクセスして過去の注文の支払いを行うこともできます。以下に示すように:


上記の機能を実装する方法を段階的に見てみましょう。

1. まず、既存の支払いモジュールを変換する必要があります。支払い用のページ URL を表すフィールド paynow_action_url を支払いメソッド クラスに追加する必要があります。さらに、支払いフォームのパラメータ隠しフィールド コードを取得するために関数 paynow_button($order_id) を追加する必要があります。
paynow_action_url フィールドを追加するには、クラス支払いのコンストラクターの最後に次のコードを追加してください:

コードをコピーします コードは次のとおりです。 :


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;
}


paynow_button($order_id) 関数を追加するには支払いクラスに追加してください。 最後の関数の後に次のコードを追加します:

コードをコピー コードは次のとおりです:


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. PayPal の支払い方法を例に挙げます。それを実装する方法を説明します。 paypal の元のコードを破壊しないように、paypal.php ファイルのコピーを作成し、paypalsimple.php という名前を付け、内部のコードに適切な変更を加えます。コードは以下のとおりです。ここでは、form_action_url の指定が削除され、paynow_action_url が指定されていることがわかります。これは、ユーザーが「注文の確認」をクリックした後に直接 checkout_process に入ってほしいためです。そのため、form_action_url が指定されていない場合は、注文を確認するためのフォームは checkout_process ページに直接送信され、paynow_action_url は前の form_action_url の値です。 paynow_button 関数の実装も非常に簡単です。ここでは、元の process_button() 関数の内容を切り取っているだけですが、グローバル $order 変数を使用する代わりに、$order = new order($order_id) を使用して再作成します。過去の注文で今すぐ支払うボタンを表示する準備として構築されたオブジェクト。
paypalsimple.php

コードをコピー コードは次のとおりです:


/**
* @package paypalsimple 支払いモジュール
* @copyright Copyright 2003-2006 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @license http://www.zen-cart.com /license/2_0.txt GNU パブリック ライセンス V2.0
* @version $Id: paypalsimple.php 4960 2009-12-29 11:46:46Z gary $
*/
// 依存関係がロードされていることを確認します
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;
// クラス コンストラクター
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();
}
// クラスメソッド
function update_status() {
global $order, $db;
if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE > 0) ) {
$check_flag = false;
$check = $db->Execute("selectzone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE . "' andzone_country_id = '" . $order->billing['country'][ 'id'] . "' ゾーン ID による順序");
while (!$check->EOF) {
if ($check->fields['zone_id'] < 1) {
$check_flag = true;
休憩;
} elseif ($check->fields['zone_id'] == $order->billing['zone_id']) {
$check_flag = true;
休憩;
}
$check->MoveNext();
}
if ($check_flag == false) {
$this->enabled = false;
}
}
}
function javascript_validation() {
return false;
}
関数 select() {
$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
);
}
関数 pre_confirmation_check() {
return false;
}
関数confirmation() {
return false;
}
function process_button() {
return false;
}
関数 before_process() {
return false;
}
関数 after_process() {
return false;
}
function get_error() {
return false;
}
関数 check() {
グローバル $db;
if (!isset($this->_check)) {
$check_query = $db->Execute("selectconfiguration_value from " . TABLE_CONFIGURATION . " whereconfiguration_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('PayPal-Simple モジュールを有効にする', 'MODULE_PAYMENT_PAYPAL_SIMPLE_STATUS', ' True', 'PayPal-Simple 支払いを受け入れますか?', '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('表示のソート順。', 'MODULE_PAYMENT_PAYPAL_SIMPLE_SORT_ORDER', '0', 'Sort表示順序。低いものが最初に表示されます。', '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) 値 ('Payment Zone', 'MODULE_PAYMENT_PAYPAL_SIMPLE_ZONE', '0', 'ゾーンが選択されている場合は、そのゾーンに対してのみこの支払い方法を有効にします。', '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', 'この支払いモジュールで行われた注文のステータスをこの値に設定します', '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('PayPal Web サービスのモード

デフォルト:< ;br />gt;www.paypal.com/cgi-bin/webscrgt;
または
www.paypal.com/us/cgi- bin/webscr
または英国の場合、
www.paypal.com/uk/cgi-bin/webscr'、'MODULE_PAYMENT_PAYPAL_SIMPLE_HANDLER' , 'www.paypal.com/cgi-bin/webscr', 'PayPal ライブ処理用の URL を選択してください', '6', '73', '', now())");
}
関数の削除() {
グローバル $db;
$db->Execute("delete from " . TABLE_CONFIGURATION . " whereconfiguration_key in ('" . implode("', '", $this->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){
グローバル $db, $order, $currency, $currency;
require_once(DIR_WS_CLASSES . 'order.php');
$order = 新しい注文($order_id);
$options = array();
$optionsCore = array();
$optionsPhone = array();
$optionsShip = array();
$optionsLineItems = array();
$optionsAggregate = array();
$optionsTrans = array();
$buttonArray = array();
$this->totalsum = $order->info['total'];
// Paypal がセッションを失った場合に備えて、セッション内容を永続的に保存します
$_SESSION['pipn_key_to_remove'] = session_id();
$db->Execute("delete from " . TABLE_PAYPAL_SESSION . " where session_id = '" . zen_db_input($_SESSION['pipn_key_to_remove']) . "'");
$sql = "に挿入" 。 TABLE_PAYPAL_SESSION 。 " (session_id、saved_session、expiry) 値 (
'" .zen_db_input($_SESSION['pipn_key_to_remove']) . "',
'" .base64_encode(serialize($_SESSION)) . "',
'" . (time() (1*60*60*24*2)) . "')";
$db->実行($sql);
$my_currency = select_pp_currency();
$this->transaction_currency = $my_currency;
$this->transaction_amount = ($this->totalsum * $currency->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( $電話,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 ' =>'custom' => zen_session_id()、
'return' => ref_link(FILENAME_PAY_SUCCESS , 'referer=paypal', 'SSL'),
'cancel_return' => zen_href_link(FILENAME_PAY_FAILED, '', 'SSL'),
'shopping_url' => SSL')、
'notify_url' => zen_href_link('ipn_main_handler.php', '', 'SSL',false,false,true),
'redirect_cmd' => >'rm' => 2、
'bn' => 'R-6C7952342H795591R'、
'pal' =>
);
$optionsCust = array(
'first_name' => replace_accents($order->customer['firstname']),
'last_name' => replace_accents($order->customer[ 'lastname'])、
'address1' => replace_accents($order->customer['street_address'])、
'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['ゾーン ID']),
'住所_zip' => $order->顧客['郵便番号'],
'住所国' => $order->顧客['国']['タイトル' ],
'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 (!isset($optionsLineItems['item_name_1'])) $optionsLineItems = array() ;
//if ($optionsLineItems['amount'] != $this->transaction_amount) $optionsLineItems = array();
ipn_debug_email('明細項目の詳細 (空白の場合、データの不一致があったためバイパスされたことを意味します): ' . "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<$n; $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('
');
echo(''.TEXT_PAYNOW.'');
echo zen_draw_form('checkout_paynow', $payment_modules->paynow_action_url, 'post', 'id="checkout_confirmation" onsubmit="submitonce();"');
$selection = $payment_modules->selection();
echo('
'.$selection[0]['module'].'
');
echo('
');
if (is_array($payment_modules->modules)) {
echo $payment_modules->paynow_button($orders_id);
}
echo(zen_image_submit(BUTTON_IMAGE_PAYNOW, BUTTON_IMAGE_PAYNOW_ALT, 'name="btn_paynow" id="btn_paynow"'));
echo('
');
echo('');
echo('
');
}
?>


4. 過去の注文に今すぐ支払うボタンを表示します。 「今すぐ支払う」ボタンを表示する必要があるページは、account、account_history、account_history_info の 3 つです。ここでの実装は、$payment_modules に渡される関数 paynow_button のパラメータが異なることを除いて、checkout_success ページの実装と似ています。ここでは詳細には触れません。
概要:
上記変更後の流れは以下の通りです:
1. ショッピングカート (ショッピングカート)
2. お支払い方法 (お支払い方法)
4. 注文の確認 (確認)
5. 注文処理 (チェックアウトの処理)
7. [サードパーティのウェブサイトでの支払い]
注文確認から注文処理までは当社独自のウェブサイトで完了し、支払いウェブサイトに入る前に注文がすでに存在しているため、注文が取り消されることはありません。


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート