Version Description
Download this release
Release Info
Developer | mercadopago |
Plugin | WooCommerce MercadoPago |
Version | 4.0.1-Beta |
Comparing to | |
See all releases |
Code changes from version 4.0.0-Beta to 4.0.1-Beta
includes/module/preference/WC_WooMercadoPago_PreferencePSE.php
DELETED
@@ -1,73 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Part of Woo Mercado Pago Module
|
4 |
-
* Author - Mercado Pago
|
5 |
-
* Developer
|
6 |
-
* Copyright - Copyright(c) MercadoPago [https://www.mercadopago.com]
|
7 |
-
* License - https://www.gnu.org/licenses/gpl.html GPL version 2 or higher
|
8 |
-
*/
|
9 |
-
|
10 |
-
class WC_WooMercadoPago_PreferencePSE extends WC_WooMercadoPago_PreferenceAbstract
|
11 |
-
{
|
12 |
-
/**
|
13 |
-
* WC_WooMercadoPago_PreferencePSE constructor.
|
14 |
-
* @param $order
|
15 |
-
* @param $pse_checkout
|
16 |
-
*/
|
17 |
-
public function __construct($order, $pse_checkout)
|
18 |
-
{
|
19 |
-
parent::__construct($order, $pse_checkout);
|
20 |
-
|
21 |
-
$this->preference['transaction_amount'] = $this->get_transaction_amount();
|
22 |
-
$this->preference['description'] = implode(', ', $this->list_of_items);
|
23 |
-
$this->preference['payment_method_id'] = $this->checkout['paymentMethodId'];
|
24 |
-
$this->preference['payer']['email'] = $this->get_email();
|
25 |
-
$this->preference['statement_descriptor'] = $this->payment->getOption('mp_statement_descriptor', 'Mercado Pago');
|
26 |
-
$this->preference['additional_info']['items'] = $this->items;
|
27 |
-
$this->preference['additional_info']['payer'] = $this->get_payer_custom();
|
28 |
-
$this->preference['additional_info']['shipments'] = $this->shipments_receiver_address();
|
29 |
-
if ($this->ship_cost > 0) {
|
30 |
-
$this->preference['additional_info']['items'][] = $this->ship_cost_item();
|
31 |
-
}
|
32 |
-
if (
|
33 |
-
isset($this->checkout['discount']) && !empty($this->checkout['discount']) &&
|
34 |
-
isset($this->checkout['coupon_code']) && !empty($this->checkout['coupon_code']) &&
|
35 |
-
$this->checkout['discount'] > 0 && WC()->session->chosen_payment_method == 'woo-mercado-pago-ticket'
|
36 |
-
) {
|
37 |
-
$this->preference['additional_info']['items'][] = $this->add_discounts();
|
38 |
-
}
|
39 |
-
|
40 |
-
// PSE Fields
|
41 |
-
if( $this->checkout['paymentMethodId'] == 'pse' ) {
|
42 |
-
$this->preferences['additional_info']['ip_address'] = $this->get_ip();
|
43 |
-
$this->preferences['payer']['identification'] = array(
|
44 |
-
'type' => $this->checkout['docType'],
|
45 |
-
'number' => $this->checkout['docNumber'],
|
46 |
-
);
|
47 |
-
$this->preferences['transaction_details'] = array(
|
48 |
-
'financial_institution' => $this->checkout['bank']
|
49 |
-
);
|
50 |
-
$this->preferences['payer']['entity_type'] = $this->checkout['personType'];
|
51 |
-
}
|
52 |
-
|
53 |
-
$this->add_discounts_campaign();
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* get_ip
|
58 |
-
*
|
59 |
-
* @return string
|
60 |
-
*/
|
61 |
-
public function get_ip()
|
62 |
-
{
|
63 |
-
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
64 |
-
return $_SERVER['HTTP_CLIENT_IP'];
|
65 |
-
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
66 |
-
return $_SERVER['HTTP_X_FORWARDED_FOR'];
|
67 |
-
} else {
|
68 |
-
return $_SERVER['REMOTE_ADDR'];
|
69 |
-
}
|
70 |
-
return '';
|
71 |
-
}
|
72 |
-
|
73 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/payments/WC_WooMercadoPago_PSEGateway.php
DELETED
@@ -1,906 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
//
|
3 |
-
///**
|
4 |
-
// * Class WC_WooMercadoPago_PSEGateway
|
5 |
-
// */
|
6 |
-
//class WC_WooMercadoPago_PSEGateway extends WC_WooMercadoPago_PaymentAbstract
|
7 |
-
//{
|
8 |
-
// const FIELD_FORMS_ORDER = array();
|
9 |
-
//
|
10 |
-
// /**
|
11 |
-
// * WC_WooMercadoPago_PSEGateway constructor.
|
12 |
-
// */
|
13 |
-
// public function __construct()
|
14 |
-
// {
|
15 |
-
// $this->id = 'woo-mercado-pago-pse';
|
16 |
-
// $this->method_title = __('Mercado Pago - PSE', 'woocommerce-mercadopago');
|
17 |
-
// $this->method_description = $this->getMethodDescription('We give you the possibility to adapt the payment experience you want to offer 100% in your website, mobile app or anywhere you want. You can build the design that best fits your business model, aiming to maximize conversion.');
|
18 |
-
// $this->title = get_option('title', __('Mercado Pago - PSE', 'woocommerce-mercadopago'));
|
19 |
-
// $this->coupon_mode = get_option('coupon_mode', 'no');
|
20 |
-
// $this->installments = get_option('installments', '24');
|
21 |
-
// $this->stock_reduce_mode = get_option('stock_reduce_mode', 'no');
|
22 |
-
// $this->gateway_discount = get_option('gateway_discount', 0);
|
23 |
-
// parent::__construct();
|
24 |
-
// $this->form_fields = $this->getFormFields('PSE');
|
25 |
-
// $this->hook = new WC_WooMercadoPago_Hook_Pse($this);
|
26 |
-
// }
|
27 |
-
//
|
28 |
-
// /**
|
29 |
-
// * @param $label
|
30 |
-
// * @return array
|
31 |
-
// */
|
32 |
-
// public function getFormFields($label)
|
33 |
-
// {
|
34 |
-
// $form_fields_abs = parent::getFormFields($label);
|
35 |
-
// if (count($form_fields_abs) == 1) {
|
36 |
-
// return $form_fields_abs;
|
37 |
-
// }
|
38 |
-
// $form_fields = $this->sortFormFields($form_fields_abs, self::FIELD_FORMS_ORDER);
|
39 |
-
// return $form_fields;
|
40 |
-
// }
|
41 |
-
//
|
42 |
-
// /**
|
43 |
-
// * Handles the manual order refunding in server-side.
|
44 |
-
// */
|
45 |
-
// public function process_refund($order_id, $amount = null, $reason = '')
|
46 |
-
// {
|
47 |
-
//
|
48 |
-
// $payments = get_post_meta($order_id, '_Mercado_Pago_Payment_IDs', true);
|
49 |
-
//
|
50 |
-
// // Validate.
|
51 |
-
// if ($this->mp == null || empty($payments)) {
|
52 |
-
// $this->write_log(__FUNCTION__, 'no payments or credentials invalid');
|
53 |
-
// return false;
|
54 |
-
// }
|
55 |
-
//
|
56 |
-
// // Processing data about this refund.
|
57 |
-
// $total_available = 0;
|
58 |
-
// $payment_structs = array();
|
59 |
-
// $payment_ids = explode(', ', $payments);
|
60 |
-
// foreach ($payment_ids as $p_id) {
|
61 |
-
// $p = get_post_meta($order_id, 'Mercado Pago - Payment ' . $p_id, true);
|
62 |
-
// $p = explode('/', $p);
|
63 |
-
// $paid_arr = explode(' ', substr($p[2], 1, -1));
|
64 |
-
// $paid = ((float)$paid_arr[1]);
|
65 |
-
// $refund_arr = explode(' ', substr($p[3], 1, -1));
|
66 |
-
// $refund = ((float)$refund_arr[1]);
|
67 |
-
// $p_struct = array('id' => $p_id, 'available_to_refund' => $paid - $refund);
|
68 |
-
// $total_available += $paid - $refund;
|
69 |
-
// $payment_structs[] = $p_struct;
|
70 |
-
// }
|
71 |
-
//
|
72 |
-
// $this->write_log(__FUNCTION__,
|
73 |
-
// 'refunding ' . $amount . ' because of ' . $reason . ' and payments ' .
|
74 |
-
// json_encode($payment_structs, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
75 |
-
// );
|
76 |
-
//
|
77 |
-
// // Do not allow refund more than available or invalid amounts.
|
78 |
-
// if ($amount > $total_available || $amount <= 0) {
|
79 |
-
// return false;
|
80 |
-
// }
|
81 |
-
//
|
82 |
-
// // Iteratively refunfind amount, taking in consideration multiple payments.
|
83 |
-
// $remaining_to_refund = $amount;
|
84 |
-
// foreach ($payment_structs as $to_refund) {
|
85 |
-
// if ($remaining_to_refund <= $to_refund['available_to_refund']) {
|
86 |
-
// // We want to refund an amount that is less than the available for this payment, so we
|
87 |
-
// // can just refund and return.
|
88 |
-
// $response = $this->mp->partial_refund_payment(
|
89 |
-
// $to_refund['id'], $remaining_to_refund,
|
90 |
-
// $reason, $this->invoice_prefix . $order_id
|
91 |
-
// );
|
92 |
-
// $message = $response['response']['message'];
|
93 |
-
// $status = $response['status'];
|
94 |
-
// $this->write_log(__FUNCTION__,
|
95 |
-
// 'refund payment of id ' . $p_id . ' => ' .
|
96 |
-
// ($status >= 200 && $status < 300 ? 'SUCCESS' : 'FAIL - ' . $message)
|
97 |
-
// );
|
98 |
-
// if ($status >= 200 && $status < 300) {
|
99 |
-
// return true;
|
100 |
-
// } else {
|
101 |
-
// return false;
|
102 |
-
// }
|
103 |
-
// } elseif ($to_refund['available_to_refund'] > 0) {
|
104 |
-
// // We want to refund an amount that exceeds the available for this payment, so we
|
105 |
-
// // totally refund this payment, and try to complete refund in other/next payments.
|
106 |
-
// $response = $this->mp->partial_refund_payment(
|
107 |
-
// $to_refund['id'], $to_refund['available_to_refund'],
|
108 |
-
// $reason, $this->invoice_prefix . $order_id
|
109 |
-
// );
|
110 |
-
// $message = $response['response']['message'];
|
111 |
-
// $status = $response['status'];
|
112 |
-
// $this->write_log(__FUNCTION__,
|
113 |
-
// 'refund payment of id ' . $p_id . ' => ' .
|
114 |
-
// ($status >= 200 && $status < 300 ? 'SUCCESS' : 'FAIL - ' . $message)
|
115 |
-
// );
|
116 |
-
// if ($status < 200 || $status >= 300) {
|
117 |
-
// return false;
|
118 |
-
// }
|
119 |
-
// $remaining_to_refund -= $to_refund['available_to_refund'];
|
120 |
-
// }
|
121 |
-
// if ($remaining_to_refund == 0)
|
122 |
-
// return true;
|
123 |
-
// }
|
124 |
-
//
|
125 |
-
// // Reaching here means that there we run out of payments, and there is an amount
|
126 |
-
// // remaining to be refund, which is impossible as it implies refunding more than
|
127 |
-
// // available on paid amounts.
|
128 |
-
// return false;
|
129 |
-
// }
|
130 |
-
//
|
131 |
-
//
|
132 |
-
// /*
|
133 |
-
// * ========================================================================
|
134 |
-
// * CHECKOUT BUSINESS RULES (CLIENT SIDE)
|
135 |
-
// * ========================================================================
|
136 |
-
// */
|
137 |
-
//
|
138 |
-
// public function add_mp_settings_script_pse()
|
139 |
-
// {
|
140 |
-
// $client_id = WC_WooMercadoPago_Module::get_client_id(get_option('_mp_access_token'));
|
141 |
-
// $is_test_user = get_option('_test_user_v1', false);
|
142 |
-
// if (!empty($client_id) && !$is_test_user) {
|
143 |
-
// $w = WC_WooMercadoPago_Module::woocommerce_instance();
|
144 |
-
// $available_payments = array();
|
145 |
-
// $gateways = WC()->payment_gateways->get_available_payment_gateways();
|
146 |
-
// foreach ($gateways as $g) {
|
147 |
-
// $available_payments[] = $g->id;
|
148 |
-
// }
|
149 |
-
// $available_payments = str_replace('-', '_', implode(', ', $available_payments));
|
150 |
-
// if (wp_get_current_user()->ID != 0) {
|
151 |
-
// $logged_user_email = wp_get_current_user()->user_email;
|
152 |
-
// } else {
|
153 |
-
// $logged_user_email = null;
|
154 |
-
// }
|
155 |
-
// ?>
|
156 |
-
<!-- <script src="https://secure.mlstatic.com/modules/javascript/analytics.js"></script>-->
|
157 |
-
<!-- <script type="text/javascript">-->
|
158 |
-
<!-- try {-->
|
159 |
-
<!-- var MA = ModuleAnalytics;-->
|
160 |
-
<!-- MA.setToken('--><?php //echo $client_id; ?>//');
|
161 |
-
// MA.setPlatform('WooCommerce');
|
162 |
-
// MA.setPlatformVersion('<?php //echo $w->version; ?>//');
|
163 |
-
// MA.setModuleVersion('<?php //echo WC_WooMercadoPago_Module::VERSION; ?>//');
|
164 |
-
// MA.setPayerEmail('<?php //echo($logged_user_email != null ? $logged_user_email : ""); ?>//');
|
165 |
-
// MA.setUserLogged( <?php //echo(empty($logged_user_email) ? 0 : 1); ?>// );
|
166 |
-
// MA.setInstalledModules('<?php //echo $available_payments; ?>//');
|
167 |
-
// MA.post();
|
168 |
-
// } catch (err) {
|
169 |
-
// }
|
170 |
-
// </script>
|
171 |
-
// <?php
|
172 |
-
// }
|
173 |
-
// }
|
174 |
-
//
|
175 |
-
//
|
176 |
-
// public function payment_fields()
|
177 |
-
// {
|
178 |
-
//
|
179 |
-
// $amount = $this->get_order_total();
|
180 |
-
// $logged_user_email = (wp_get_current_user()->ID != 0) ? wp_get_current_user()->user_email : null;
|
181 |
-
// $customer = isset($logged_user_email) ? $this->mp->get_or_create_customer($logged_user_email) : null;
|
182 |
-
// $discount_action_url = get_site_url() . '/index.php/woocommerce-mercadopago/?wc-api=WC_WooMercadoPago_PSEGateway';
|
183 |
-
// $address = get_user_meta(wp_get_current_user()->ID, 'shipping_address_1', true);
|
184 |
-
// $address_2 = get_user_meta(wp_get_current_user()->ID, 'shipping_address_2', true);
|
185 |
-
// $address .= (!empty($address_2) ? ' - ' . $address_2 : '');
|
186 |
-
// $country = get_user_meta(wp_get_current_user()->ID, 'shipping_country', true);
|
187 |
-
// $address .= (!empty($country) ? ' - ' . $country : '');
|
188 |
-
//
|
189 |
-
// $currency_ratio = 1;
|
190 |
-
// $_mp_currency_conversion_v1 = get_option('_mp_currency_conversion_v1', '');
|
191 |
-
// if (!empty($_mp_currency_conversion_v1)) {
|
192 |
-
// $currency_ratio = WC_WooMercadoPago_Module::get_conversion_rate($this->site_data['currency']);
|
193 |
-
// $currency_ratio = $currency_ratio > 0 ? $currency_ratio : 1;
|
194 |
-
// }
|
195 |
-
//
|
196 |
-
// $payment_methods = $this->mp->get_payment_methods();
|
197 |
-
// $financial_institutions = null;
|
198 |
-
// if ($payment_methods['status'] == '200') {
|
199 |
-
// foreach ($payment_methods['response'] as $payment_method) {
|
200 |
-
// if ($payment_method['id'] == 'pse') {
|
201 |
-
// $financial_institutions = $payment_method['financial_institutions'];
|
202 |
-
// }
|
203 |
-
// }
|
204 |
-
// }
|
205 |
-
//
|
206 |
-
//
|
207 |
-
// $parameters = array(
|
208 |
-
// 'amount' => $amount,
|
209 |
-
// // ===
|
210 |
-
// 'site_id' => get_option('_site_id_v1'),
|
211 |
-
//// 'coupon_mode' => isset( $logged_user_email ) ? $this->coupon_mode : 'no',
|
212 |
-
// 'discount_action_url' => $discount_action_url,
|
213 |
-
// 'payer_email' => $logged_user_email,
|
214 |
-
// // ===
|
215 |
-
// 'images_path' => plugins_url('assets/images/', plugin_dir_path(__FILE__)),
|
216 |
-
// 'currency_ratio' => $currency_ratio,
|
217 |
-
// 'woocommerce_currency' => get_woocommerce_currency(),
|
218 |
-
// 'account_currency' => $this->site_data['currency'],
|
219 |
-
// // ===
|
220 |
-
// 'financial_institutions' => $financial_institutions,
|
221 |
-
// 'pse_data' => array(
|
222 |
-
// 'docType' => '',
|
223 |
-
// 'docNumber' => '',
|
224 |
-
// 'bank' => '',
|
225 |
-
// 'personType' => ''
|
226 |
-
// ),
|
227 |
-
// 'path_to_javascript' => plugins_url('../../assets/js/pse.js', plugin_dir_path(__FILE__))
|
228 |
-
// );
|
229 |
-
//
|
230 |
-
// wc_get_template(
|
231 |
-
// 'pse/pse-form.php',
|
232 |
-
// $parameters,
|
233 |
-
// 'woo/mercado/pago/module/',
|
234 |
-
// WC_WooMercadoPago_Module::get_templates_path()
|
235 |
-
// );
|
236 |
-
// }
|
237 |
-
//
|
238 |
-
// /**
|
239 |
-
// * Summary: Handle the payment and processing the order.
|
240 |
-
// * Description: This function is called after we click on [place_order] button, and each field is
|
241 |
-
// * passed to this function through $_POST variable.
|
242 |
-
// * @return an array containing the result of the processment and the URL to redirect.
|
243 |
-
// */
|
244 |
-
// public function process_payment($order_id)
|
245 |
-
// {
|
246 |
-
//
|
247 |
-
// if (!isset($_POST['mercadopago_pse'])) {
|
248 |
-
// return;
|
249 |
-
// }
|
250 |
-
// $pse_checkout = apply_filters('wc_mercadopagopse_pse_checkout', $_POST['mercadopago_pse']);
|
251 |
-
//
|
252 |
-
// $order = wc_get_order($order_id);
|
253 |
-
//
|
254 |
-
// if (method_exists($order, 'update_meta_data')) {
|
255 |
-
// $order->update_meta_data('_used_gateway', 'WC_WooMercadoPago_PSEGateway');
|
256 |
-
// $order->save();
|
257 |
-
// } else {
|
258 |
-
// update_post_meta($order_id, '_used_gateway', 'WC_WooMercadoPago_PSEGateway');
|
259 |
-
// }
|
260 |
-
//
|
261 |
-
// // Check fullfilment of PSE form.
|
262 |
-
// if (get_option('_site_id_v1') == 'MCO') {
|
263 |
-
// if (!isset($pse_checkout['docType']) || empty($pse_checkout['docType']) ||
|
264 |
-
// !isset($pse_checkout['docNumber']) || empty($pse_checkout['docNumber']) ||
|
265 |
-
// !isset($pse_checkout['bank']) || empty($pse_checkout['bank']) ||
|
266 |
-
// !isset($pse_checkout['personType']) || empty($pse_checkout['personType'])) {
|
267 |
-
// wc_add_notice(
|
268 |
-
// '<p>' .
|
269 |
-
// __('A problem was occurred when processing your payment. Are you sure you have correctly filled all information in the checkout form?', 'woocommerce-mercadopago') .
|
270 |
-
// '</p>',
|
271 |
-
// 'error'
|
272 |
-
// );
|
273 |
-
// return array(
|
274 |
-
// 'result' => 'fail',
|
275 |
-
// 'redirect' => '',
|
276 |
-
// );
|
277 |
-
// }
|
278 |
-
// }
|
279 |
-
//
|
280 |
-
// if (isset($pse_checkout['amount']) && !empty($pse_checkout['amount']) &&
|
281 |
-
// isset($pse_checkout['paymentMethodId']) && !empty($pse_checkout['paymentMethodId'])) {
|
282 |
-
//
|
283 |
-
// $response = $this->create_url($order, $pse_checkout);
|
284 |
-
//
|
285 |
-
// if (array_key_exists('status', $response)) {
|
286 |
-
// if ($response['status'] == 'pending') {
|
287 |
-
// if ($response['status_detail'] == 'pending_waiting_transfer') {
|
288 |
-
// WC()->cart->empty_cart();
|
289 |
-
// if ($this->stock_reduce_mode == 'yes') {
|
290 |
-
// $order->reduce_order_stock();
|
291 |
-
// }
|
292 |
-
// // WooCommerce 3.0 or later.
|
293 |
-
// if (method_exists($order, 'update_meta_data')) {
|
294 |
-
// $order->update_meta_data('_transaction_details_pse', $response['transaction_details']['external_resource_url']);
|
295 |
-
// $order->save();
|
296 |
-
// } else {
|
297 |
-
// update_post_meta(
|
298 |
-
// $order->id,
|
299 |
-
// '_transaction_details_pse',
|
300 |
-
// $response['transaction_details']['external_resource_url']
|
301 |
-
// );
|
302 |
-
// }
|
303 |
-
// // Shows some info in checkout page.
|
304 |
-
// $order->add_order_note(
|
305 |
-
// 'Mercado Pago: ' .
|
306 |
-
// __('Customer haven\'t paid yet.', 'woocommerce-mercadopago')
|
307 |
-
// );
|
308 |
-
// $order->add_order_note(
|
309 |
-
// 'Mercado Pago: ' .
|
310 |
-
// __('Link to bank transfer ', 'woocommerce-mercadopago') .
|
311 |
-
// '<a target="_blank" href="' .
|
312 |
-
// $response['transaction_details']['external_resource_url'] . '">' .
|
313 |
-
// __('here', 'woocommerce-mercadopago') .
|
314 |
-
// '</a>', 1, false
|
315 |
-
// );
|
316 |
-
// return array(
|
317 |
-
// 'result' => 'success',
|
318 |
-
// 'redirect' => $order->get_checkout_order_received_url()
|
319 |
-
// );
|
320 |
-
// }
|
321 |
-
// }
|
322 |
-
// } else {
|
323 |
-
// // Process when fields are imcomplete.
|
324 |
-
// wc_add_notice(
|
325 |
-
// '<p>' .
|
326 |
-
// __('A problem was occurred when processing your payment. Are you sure you have correctly filled all information in the checkout form? ', 'woocommerce-mercadopago') . ' MERCADO PAGO: ' .
|
327 |
-
// WC_WooMercadoPago_Module::get_common_error_messages($response) .
|
328 |
-
// '</p>',
|
329 |
-
// 'error'
|
330 |
-
// );
|
331 |
-
// return array(
|
332 |
-
// 'result' => 'fail',
|
333 |
-
// 'redirect' => '',
|
334 |
-
// );
|
335 |
-
// }
|
336 |
-
// } else {
|
337 |
-
// // Process when fields are imcomplete.
|
338 |
-
// wc_add_notice(
|
339 |
-
// '<p>' .
|
340 |
-
// __('A problem was occurred when processing your payment. Please, try again.', 'woocommerce-mercadopago') .
|
341 |
-
// '</p>',
|
342 |
-
// 'error'
|
343 |
-
// );
|
344 |
-
// return array(
|
345 |
-
// 'result' => 'fail',
|
346 |
-
// 'redirect' => '',
|
347 |
-
// );
|
348 |
-
// }
|
349 |
-
//
|
350 |
-
// }
|
351 |
-
//
|
352 |
-
// /**
|
353 |
-
// * Summary: Build Mercado Pago preference.
|
354 |
-
// * Description: Create Mercado Pago preference and get init_point URL based in the order options
|
355 |
-
// * from the cart.
|
356 |
-
// * @return the preference object.
|
357 |
-
// */
|
358 |
-
// private function build_payment_preference($order, $pse_checkout)
|
359 |
-
// {
|
360 |
-
//
|
361 |
-
// // A string to register items (workaround to deal with API problem that shows only first item).
|
362 |
-
// $items = array();
|
363 |
-
// $order_total = 0;
|
364 |
-
// $list_of_items = array();
|
365 |
-
// // Find currency rate.
|
366 |
-
// $currency_ratio = 1;
|
367 |
-
// $_mp_currency_conversion_v1 = get_option('_mp_currency_conversion_v1', '');
|
368 |
-
// if (!empty($_mp_currency_conversion_v1)) {
|
369 |
-
// $currency_ratio = WC_WooMercadoPago_Module::get_conversion_rate($this->site_data['currency']);
|
370 |
-
// $currency_ratio = $currency_ratio > 0 ? $currency_ratio : 1;
|
371 |
-
// }
|
372 |
-
//
|
373 |
-
// // Here we build the array that contains ordered items, from customer cart.
|
374 |
-
// if (sizeof($order->get_items()) > 0) {
|
375 |
-
// foreach ($order->get_items() as $item) {
|
376 |
-
// if ($item['qty']) {
|
377 |
-
// $product = new WC_product($item['product_id']);
|
378 |
-
// $product_title = method_exists($product, 'get_description') ?
|
379 |
-
// $product->get_name() :
|
380 |
-
// $product->post->post_title;
|
381 |
-
// $product_content = method_exists($product, 'get_description') ?
|
382 |
-
// $product->get_description() :
|
383 |
-
// $product->post->post_content;
|
384 |
-
// // Calculates line amount and discounts.
|
385 |
-
// $line_amount = $item['line_total'] + $item['line_tax'];
|
386 |
-
// $discount_by_gateway = (float)$line_amount * ($this->gateway_discount / 100);
|
387 |
-
// $order_total += ($line_amount - $discount_by_gateway);
|
388 |
-
// // Add the item.
|
389 |
-
// array_push($list_of_items, $product_title . ' x ' . $item['qty']);
|
390 |
-
// array_push($items, array(
|
391 |
-
// 'id' => $item['product_id'],
|
392 |
-
// 'title' => html_entity_decode($product_title) . ' x ' . $item['qty'],
|
393 |
-
// 'description' => sanitize_file_name(html_entity_decode(
|
394 |
-
// strlen($product_content) > 230 ?
|
395 |
-
// substr($product_content, 0, 230) . '...' :
|
396 |
-
// $product_content
|
397 |
-
// )),
|
398 |
-
// 'picture_url' => sizeof($order->get_items()) > 1 ?
|
399 |
-
// plugins_url('assets/images/cart.png', plugin_dir_path(__FILE__)) :
|
400 |
-
// wp_get_attachment_url($product->get_image_id()),
|
401 |
-
// 'category_id' => get_option('_mp_category_name', 'others'),
|
402 |
-
// 'quantity' => 1,
|
403 |
-
// 'unit_price' => ($this->site_data['currency'] == 'COP' || $this->site_data['currency'] == 'CLP') ?
|
404 |
-
// floor(($line_amount - $discount_by_gateway) * $currency_ratio) :
|
405 |
-
// floor(($line_amount - $discount_by_gateway) * $currency_ratio * 100) / 100
|
406 |
-
// ));
|
407 |
-
// }
|
408 |
-
// }
|
409 |
-
// }
|
410 |
-
//
|
411 |
-
// // Creates the shipment cost structure.
|
412 |
-
// $ship_cost = ($order->get_total_shipping() + $order->get_shipping_tax());
|
413 |
-
// if ($ship_cost > 0) {
|
414 |
-
// $order_total += $ship_cost;
|
415 |
-
// $item = array(
|
416 |
-
// 'title' => method_exists($order, 'get_id') ?
|
417 |
-
// $order->get_shipping_method() :
|
418 |
-
// $order->shipping_method,
|
419 |
-
// 'description' => __('Shipping service used by store', 'woocommerce-mercadopago'),
|
420 |
-
// 'category_id' => get_option('_mp_category_name', 'others'),
|
421 |
-
// 'quantity' => 1,
|
422 |
-
// 'unit_price' => ($this->site_data['currency'] == 'COP' || $this->site_data['currency'] == 'CLP') ?
|
423 |
-
// floor($ship_cost * $currency_ratio) :
|
424 |
-
// floor($ship_cost * $currency_ratio * 100) / 100
|
425 |
-
// );
|
426 |
-
// $items[] = $item;
|
427 |
-
// }
|
428 |
-
//
|
429 |
-
// // Discounts features.
|
430 |
-
// if (isset($pse_checkout['discount']) && !empty($pse_checkout['discount']) &&
|
431 |
-
// isset($pse_checkout['coupon_code']) && !empty($pse_checkout['coupon_code']) &&
|
432 |
-
// $pse_checkout['discount'] > 0 && WC()->session->chosen_payment_method == 'woo-mercado-pago-pse') {
|
433 |
-
// $item = array(
|
434 |
-
// 'title' => __('Discount provided by store', 'woocommerce-mercadopago'),
|
435 |
-
// 'description' => __('Discount provided by store', 'woocommerce-mercadopago'),
|
436 |
-
// 'category_id' => get_option('_mp_category_name', 'others'),
|
437 |
-
// 'quantity' => 1,
|
438 |
-
// 'unit_price' => ($this->site_data['currency'] == 'COP' || $this->site_data['currency'] == 'CLP') ?
|
439 |
-
// -floor($pse_checkout['discount'] * $currency_ratio) :
|
440 |
-
// -floor($pse_checkout['discount'] * $currency_ratio * 100) / 100
|
441 |
-
// );
|
442 |
-
// $items[] = $item;
|
443 |
-
// }
|
444 |
-
//
|
445 |
-
// // Build additional information from the customer data.
|
446 |
-
// $payer_additional_info = array(
|
447 |
-
// 'first_name' => (method_exists($order, 'get_id') ?
|
448 |
-
// html_entity_decode($order->get_billing_first_name()) :
|
449 |
-
// html_entity_decode($order->billing_first_name)),
|
450 |
-
// 'last_name' => (method_exists($order, 'get_id') ?
|
451 |
-
// html_entity_decode($order->get_billing_last_name()) :
|
452 |
-
// html_entity_decode($order->billing_last_name)),
|
453 |
-
// //'registration_date' =>
|
454 |
-
// 'phone' => array(
|
455 |
-
// //'area_code' =>
|
456 |
-
// 'number' => (method_exists($order, 'get_id') ?
|
457 |
-
// $order->get_billing_phone() :
|
458 |
-
// $order->billing_phone)
|
459 |
-
// ),
|
460 |
-
// 'address' => array(
|
461 |
-
// 'zip_code' => (method_exists($order, 'get_id') ?
|
462 |
-
// $order->get_billing_postcode() :
|
463 |
-
// $order->billing_postcode
|
464 |
-
// ),
|
465 |
-
// //'street_number' =>
|
466 |
-
// 'street_name' => html_entity_decode(method_exists($order, 'get_id') ?
|
467 |
-
// $order->get_billing_address_1() . ' / ' .
|
468 |
-
// $order->get_billing_city() . ' ' .
|
469 |
-
// $order->get_billing_state() . ' ' .
|
470 |
-
// $order->get_billing_country() :
|
471 |
-
// $order->billing_address_1 . ' / ' .
|
472 |
-
// $order->billing_city . ' ' .
|
473 |
-
// $order->billing_state . ' ' .
|
474 |
-
// $order->billing_country
|
475 |
-
// )
|
476 |
-
// )
|
477 |
-
// );
|
478 |
-
//
|
479 |
-
// // Create the shipment address information set.
|
480 |
-
// $shipments = array(
|
481 |
-
// 'receiver_address' => array(
|
482 |
-
// 'zip_code' => method_exists($order, 'get_id') ?
|
483 |
-
// $order->get_shipping_postcode() :
|
484 |
-
// $order->shipping_postcode,
|
485 |
-
// //'street_number' =>
|
486 |
-
// 'street_name' => html_entity_decode(method_exists($order, 'get_id') ?
|
487 |
-
// $order->get_shipping_address_1() . ' ' .
|
488 |
-
// $order->get_shipping_address_2() . ' ' .
|
489 |
-
// $order->get_shipping_city() . ' ' .
|
490 |
-
// $order->get_shipping_state() . ' ' .
|
491 |
-
// $order->get_shipping_country() :
|
492 |
-
// $order->shipping_address_1 . ' ' .
|
493 |
-
// $order->shipping_address_2 . ' ' .
|
494 |
-
// $order->shipping_city . ' ' .
|
495 |
-
// $order->shipping_state . ' ' .
|
496 |
-
// $order->shipping_country
|
497 |
-
// ),
|
498 |
-
// //'floor' =>
|
499 |
-
// 'apartment' => method_exists($order, 'get_id') ?
|
500 |
-
// $order->get_shipping_address_2() :
|
501 |
-
// $order->shipping_address_2
|
502 |
-
// )
|
503 |
-
// );
|
504 |
-
//
|
505 |
-
// $ip = "";
|
506 |
-
// if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
507 |
-
// $ip = $_SERVER['HTTP_CLIENT_IP'];
|
508 |
-
// } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
509 |
-
// $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
510 |
-
// } else {
|
511 |
-
// $ip = $_SERVER['REMOTE_ADDR'];
|
512 |
-
// }
|
513 |
-
//
|
514 |
-
// // The payment preference.
|
515 |
-
// $preferences = array(
|
516 |
-
// 'date_of_expiration' => $date_of_expiration,
|
517 |
-
// 'transaction_amount' => ($this->site_data['currency'] == 'COP' || $this->site_data['currency'] == 'CLP') ?
|
518 |
-
// floor($order_total * $currency_ratio) :
|
519 |
-
// floor($order_total * $currency_ratio * 100) / 100,
|
520 |
-
// 'description' => implode(', ', $list_of_items),
|
521 |
-
// 'payment_method_id' => $pse_checkout['paymentMethodId'],
|
522 |
-
// 'payer' => array(
|
523 |
-
// 'email' => method_exists($order, 'get_id') ?
|
524 |
-
// $order->get_billing_email() :
|
525 |
-
// $order->billing_email
|
526 |
-
// ),
|
527 |
-
// 'external_reference' => get_option('_mp_store_identificator', 'WC-') .
|
528 |
-
// (method_exists($order, 'get_id') ? $order->get_id() : $order->id),
|
529 |
-
// 'statement_descriptor' => get_option('_mp_statement_descriptor', 'Mercado Pago'),
|
530 |
-
// 'binary_mode' => ($this->binary_mode == 'yes'),
|
531 |
-
// 'additional_info' => array(
|
532 |
-
// 'items' => $items,
|
533 |
-
// 'payer' => $payer_additional_info,
|
534 |
-
// 'shipments' => $shipments
|
535 |
-
// ),
|
536 |
-
// 'callback_url' => $order->get_checkout_order_received_url()
|
537 |
-
// );
|
538 |
-
//
|
539 |
-
// // PSE Fields
|
540 |
-
// if ($pse_checkout['paymentMethodId'] == 'pse') {
|
541 |
-
// $preferences['additional_info']['ip_address'] = $ip;
|
542 |
-
// $preferences['payer']['identification'] = array(
|
543 |
-
// 'type' => $pse_checkout['docType'],
|
544 |
-
// 'number' => $pse_checkout['docNumber'],
|
545 |
-
// );
|
546 |
-
// $preferences['transaction_details'] = array(
|
547 |
-
// 'financial_institution' => $pse_checkout['bank']
|
548 |
-
// );
|
549 |
-
// $preferences['payer']['entity_type'] = $pse_checkout['personType'];
|
550 |
-
// }
|
551 |
-
//
|
552 |
-
// // Do not set IPN url if it is a localhost.
|
553 |
-
// if (!strrpos(get_site_url(), 'localhost')) {
|
554 |
-
// $notification_url = get_option('_mp_custom_domain', '');
|
555 |
-
// // Check if we have a custom URL.
|
556 |
-
// if (empty($notification_url) || filter_var($notification_url, FILTER_VALIDATE_URL) === FALSE) {
|
557 |
-
// $preferences['notification_url'] = WC()->api_request_url('WC_WooMercadoPago_PSEGateway');
|
558 |
-
// } else {
|
559 |
-
// $preferences['notification_url'] = WC_WooMercadoPago_Module::fix_url_ampersand(esc_url(
|
560 |
-
// $notification_url . '/wc-api/WC_WooMercadoPago_PSEGateway/'
|
561 |
-
// ));
|
562 |
-
// }
|
563 |
-
// }
|
564 |
-
//
|
565 |
-
// // Discounts features.
|
566 |
-
// if (isset($pse_checkout['discount']) && !empty($pse_checkout['discount']) &&
|
567 |
-
// isset($pse_checkout['coupon_code']) && !empty($pse_checkout['coupon_code']) &&
|
568 |
-
// $pse_checkout['discount'] > 0 && WC()->session->chosen_payment_method == 'woo-mercado-pago-pse') {
|
569 |
-
// $preferences['campaign_id'] = (int)$pse_checkout['campaign_id'];
|
570 |
-
// $preferences['coupon_amount'] = ($this->site_data['currency'] == 'COP' || $this->site_data['currency'] == 'CLP') ?
|
571 |
-
// floor($pse_checkout['discount'] * $currency_ratio) :
|
572 |
-
// floor($pse_checkout['discount'] * $currency_ratio * 100) / 100;
|
573 |
-
// $preferences['coupon_code'] = strtoupper($pse_checkout['coupon_code']);
|
574 |
-
// }
|
575 |
-
//
|
576 |
-
// // Set sponsor ID.
|
577 |
-
// $_test_user_v1 = get_option('_test_user_v1', false);
|
578 |
-
// if (!$_test_user_v1) {
|
579 |
-
// $preferences['sponsor_id'] = WC_WooMercadoPago_Module::get_sponsor_id();
|
580 |
-
// }
|
581 |
-
//
|
582 |
-
// // Debug/log this preference.
|
583 |
-
// $this->write_log(
|
584 |
-
// __FUNCTION__,
|
585 |
-
// 'returning just created [$preferences] structure: ' .
|
586 |
-
// json_encode($preferences, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
587 |
-
// );
|
588 |
-
//
|
589 |
-
// return $preferences;
|
590 |
-
// }
|
591 |
-
//
|
592 |
-
// protected function create_url($order, $pse_checkout)
|
593 |
-
// {
|
594 |
-
// // Creates the order parameters by checking the cart configuration.
|
595 |
-
// $preferences = $this->build_payment_preference($order, $pse_checkout);
|
596 |
-
// // Checks for sandbox mode.
|
597 |
-
// $this->mp->sandbox_mode($this->sandbox);
|
598 |
-
// // Create order preferences with Mercado Pago API request.
|
599 |
-
// try {
|
600 |
-
// $checkout_info = $this->mp->create_payment(json_encode($preferences));
|
601 |
-
// if ($checkout_info['status'] < 200 || $checkout_info['status'] >= 300) {
|
602 |
-
// // Mercado Pago throwed an error.
|
603 |
-
// $this->write_log(
|
604 |
-
// __FUNCTION__,
|
605 |
-
// 'mercado pago gave error, payment creation failed with error: ' . $checkout_info['response']['message']
|
606 |
-
// );
|
607 |
-
// return $checkout_info['response']['message'];
|
608 |
-
// } elseif (is_wp_error($checkout_info)) {
|
609 |
-
// // WordPress throwed an error.
|
610 |
-
// $this->write_log(
|
611 |
-
// __FUNCTION__,
|
612 |
-
// 'wordpress gave error, payment creation failed with error: ' . $checkout_info['response']['message']
|
613 |
-
// );
|
614 |
-
// return $checkout_info['response']['message'];
|
615 |
-
// } else {
|
616 |
-
// // Obtain the URL.
|
617 |
-
// $this->write_log(
|
618 |
-
// __FUNCTION__,
|
619 |
-
// 'payment link generated with success from mercado pago, with structure as follow: ' .
|
620 |
-
// json_encode($checkout_info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
621 |
-
// );
|
622 |
-
// // TODO: Verify sandbox availability.
|
623 |
-
// //if ( 'yes' == $this->sandbox ) {
|
624 |
-
// // return $checkout_info['response']['sandbox_init_point'];
|
625 |
-
// //} else {
|
626 |
-
// return $checkout_info['response'];
|
627 |
-
// //}
|
628 |
-
// }
|
629 |
-
// } catch (MercadoPagoException $ex) {
|
630 |
-
// // Something went wrong with the payment creation.
|
631 |
-
// $this->write_log(
|
632 |
-
// __FUNCTION__,
|
633 |
-
// 'payment creation failed with exception: ' .
|
634 |
-
// json_encode($ex, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
635 |
-
// );
|
636 |
-
// return $ex->getMessage();
|
637 |
-
// }
|
638 |
-
// }
|
639 |
-
//
|
640 |
-
// /**
|
641 |
-
// * Summary: Receive post data and applies a discount based in the received values.
|
642 |
-
// * Description: Receive post data and applies a discount based in the received values.
|
643 |
-
// */
|
644 |
-
//
|
645 |
-
//
|
646 |
-
// // Display the discount in payment method title.
|
647 |
-
//
|
648 |
-
//
|
649 |
-
// /*
|
650 |
-
// * ========================================================================
|
651 |
-
// * AUXILIARY AND FEEDBACK METHODS (SERVER SIDE)
|
652 |
-
// * ========================================================================
|
653 |
-
// */
|
654 |
-
//
|
655 |
-
//
|
656 |
-
// /*
|
657 |
-
// * ========================================================================
|
658 |
-
// * IPN MECHANICS (SERVER SIDE)
|
659 |
-
// * ========================================================================
|
660 |
-
// */
|
661 |
-
//
|
662 |
-
// /**
|
663 |
-
// * Summary: This call checks any incoming notifications from Mercado Pago server.
|
664 |
-
// * Description: This call checks any incoming notifications from Mercado Pago server.
|
665 |
-
// */
|
666 |
-
// public function check_ipn_response()
|
667 |
-
// {
|
668 |
-
// @ob_clean();
|
669 |
-
// $this->write_log(
|
670 |
-
// __FUNCTION__,
|
671 |
-
// 'received _get content: ' .
|
672 |
-
// json_encode($_GET, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
673 |
-
// );
|
674 |
-
// // Setup sandbox mode.
|
675 |
-
// $this->mp->sandbox_mode($this->sandbox);
|
676 |
-
// // Over here, $_GET should come with this JSON structure:
|
677 |
-
// // {
|
678 |
-
// // "topic": <string>,
|
679 |
-
// // "id": <string>
|
680 |
-
// // }
|
681 |
-
// // If not, the IPN is corrupted in some way.
|
682 |
-
// $data = $_GET;
|
683 |
-
// if (isset($data['coupon_id']) && !empty($data['coupon_id'])) {
|
684 |
-
// // Process coupon evaluations.
|
685 |
-
// if (isset($data['payer']) && !empty($data['payer'])) {
|
686 |
-
// $response = $this->mp->check_discount_campaigns($data['amount'], $data['payer'], $data['coupon_id']);
|
687 |
-
// header('HTTP/1.1 200 OK');
|
688 |
-
// header('Content-Type: application/json');
|
689 |
-
// echo json_encode($response);
|
690 |
-
// } else {
|
691 |
-
// $obj = new stdClass();
|
692 |
-
// $obj->status = 404;
|
693 |
-
// $obj->response = array(
|
694 |
-
// 'message' => __('Please, inform your email in billing address to use this feature', 'woocommerce-mercadopago'),
|
695 |
-
// 'error' => 'payer_not_found',
|
696 |
-
// 'status' => 404,
|
697 |
-
// 'cause' => array()
|
698 |
-
// );
|
699 |
-
// header('HTTP/1.1 200 OK');
|
700 |
-
// header('Content-Type: application/json');
|
701 |
-
// echo json_encode($obj);
|
702 |
-
// }
|
703 |
-
// exit(0);
|
704 |
-
// } else if (!isset($data['data_id']) || !isset($data['type'])) {
|
705 |
-
// // Received IPN call from v0.
|
706 |
-
// $this->write_log(
|
707 |
-
// __FUNCTION__,
|
708 |
-
// 'data_id or type not set: ' .
|
709 |
-
// json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
710 |
-
// );
|
711 |
-
// if (!isset($data['id']) || !isset($data['topic'])) {
|
712 |
-
// $this->write_log(
|
713 |
-
// __FUNCTION__,
|
714 |
-
// 'Mercado Pago Request failure: ' .
|
715 |
-
// json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
716 |
-
// );
|
717 |
-
// wp_die(__('Mercado Pago Request Failure', 'woocommerce-mercadopago'));
|
718 |
-
// } else {
|
719 |
-
// // At least, check if its a v0 ipn.
|
720 |
-
// header('HTTP/1.1 200 OK');
|
721 |
-
// }
|
722 |
-
// } else {
|
723 |
-
// // Needed informations are present, so start process then.
|
724 |
-
// try {
|
725 |
-
// if ($data['type'] == 'payment') {
|
726 |
-
// $access_token = array('access_token' => $this->mp->get_access_token());
|
727 |
-
// $payment_info = $this->mp->get('/v1/payments/' . $data['data_id'], $access_token, false);
|
728 |
-
// if (!is_wp_error($payment_info) && ($payment_info['status'] == 200 || $payment_info['status'] == 201)) {
|
729 |
-
// if ($payment_info['response']) {
|
730 |
-
// header('HTTP/1.1 200 OK');
|
731 |
-
// do_action('valid_mercadopago_pse_ipn_request', $payment_info['response']);
|
732 |
-
// }
|
733 |
-
// } else {
|
734 |
-
// $this->write_log(
|
735 |
-
// __FUNCTION__,
|
736 |
-
// 'error when processing received data: ' .
|
737 |
-
// json_encode($payment_info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
738 |
-
// );
|
739 |
-
// }
|
740 |
-
// }
|
741 |
-
// } catch (MercadoPagoException $ex) {
|
742 |
-
// $this->write_log(
|
743 |
-
// __FUNCTION__,
|
744 |
-
// 'MercadoPagoException: ' .
|
745 |
-
// json_encode($ex, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
746 |
-
// );
|
747 |
-
// }
|
748 |
-
// }
|
749 |
-
// }
|
750 |
-
//
|
751 |
-
// /**
|
752 |
-
// * Summary: Properly handles each case of notification, based in payment status.
|
753 |
-
// * Description: Properly handles each case of notification, based in payment status.
|
754 |
-
// */
|
755 |
-
// public function successful_request($data)
|
756 |
-
// {
|
757 |
-
// $this->write_log(__FUNCTION__, 'starting to process ipn update...');
|
758 |
-
// // Get the order and check its presence.
|
759 |
-
// $order_key = $data['external_reference'];
|
760 |
-
// if (empty($order_key)) {
|
761 |
-
// return;
|
762 |
-
// }
|
763 |
-
// $invoice_prefix = get_option('_mp_store_identificator', 'WC-');
|
764 |
-
// $id = (int)str_replace($invoice_prefix, '', $order_key);
|
765 |
-
// $order = wc_get_order($id);
|
766 |
-
// // Check if order exists.
|
767 |
-
// if (!$order) {
|
768 |
-
// return;
|
769 |
-
// }
|
770 |
-
// // WooCommerce 3.0 or later.
|
771 |
-
// $order_id = (method_exists($order, 'get_id') ? $order->get_id() : $order->id);
|
772 |
-
// // Check if we have the correct order.
|
773 |
-
// if ($order_id !== $id) {
|
774 |
-
// return;
|
775 |
-
// }
|
776 |
-
// $this->write_log(
|
777 |
-
// __FUNCTION__,
|
778 |
-
// 'updating metadata and status with data: ' .
|
779 |
-
// json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
780 |
-
// );
|
781 |
-
// // Here, we process the status... this is the business rules!
|
782 |
-
// // Reference: https://www.mercadopago.com.br/developers/en/api-docs/basic-checkout/ipn/payment-status/
|
783 |
-
// $status = isset($data['status']) ? $data['status'] : 'pending';
|
784 |
-
// $total_paid = isset($data['transaction_details']['total_paid_amount']) ? $data['transaction_details']['total_paid_amount'] : 0.00;
|
785 |
-
// $total_refund = isset($data['transaction_amount_refunded']) ? $data['transaction_amount_refunded'] : 0.00;
|
786 |
-
// // WooCommerce 3.0 or later.
|
787 |
-
// if (method_exists($order, 'update_meta_data')) {
|
788 |
-
// // Updates the type of gateway.
|
789 |
-
// $order->update_meta_data('_used_gateway', 'WC_WooMercadoPago_PESGateway');
|
790 |
-
// if (!empty($data['payer']['email'])) {
|
791 |
-
// $order->update_meta_data(__('Payer email', 'woocommerce-mercadopago'), $data['payer']['email']);
|
792 |
-
// }
|
793 |
-
// if (!empty($data['payment_type_id'])) {
|
794 |
-
// $order->update_meta_data(__('Payment type', 'woocommerce-mercadopago'), $data['payment_type_id']);
|
795 |
-
// }
|
796 |
-
// $order->update_meta_data(
|
797 |
-
// 'Mercado Pago - Payment ' . $data['id'],
|
798 |
-
// '[Date ' . date('Y-m-d H:i:s', strtotime($data['date_created'])) .
|
799 |
-
// ']/[Amount ' . $data['transaction_amount'] .
|
800 |
-
// ']/[Paid ' . $total_paid .
|
801 |
-
// ']/[Refund ' . $total_refund . ']'
|
802 |
-
// );
|
803 |
-
// $order->update_meta_data('_Mercado_Pago_Payment_IDs', $data['id']);
|
804 |
-
// $order->save();
|
805 |
-
// } else {
|
806 |
-
// // Updates the type of gateway.
|
807 |
-
// update_post_meta($order_id, '_used_gateway', 'WC_WooMercadoPago_PSEGateway');
|
808 |
-
// if (!empty($data['payer']['email'])) {
|
809 |
-
// update_post_meta($order_id, __('Payer email', 'woocommerce-mercadopago'), $data['payer']['email']);
|
810 |
-
// }
|
811 |
-
// if (!empty($data['payment_type_id'])) {
|
812 |
-
// update_post_meta($order_id, __('Payment type', 'woocommerce-mercadopago'), $data['payment_type_id']);
|
813 |
-
// }
|
814 |
-
// update_post_meta(
|
815 |
-
// $order_id,
|
816 |
-
// 'Mercado Pago - Payment ' . $data['id'],
|
817 |
-
// '[Date ' . date('Y-m-d H:i:s', strtotime($data['date_created'])) .
|
818 |
-
// ']/[Amount ' . $data['transaction_amount'] .
|
819 |
-
// ']/[Paid ' . $total_paid .
|
820 |
-
// ']/[Refund ' . $total_refund . ']'
|
821 |
-
// );
|
822 |
-
// update_post_meta($order_id, '_Mercado_Pago_Payment_IDs', $data['id']);
|
823 |
-
// }
|
824 |
-
// // Switch the status and update in WooCommerce.
|
825 |
-
// $this->write_log(
|
826 |
-
// __FUNCTION__,
|
827 |
-
// 'Changing order status to: ' .
|
828 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status(str_replace('_', '', $status))
|
829 |
-
// );
|
830 |
-
// switch ($status) {
|
831 |
-
// case 'approved':
|
832 |
-
// $order->add_order_note(
|
833 |
-
// 'Mercado Pago: ' . __('Payment approved.', 'woocommerce-mercadopago')
|
834 |
-
// );
|
835 |
-
// if ($this->stock_reduce_mode == 'no') {
|
836 |
-
// $order->payment_complete();
|
837 |
-
// }
|
838 |
-
// $order->update_status(
|
839 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('approved')
|
840 |
-
// );
|
841 |
-
// break;
|
842 |
-
// case 'pending':
|
843 |
-
// $order->update_status(
|
844 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('pending')
|
845 |
-
// );
|
846 |
-
// // decrease stock if not yet decreased and order not exists.
|
847 |
-
// $notes = $order->get_customer_order_notes();
|
848 |
-
// $has_note = false;
|
849 |
-
// if (sizeof($notes) > 1) {
|
850 |
-
// $has_note = true;
|
851 |
-
// break;
|
852 |
-
// }
|
853 |
-
// if (!$has_note) {
|
854 |
-
// $order->add_order_note(
|
855 |
-
// 'Mercado Pago: ' . __('Waiting for the bank transfer.', 'woocommerce-mercadopago'),
|
856 |
-
// 1, false
|
857 |
-
// );
|
858 |
-
// }
|
859 |
-
// break;
|
860 |
-
// case 'in_process':
|
861 |
-
// $order->update_status(
|
862 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('on-hold'),
|
863 |
-
// 'Mercado Pago: ' . __('Payment under review.', 'woocommerce-mercadopago')
|
864 |
-
// );
|
865 |
-
// break;
|
866 |
-
// case 'rejected':
|
867 |
-
// $order->update_status(
|
868 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('rejected'),
|
869 |
-
// 'Mercado Pago: ' . __('The payment was refused. The customer can try again.', 'woocommerce-mercadopago')
|
870 |
-
// );
|
871 |
-
// break;
|
872 |
-
// case 'refunded':
|
873 |
-
// $order->update_status(
|
874 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('refunded'),
|
875 |
-
// 'Mercado Pago: ' . __('The payment was refunded to the customer.', 'woocommerce-mercadopago')
|
876 |
-
// );
|
877 |
-
// break;
|
878 |
-
// case 'cancelled':
|
879 |
-
// $this->process_cancel_order_meta_box_actions($order);
|
880 |
-
// $order->update_status(
|
881 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('cancelled'),
|
882 |
-
// 'Mercado Pago: ' . __('The payment was cancelled.', 'woocommerce-mercadopago')
|
883 |
-
// );
|
884 |
-
// break;
|
885 |
-
// case 'in_mediation':
|
886 |
-
// $order->update_status(
|
887 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('inmediation')
|
888 |
-
// );
|
889 |
-
// $order->add_order_note(
|
890 |
-
// 'Mercado Pago: ' . __('The payment is under mediation or it was charged-back.', 'woocommerce-mercadopago')
|
891 |
-
// );
|
892 |
-
// break;
|
893 |
-
// case 'charged-back':
|
894 |
-
// $order->update_status(
|
895 |
-
// WC_WooMercadoPago_Module::get_wc_status_for_mp_status('chargedback')
|
896 |
-
// );
|
897 |
-
// $order->add_order_note(
|
898 |
-
// 'Mercado Pago: ' . __('The payment is under mediation or it was charged-back.', 'woocommerce-mercadopago')
|
899 |
-
// );
|
900 |
-
// break;
|
901 |
-
// default:
|
902 |
-
// break;
|
903 |
-
// }
|
904 |
-
// }
|
905 |
-
//
|
906 |
-
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/payments/hooks/WC_WooMercadoPago_Hook_Pse.php
DELETED
@@ -1,126 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class WC_WooMercadoPago_Hook_Pse
|
5 |
-
*/
|
6 |
-
class WC_WooMercadoPago_Hook_Pse extends WC_WooMercadoPago_Hook_Abstract
|
7 |
-
{
|
8 |
-
/**
|
9 |
-
* WC_WooMercadoPago_Hook_Pse constructor.
|
10 |
-
* @param $payment
|
11 |
-
*/
|
12 |
-
public function __construct($payment)
|
13 |
-
{
|
14 |
-
parent::__construct($payment);
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Load Hooks
|
19 |
-
*/
|
20 |
-
public function loadHooks()
|
21 |
-
{
|
22 |
-
parent::loadHooks();
|
23 |
-
add_action('wp_enqueue_scripts', array($this, 'add_checkout_scripts'));
|
24 |
-
//add_action('valid_mercadopago_pse_ipn_request', array($this, 'successful_request'));
|
25 |
-
add_action('woocommerce_cart_calculate_fees', array($this, 'add_discount_pse'), 10);
|
26 |
-
if (!empty($this->payment->settings['enabled']) && $this->payment->settings['enabled'] == 'yes') {
|
27 |
-
add_action('woocommerce_after_checkout_form', array($this, 'add_mp_settings_script_pse'));
|
28 |
-
add_action('woocommerce_thankyou_' . $this->id, array($this, 'success_page_pse'));
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
*
|
34 |
-
*/
|
35 |
-
public function add_mp_settings_script_pse()
|
36 |
-
{
|
37 |
-
parent::add_mp_settings_script();
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @param $order_id
|
42 |
-
*/
|
43 |
-
public function success_page_pse($order_id)
|
44 |
-
{
|
45 |
-
parent::update_mp_settings_script($order_id);
|
46 |
-
$order = wc_get_order($order_id);
|
47 |
-
$transaction_details = (method_exists($order, 'get_meta')) ? $order->get_meta('_transaction_details_pse') : get_post_meta($order->get_id(), '_transaction_details_pse', true);
|
48 |
-
if (empty($transaction_details)) {
|
49 |
-
return;
|
50 |
-
}
|
51 |
-
|
52 |
-
$html = '<p>' .
|
53 |
-
__('Obrigado pela sua compra. Por favor, transfiera el dinero para tener su compra aprobada.', 'woocommerce-mercadopago') .
|
54 |
-
'</p>' .
|
55 |
-
'<p><iframe src="' . $transaction_details . '" style="width:100%; height:1000px;"></iframe></p>' .
|
56 |
-
'<a id="submit-payment" target="_blank" href="' . $transaction_details . '" class="button alt"' .
|
57 |
-
' style="font-size:1.25rem; width:75%; height:48px; line-height:24px; text-align:center;">' .
|
58 |
-
__('Transferir', 'woocommerce-mercadopago') .
|
59 |
-
'</a> ';
|
60 |
-
$added_text = '<p>' . $html . '</p>';
|
61 |
-
echo $added_text;
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Add Discount PSE
|
66 |
-
*/
|
67 |
-
public function add_discount_pse()
|
68 |
-
{
|
69 |
-
if (!isset($_POST['mercadopago_pse'])) {
|
70 |
-
return;
|
71 |
-
}
|
72 |
-
|
73 |
-
if (is_admin() && !defined('DOING_AJAX') || is_cart()) {
|
74 |
-
return;
|
75 |
-
}
|
76 |
-
|
77 |
-
$pse_checkout = $_POST['mercadopago_pse'];
|
78 |
-
if (isset($pse_checkout['discount']) && !empty($pse_checkout['discount']) &&
|
79 |
-
isset($pse_checkout['coupon_code']) && !empty($pse_checkout['coupon_code']) &&
|
80 |
-
$pse_checkout['discount'] > 0 && WC()->session->chosen_payment_method == 'woo-mercado-pago-pse') {
|
81 |
-
$this->payment->log->write_log(__FUNCTION__, 'pse checkout trying to apply discount...');
|
82 |
-
$value = ($this->payment->site_data['currency'] == 'COP' || $this->payment->site_data['currency'] == 'CLP') ?
|
83 |
-
floor($pse_checkout['discount'] / $pse_checkout['currency_ratio']) :
|
84 |
-
floor($pse_checkout['discount'] / $pse_checkout['currency_ratio'] * 100) / 100;
|
85 |
-
global $woocommerce;
|
86 |
-
if (apply_filters('wc_mercadopagopse_module_apply_discount', 0 < $value, $woocommerce->cart)) {
|
87 |
-
$woocommerce->cart->add_fee(sprintf(__('Descuento para el cupón %s', 'woocommerce-mercadopago'), esc_attr($pse_checkout['campaign'])),
|
88 |
-
($value * -1), false
|
89 |
-
);
|
90 |
-
}
|
91 |
-
}
|
92 |
-
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* @return mixed
|
97 |
-
*/
|
98 |
-
public function custom_process_admin_options()
|
99 |
-
{
|
100 |
-
$this->payment->init_settings();
|
101 |
-
$post_data = $this->payment->get_post_data();
|
102 |
-
foreach ( $this->payment->get_form_fields() as $key => $field ) {
|
103 |
-
if ( 'title' !== $this->payment->get_field_type( $field ) ) {
|
104 |
-
$value = $this->payment->get_field_value( $key, $field, $post_data );
|
105 |
-
if ( $key == 'gateway_discount') {
|
106 |
-
if ( ! is_numeric( $value ) || empty ( $value ) || $value < -99 || $value > 99 ) {
|
107 |
-
$this->payment->settings[$key] = 0;
|
108 |
-
} else {
|
109 |
-
$this->payment->settings[$key] = $value;
|
110 |
-
}
|
111 |
-
} else {
|
112 |
-
$this->payment->settings[$key] = $this->payment->get_field_value( $key, $field, $post_data );
|
113 |
-
}
|
114 |
-
}
|
115 |
-
}
|
116 |
-
$_site_id_v1 = get_option( '_site_id_v1', '' );
|
117 |
-
$is_test_user = get_option( '_test_user_v1', false );
|
118 |
-
if ( ! empty( $_site_id_v1 ) && ! $is_test_user ) {
|
119 |
-
// Analytics.
|
120 |
-
$infra_data = WC_WooMercadoPago_Module::get_common_settings();
|
121 |
-
$infra_data['checkout_custom_pse'] = ( $this->payment->settings['enabled'] == 'yes' ? 'true' : 'false' );
|
122 |
-
$this->mpInstance->analytics_save_settings( $infra_data );
|
123 |
-
}
|
124 |
-
return update_option($this->payment->get_option_key(), apply_filters( 'woocommerce_settings_api_sanitized_fields_' . $this->payment->id, $this->payment->settings ));
|
125 |
-
}
|
126 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|