Created
December 14, 2016 05:19
-
-
Save torunar/1113834bdf44ca72183d18b93a87aa01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/app/addons/paypal/controllers/common/payment_notification.post.php b/app/addons/paypal/controllers/common/payment_notification.post.php | |
index a5248fa..d4d9432 100644 | |
--- a/app/addons/paypal/controllers/common/payment_notification.post.php | |
+++ b/app/addons/paypal/controllers/common/payment_notification.post.php | |
@@ -20,23 +20,15 @@ if (!defined('BOOTSTRAP')) { die('Access denied'); } | |
if ($_SERVER['REQUEST_METHOD'] == 'POST') { | |
if ($mode == 'paypal_ipn') { | |
if (!empty($_REQUEST['custom'])) { | |
- unset($_REQUEST['dispatch']); | |
- | |
- $result = ''; | |
- $_REQUEST['cmd'] = '_notify-validate'; | |
- $data = array_merge(array('cmd' => '_notify-validate'), $_REQUEST); | |
- //the txn_type variable absent in case of refund | |
- if (isset($data['txn_type']) && in_array($data['txn_type'], array('cart', 'express_checkout', 'web_accept')) || !isset($data['txn_type'])) { | |
- $order_ids = fn_pp_get_ipn_order_ids($data); | |
- $mode = fn_pp_get_mode(reset($order_ids)); | |
- $url = ($mode == 'test') ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr'; | |
- $result = Http::post($url, $data); | |
- } | |
+ | |
+ list($result, $order_ids, $data) = fn_pp_validate_ipn_payload($_REQUEST); | |
if ($result == 'VERIFIED') { | |
fn_define('ORDER_MANAGEMENT', true); | |
foreach($order_ids as $order_id) { | |
fn_process_paypal_ipn($order_id, $data); | |
+ // unlock order after processing IPN | |
+ fn_pp_set_orders_lock($order_id, false); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/app/addons/paypal/func.php b/app/addons/paypal/func.php | |
index a5ea5b2..ca05037 100644 | |
--- a/app/addons/paypal/func.php | |
+++ b/app/addons/paypal/func.php | |
@@ -1078,3 +1078,88 @@ function fn_paypal_user_init(&$auth, &$user_info, &$first_init) | |
} | |
} | |
} | |
+ | |
+/** | |
+ * Gets list of order identifiers whose IPN is currently processing. | |
+ * | |
+ * @return array Order identifiers | |
+ */ | |
+function fn_pp_get_locked_orders() | |
+{ | |
+ $orders_ids = fn_get_storage_data('paypal_locked_orders'); | |
+ | |
+ if ($orders_ids) { | |
+ return explode(',', $orders_ids); | |
+ } | |
+ | |
+ return array(); | |
+} | |
+ | |
+/** | |
+ * Marks or unmarks orders as processors of IPN. | |
+ * | |
+ * @param array $orders_ids Orders' identifiers | |
+ * @param bool $are_locked True IPN for the orders is currently processing, false if processing is finished | |
+ * @param array $locked_orders_ids Currently locked orders (leave empty to fetch from the DB) | |
+ * @return array | |
+ */ | |
+function fn_pp_set_orders_lock($orders_ids = array(), $are_locked = true, $locked_orders_ids = array()) | |
+{ | |
+ $orders_ids = (array)$orders_ids; | |
+ | |
+ if (!$locked_orders_ids) { | |
+ $locked_orders_ids = fn_pp_get_locked_orders(); | |
+ } | |
+ | |
+ if ($are_locked) { | |
+ $orders_ids = array_unique(array_merge($locked_orders_ids, $orders_ids)); | |
+ } else { | |
+ $orders_ids = array_diff($locked_orders_ids, $orders_ids); | |
+ } | |
+ | |
+ fn_set_storage_data('paypal_locked_orders', implode(',', $orders_ids), true); | |
+ | |
+ return array_values($orders_ids); | |
+} | |
+ | |
+/** | |
+ * Checks if IPN for the order is currently processing. | |
+ * | |
+ * @param int $order_id Order identifier | |
+ * | |
+ * @return bool True if IPN is processing, false otherwise | |
+ */ | |
+function fn_pp_is_order_locked($order_id = 0) | |
+{ | |
+ $locked_order_ids = fn_pp_get_locked_orders(); | |
+ | |
+ return in_array($order_id, $locked_order_ids); | |
+} | |
+ | |
+/** | |
+ * Checks if IPN is sent by PayPal. | |
+ * | |
+ * @param array $data Payload | |
+ * | |
+ * @return array Validation result, orders processed in the IPN and payload for ::fn_process_paypal_ipn() | |
+ */ | |
+function fn_pp_validate_ipn_payload($data) | |
+{ | |
+ $result = ''; | |
+ $order_ids = array(); | |
+ | |
+ unset($data['dispatch']); | |
+ $data['cmd'] = '_notify-validate'; | |
+ $data = array_merge(array('cmd' => '_notify-validate'), $data); | |
+ //the txn_type variable absent in case of refund | |
+ if (isset($data['txn_type']) && in_array($data['txn_type'], array('cart', 'express_checkout', 'web_accept')) || !isset($data['txn_type'])) { | |
+ $order_ids = fn_pp_get_ipn_order_ids($data); | |
+ // lock orders while processing IPN | |
+ fn_pp_set_orders_lock($order_ids, true); | |
+ $mode = fn_pp_get_mode(reset($order_ids)); | |
+ $url = ($mode == 'test') ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr'; | |
+ $result = Http::post($url, $data); | |
+ } | |
+ | |
+ return array($result, $order_ids, $data); | |
+} | |
\ No newline at end of file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/app/addons/paypal/payments/paypal.php b/app/addons/paypal/payments/paypal.php | |
index 45664b4..dca962b 100644 | |
--- a/app/addons/paypal/payments/paypal.php | |
+++ b/app/addons/paypal/payments/paypal.php | |
@@ -45,6 +45,22 @@ if (defined('PAYMENT_NOTIFICATION')) { | |
} | |
} | |
} | |
+ | |
+ // wait for the IPN to be processed | |
+ $is_locked = fn_pp_is_order_locked($_REQUEST['order_id']); | |
+ $time_to_wait = 10; // time to wait for IPN to be processed, seconds | |
+ while ($is_locked && $time_to_wait) { | |
+ sleep(1); | |
+ $time_to_wait--; | |
+ $is_locked = fn_pp_is_order_locked($_REQUEST['order_id']); | |
+ } | |
+ | |
+ // set order's status to Open and wait for the IPN to arrive | |
+ $order_info = fn_get_order_info($_REQUEST['order_id'], true); | |
+ if (fn_pp_get_order_status($order_info) == STATUS_INCOMPLETED_ORDER) { | |
+ fn_change_order_status($_REQUEST['order_id'], 'O', ''); | |
+ } | |
+ | |
fn_order_placement_routines('route', $_REQUEST['order_id'], false); | |
} elseif ($mode == 'cancel') { | |
@@ -142,20 +158,24 @@ if (defined('PAYMENT_NOTIFICATION')) { | |
list($products, $product_count) = fn_pp_standart_prepare_products($order_info, $paypal_currency); | |
$post_data = array_merge($post_data, $products); | |
- if ($order_info['status'] == STATUS_INCOMPLETED_ORDER) { | |
- fn_change_order_status($order_id, 'O', '', false); | |
- } | |
- if (fn_allowed_for('MULTIVENDOR')) { | |
- if ($order_info['status'] == STATUS_PARENT_ORDER) { | |
- $child_orders = db_get_hash_single_array("SELECT order_id, status FROM ?:orders WHERE parent_order_id = ?i", array('order_id', 'status'), $order_id); | |
+ // empty (or no) 'new_order_status' value means that order has to be set to 'open' status | |
+ if (empty($processor_data['processor_params']['new_order_status'])) { | |
+ if ($order_info['status'] == STATUS_INCOMPLETED_ORDER) { | |
+ fn_change_order_status($order_id, 'O', '', false); | |
+ } | |
+ if (fn_allowed_for('MULTIVENDOR')) { | |
+ if ($order_info['status'] == STATUS_PARENT_ORDER) { | |
+ $child_orders = db_get_hash_single_array("SELECT order_id, status FROM ?:orders WHERE parent_order_id = ?i", array('order_id', 'status'), $order_id); | |
- foreach ($child_orders as $order_id => $order_status) { | |
- if ($order_status == STATUS_INCOMPLETED_ORDER) { | |
- fn_change_order_status($order_id, 'O', '', false); | |
+ foreach ($child_orders as $order_id => $order_status) { | |
+ if ($order_status == STATUS_INCOMPLETED_ORDER) { | |
+ fn_change_order_status($order_id, 'O', '', false); | |
+ } | |
} | |
} | |
} | |
} | |
+ | |
fn_pp_save_mode($order_info); | |
fn_create_payment_form($paypal_url, $post_data, 'PayPal server', false); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/design/backend/templates/addons/paypal/views/payments/components/cc_processors/paypal.tpl b/design/backend/templates/addons/paypal/views/payments/components/cc_processors/paypal.tpl | |
index fe8c528..a3ff585 100644 | |
--- a/design/backend/templates/addons/paypal/views/payments/components/cc_processors/paypal.tpl | |
+++ b/design/backend/templates/addons/paypal/views/payments/components/cc_processors/paypal.tpl | |
@@ -41,3 +41,13 @@ | |
<input type="text" name="payment_data[processor_params][order_prefix]" id="order_prefix" value="{$processor_params.order_prefix}" > | |
</div> | |
</div> | |
+ | |
+<div class="control-group"> | |
+ <label class="control-label" for="elm_new_order_status">{__("addons.paypal.status_for_new_orders")}:</label> | |
+ <div class="controls"> | |
+ <select name="payment_data[processor_params][new_order_status]" id="elm_new_order_status"> | |
+ <option value="" {if $processor_params.new_order_status == ""}selected="selected"{/if}>{__("open")}</option> | |
+ <option value="{$smarty.const.STATUS_INCOMPLETED_ORDER}" {if $processor_params.new_order_status == "{$smarty.const.STATUS_INCOMPLETED_ORDER}"}selected="selected"{/if}>{__("incompleted")}</option> | |
+ </select> | |
+ </div> | |
+</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment