WooCommerce MercadoPago - Version 1.8.0

Version Description

  • Removida compatibilidade com verses 1.6.x ou inferiores do WooCommerce.
  • Adicionada compatibilidade com WooCommerce 2.1 ou superior.

=

Download this release

Release Info

Developer claudiosanches
Plugin Icon 128x128 WooCommerce MercadoPago
Version 1.8.0
Comparing to
See all releases

Code changes from version 1.7.0 to 1.8.0

class-wc-mercadopago-gateway.php DELETED
@@ -1,580 +0,0 @@
1
- <?php
2
- /**
3
- * WC MercadoPago Gateway Class.
4
- *
5
- * Built the MercadoPago method.
6
- */
7
- class WC_MercadoPago_Gateway extends WC_Payment_Gateway {
8
-
9
- /**
10
- * Constructor for the gateway.
11
- *
12
- * @return void
13
- */
14
- public function __construct() {
15
- global $woocommerce;
16
-
17
- // Standards
18
- $this->id = 'mercadopago';
19
- $this->icon = apply_filters( 'woocommerce_mercadopago_icon', plugins_url( 'images/mercadopago.png', __FILE__ ) );
20
- $this->has_fields = false;
21
- $this->method_title = __( 'MercadoPago', 'woocommerce-mercadopago' );
22
-
23
- // API URLs.
24
- $this->payment_url = 'https://api.mercadolibre.com/checkout/preferences?access_token=';
25
- $this->ipn_url = 'https://api.mercadolibre.com/collections/notifications/';
26
- $this->sandbox_ipn_url = 'https://api.mercadolibre.com/sandbox/collections/notifications/';
27
- $this->oauth_token = 'https://api.mercadolibre.com/oauth/token';
28
-
29
- // Load the form fields.
30
- $this->init_form_fields();
31
-
32
- // Load the settings.
33
- $this->init_settings();
34
-
35
- // Define user set variables.
36
- $this->title = $this->settings['title'];
37
- $this->description = $this->settings['description'];
38
- $this->client_id = $this->settings['client_id'];
39
- $this->client_secret = $this->settings['client_secret'];
40
- $this->invoice_prefix = ! empty( $this->settings['invoice_prefix'] ) ? $this->settings['invoice_prefix'] : 'WC-';
41
- $this->method = ! empty( $this->settings['method'] ) ? $this->settings['method'] : 'modal';
42
- $this->sandbox = isset( $this->settings['sandbox'] ) ? $this->settings['sandbox'] : false;
43
- $this->debug = $this->settings['debug'];
44
-
45
- // Actions.
46
- add_action( 'woocommerce_api_wc_mercadopago_gateway', array( &$this, 'check_ipn_response' ) );
47
- add_action( 'valid_mercadopago_ipn_request', array( &$this, 'successful_request' ) );
48
- add_action( 'woocommerce_receipt_mercadopago', array( &$this, 'receipt_page' ) );
49
- add_action( 'wp_head', array( &$this, 'css' ) );
50
- if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) )
51
- add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ) );
52
- else
53
- add_action( 'woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ) );
54
-
55
- // Checks if client_id is not empty.
56
- if ( empty( $this->client_id ) )
57
- add_action( 'admin_notices', array( $this, 'client_id_missing_message' ) );
58
-
59
- // Checks if client_secret is not empty.
60
- if ( empty( $this->client_secret ) )
61
- add_action( 'admin_notices', array( $this, 'client_secret_missing_message' ) );
62
-
63
- // Checks that the currency is supported
64
- if ( ! $this->using_supported_currency() )
65
- add_action( 'admin_notices', array( $this, 'currency_not_supported_message' ) );
66
-
67
- // Active logs.
68
- if ( 'yes' == $this->debug )
69
- $this->log = $woocommerce->logger();
70
- }
71
-
72
- /**
73
- * Returns a bool that indicates if currency is amongst the supported ones.
74
- *
75
- * @return bool
76
- */
77
- protected function using_supported_currency() {
78
- return in_array( get_woocommerce_currency(), array( 'ARS', 'BRL', 'MXN', 'USD', 'VEF' ) );
79
- }
80
-
81
- /**
82
- * Returns a value indicating the the Gateway is available or not. It's called
83
- * automatically by WooCommerce before allowing customers to use the gateway
84
- * for payment.
85
- *
86
- * @return bool
87
- */
88
- public function is_available() {
89
- // Test if is valid for use.
90
- $available = ( 'yes' == $this->settings['enabled'] ) &&
91
- ! empty( $this->client_id ) &&
92
- ! empty( $this->client_secret ) &&
93
- $this->using_supported_currency();
94
-
95
- return $available;
96
- }
97
-
98
- /**
99
- * Initialise Gateway Settings Form Fields.
100
- *
101
- * @return void
102
- */
103
- public function init_form_fields() {
104
-
105
- $api_secret_locale = sprintf( '<a href="https://www.mercadopago.com/mla/herramientas/aplicaciones" target="_blank">%1$s</a>, <a href="https://www.mercadopago.com/mlb/ferramentas/aplicacoes" target="_blank">%2$s</a>, <a href="https://www.mercadopago.com/mlm/herramientas/aplicaciones" target="_blank">%3$s</a> %5$s <a href="https://www.mercadopago.com/mlv/herramientas/aplicaciones" target="_blank">%4$s</a>', __( 'Argentine', 'woocommerce-mercadopago' ), __( 'Brazil', 'woocommerce-mercadopago' ), __( 'Mexico', 'woocommerce-mercadopago' ), __( 'Venezuela', 'woocommerce-mercadopago' ), __( 'or', 'woocommerce-mercadopago' ) );
106
-
107
- $this->form_fields = array(
108
- 'enabled' => array(
109
- 'title' => __( 'Enable/Disable', 'woocommerce-mercadopago' ),
110
- 'type' => 'checkbox',
111
- 'label' => __( 'Enable MercadoPago standard', 'woocommerce-mercadopago' ),
112
- 'default' => 'yes'
113
- ),
114
- 'title' => array(
115
- 'title' => __( 'Title', 'woocommerce-mercadopago' ),
116
- 'type' => 'text',
117
- 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-mercadopago' ),
118
- 'desc_tip' => true,
119
- 'default' => __( 'MercadoPago', 'woocommerce-mercadopago' )
120
- ),
121
- 'description' => array(
122
- 'title' => __( 'Description', 'woocommerce-mercadopago' ),
123
- 'type' => 'textarea',
124
- 'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-mercadopago' ),
125
- 'default' => __( 'Pay via MercadoPago', 'woocommerce-mercadopago' )
126
- ),
127
- 'client_id' => array(
128
- 'title' => __( 'MercadoPago Client_id', 'woocommerce-mercadopago' ),
129
- 'type' => 'text',
130
- 'description' => __( 'Please enter your MercadoPago Client_id.', 'woocommerce-mercadopago' ) . ' ' . sprintf( __( 'You can to get this information in MercadoPago from %s.', 'woocommerce-mercadopago' ), $api_secret_locale ),
131
- 'default' => ''
132
- ),
133
- 'client_secret' => array(
134
- 'title' => __( 'MercadoPago Client_secret', 'woocommerce-mercadopago' ),
135
- 'type' => 'text',
136
- 'description' => __( 'Please enter your MercadoPago Client_secret.', 'woocommerce-mercadopago' ) . ' ' . sprintf( __( 'You can to get this information in MercadoPago from %s.', 'woocommerce-mercadopago' ), $api_secret_locale ),
137
- 'default' => ''
138
- ),
139
- 'invoice_prefix' => array(
140
- 'title' => __( 'Invoice Prefix', 'woocommerce-mercadopago' ),
141
- 'type' => 'text',
142
- 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your MercadoPago account for multiple stores ensure this prefix is unqiue as MercadoPago will not allow orders with the same invoice number.', 'woocommerce-mercadopago' ),
143
- 'desc_tip' => true,
144
- 'default' => 'WC-'
145
- ),
146
- 'method' => array(
147
- 'title' => __( 'Integration method', 'woocommerce-mercadopago' ),
148
- 'type' => 'select',
149
- 'description' => __( 'Choose how the customer will interact with the MercadoPago. Modal Window (Inside your store) Redirect (Client goes to MercadoPago).', 'woocommerce-mercadopago' ),
150
- 'desc_tip' => true,
151
- 'default' => 'modal',
152
- 'options' => array(
153
- 'modal' => __( 'Modal Window', 'woocommerce-mercadopago' ),
154
- 'redirect' => __( 'Redirect', 'woocommerce-mercadopago' ),
155
- )
156
- ),
157
- 'testing' => array(
158
- 'title' => __( 'Gateway Testing', 'woocommerce-mercadopago' ),
159
- 'type' => 'title',
160
- 'description' => '',
161
- ),
162
- 'sandbox' => array(
163
- 'title' => __( 'MercadoPago Sandbox', 'woocommerce-mercadopago' ),
164
- 'type' => 'checkbox',
165
- 'label' => __( 'Enable MercadoPago sandbox', 'woocommerce-mercadopago' ),
166
- 'default' => 'no',
167
- 'description' => __( 'MercadoPago sandbox can be used to test payments.', 'woocommerce-mercadopago' ),
168
- ),
169
- 'debug' => array(
170
- 'title' => __( 'Debug Log', 'woocommerce-mercadopago' ),
171
- 'type' => 'checkbox',
172
- 'label' => __( 'Enable logging', 'woocommerce-mercadopago' ),
173
- 'default' => 'no',
174
- 'description' => sprintf( __( 'Log MercadoPago events, such as API requests, inside %s', 'woocommerce-mercadopago' ), '<code>woocommerce/logs/mercadopago-' . sanitize_file_name( wp_hash( 'mercadopago' ) ) . '.txt</code>' ),
175
- )
176
- );
177
- }
178
-
179
- /**
180
- * Generate the args to form.
181
- *
182
- * @param object $order Order data.
183
- *
184
- * @return array Form arguments.
185
- */
186
- public function get_form_args( $order ) {
187
-
188
- $args = array(
189
- 'back_urls' => array(
190
- 'success' => esc_url( $this->get_return_url( $order ) ),
191
- 'failure' => esc_url( $order->get_cancel_order_url() ),
192
- 'pending' => esc_url( $this->get_return_url( $order ) )
193
- ),
194
- 'payer' => array(
195
- 'name' => $order->billing_first_name,
196
- 'surname' => $order->billing_last_name,
197
- 'email' => $order->billing_email
198
- ),
199
- 'external_reference' => $this->invoice_prefix . $order->id,
200
- 'items' => array(
201
- array(
202
- 'quantity' => 1,
203
- 'unit_price' => (float) $order->order_total,
204
- 'currency_id' => get_woocommerce_currency(),
205
- // 'picture_url' => 'https://www.mercadopago.com/org-img/MP3/home/logomp3.gif'
206
- )
207
- )
208
- );
209
-
210
- // Cart Contents.
211
- $item_names = array();
212
-
213
- if ( sizeof( $order->get_items() ) > 0 ) {
214
- foreach ( $order->get_items() as $item ) {
215
- if ( $item['qty'] )
216
- $item_names[] = $item['name'] . ' x ' . $item['qty'];
217
- }
218
- }
219
-
220
- $args['items'][0]['title'] = sprintf( __( 'Order %s', 'woocommerce-mercadopago' ), $order->get_order_number() ) . ' - ' . implode( ', ', $item_names );
221
-
222
- // Shipping Cost item.
223
- if ( $order->get_shipping() > 0 )
224
- $args['items'][0]['title'] .= ', ' . __( 'Shipping via', 'woocommerce-mercadopago' ) . ' ' . ucwords( $order->shipping_method_title );
225
-
226
- $args = apply_filters( 'woocommerce_mercadopago_args', $args, $order );
227
-
228
- return $args;
229
- }
230
-
231
- /**
232
- * Generate the MercadoPago payment url.
233
- *
234
- * @param object $order Order Object.
235
- *
236
- * @return string MercadoPago payment url.
237
- */
238
- protected function get_mercadopago_url( $order ) {
239
- $args = json_encode( $this->get_form_args( $order ) );
240
-
241
- if ( 'yes' == $this->debug )
242
- $this->log->add( 'mercadopago', 'Payment arguments for order ' . $order->get_order_number() . ': ' . print_r( $this->get_form_args( $order ), true ) );
243
-
244
- $url = $this->payment_url . $this->get_client_credentials();
245
-
246
- $params = array(
247
- 'body' => $args,
248
- 'sslverify' => false,
249
- 'timeout' => 30,
250
- 'headers' => array( 'content-type' => 'application/json;charset=UTF-8' )
251
- );
252
-
253
- $response = wp_remote_post( $url, $params );
254
-
255
- if ( ! is_wp_error( $response ) && $response['response']['code'] == 201 && ( strcmp( $response['response']['message'], 'Created' ) == 0 ) ) {
256
- $checkout_info = json_decode( $response['body'] );
257
-
258
- if ( 'yes' == $this->debug )
259
- $this->log->add( 'mercadopago', 'Payment link generated with success from MercadoPago' );
260
-
261
- if ( 'yes' == $this->sandbox )
262
- return esc_url( $checkout_info->sandbox_init_point );
263
- else
264
- return esc_url( $checkout_info->init_point );
265
-
266
- } else {
267
- if ( 'yes' == $this->debug )
268
- $this->log->add( 'mercadopago', 'Generate payment error response: ' . print_r( $response, true ) );
269
- }
270
-
271
- return false;
272
- }
273
-
274
- /**
275
- * Generate the form.
276
- *
277
- * @param int $order_id Order ID.
278
- *
279
- * @return string Payment form.
280
- */
281
- public function generate_form( $order_id ) {
282
-
283
- $order = new WC_Order( $order_id );
284
- $url = $this->get_mercadopago_url( $order );
285
-
286
- if ( $url ) {
287
-
288
- // Display checkout.
289
- $html = '<p>' . __( 'Thank you for your order, please click the button below to pay with MercadoPago.', 'woocommerce-mercadopago' ) . '</p>';
290
-
291
- $html .= '<a id="submit-payment" href="' . $url . '" name="MP-Checkout" class="button alt" mp-mode="modal">' . __( 'Pay via MercadoPago', 'woocommerce-mercadopago' ) . '</a> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order &amp; restore cart', 'woocommerce-mercadopago' ) . '</a>';
292
-
293
- // Add MercadoPago JS.
294
- $html .= '<script type="text/javascript">(function(){function $MPBR_load(){window.$MPBR_loaded !== true && (function(){var s = document.createElement("script");s.type = "text/javascript";s.async = true;s.src = ("https:"==document.location.protocol?"https://www.mercadopago.com/org-img/jsapi/mptools/buttons/":"http://mp-tools.mlstatic.com/buttons/")+"render.js";var x = document.getElementsByTagName("script")[0];x.parentNode.insertBefore(s, x);window.$MPBR_loaded = true;})();}window.$MPBR_loaded !== true ? (window.attachEvent ? window.attachEvent("onload", $MPBR_load) : window.addEventListener("load", $MPBR_load, false)) : null;})();</script>';
295
-
296
- return $html;
297
- } else {
298
- // Display message if a problem occurs.
299
- $html = '<p>' . __( 'An error has occurred while processing your payment, please try again. Or contact us for assistance.', 'woocommerce-mercadopago' ) . '</p>';
300
-
301
- $html .= '<a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Click to try again', 'woocommerce-mercadopago' ) . '</a>';
302
-
303
- return $html;
304
- }
305
- }
306
-
307
- /**
308
- * Fix MercadoPago CSS.
309
- *
310
- * @return string Styles.
311
- */
312
- public function css() {
313
- echo '<style type="text/css">#MP-Checkout-dialog { z-index: 9999 !important; }</style>';
314
- }
315
-
316
- /**
317
- * Process the payment and return the result.
318
- *
319
- * @param int $order_id Order ID.
320
- *
321
- * @return array Redirect.
322
- */
323
- public function process_payment( $order_id ) {
324
-
325
- $order = new WC_Order( $order_id );
326
-
327
- // Redirect or modal window integration.
328
- if ( 'redirect' == $this->method ) {
329
- return array(
330
- 'result' => 'success',
331
- 'redirect' => $this->get_mercadopago_url( $order )
332
- );
333
- } else {
334
- if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
335
- return array(
336
- 'result' => 'success',
337
- 'redirect' => $order->get_checkout_payment_url( true )
338
- );
339
- } else {
340
- return array(
341
- 'result' => 'success',
342
- 'redirect' => add_query_arg( 'order', $order->id, add_query_arg( 'key', $order->order_key, get_permalink( woocommerce_get_page_id( 'pay' ) ) ) )
343
- );
344
- }
345
- }
346
- }
347
-
348
- /**
349
- * Output for the order received page.
350
- *
351
- * @return void
352
- */
353
- public function receipt_page( $order ) {
354
- echo $this->generate_form( $order );
355
- }
356
-
357
- /**
358
- * Get cliente token.
359
- *
360
- * @return mixed Sucesse return the token and error return null.
361
- */
362
- protected function get_client_credentials() {
363
-
364
- if ( 'yes' == $this->debug )
365
- $this->log->add( 'mercadopago', 'Getting client credentials...' );
366
-
367
- // Set postdata.
368
- $postdata = 'grant_type=client_credentials';
369
- $postdata .= '&client_id=' . $this->client_id;
370
- $postdata .= '&client_secret=' . $this->client_secret;
371
-
372
- // Built wp_remote_post params.
373
- $params = array(
374
- 'body' => $postdata,
375
- 'sslverify' => false,
376
- 'timeout' => 30
377
- );
378
-
379
- $response = wp_remote_post( $this->oauth_token, $params );
380
-
381
- // Check to see if the request was valid and return the token.
382
- if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && ( strcmp( $response['response']['message'], 'OK' ) == 0 ) ) {
383
-
384
- $token = json_decode( $response['body'] );
385
-
386
- if ( 'yes' == $this->debug )
387
- $this->log->add( 'mercadopago', 'Received valid response from MercadoPago' );
388
-
389
- return $token->access_token;
390
- } else {
391
- if ( 'yes' == $this->debug )
392
- $this->log->add( 'mercadopago', 'Received invalid response from MercadoPago. Error response: ' . print_r( $response, true ) );
393
- }
394
-
395
- return null;
396
- }
397
-
398
- /**
399
- * Check IPN.
400
- *
401
- * @param array $data MercadoPago post data.
402
- *
403
- * @return mixed False or posted response.
404
- */
405
- public function check_ipn_request_is_valid( $data ) {
406
-
407
- if ( ! isset( $data['id'] ) )
408
- return false;
409
-
410
- if ( 'yes' == $this->debug )
411
- $this->log->add( 'mercadopago', 'Checking IPN request...' );
412
-
413
- if ( 'yes' == $this->sandbox )
414
- $ipn_url = $this->sandbox_ipn_url;
415
- else
416
- $ipn_url = $this->ipn_url;
417
-
418
- $url = $ipn_url . $data['id'] . '?access_token=' . $this->get_client_credentials();
419
-
420
- // Send back post vars.
421
- $params = array(
422
- 'sslverify' => false,
423
- 'timeout' => 30
424
- );
425
-
426
- // GET a response.
427
- $response = wp_remote_get( $url, $params );
428
-
429
- if ( 'yes' == $this->debug )
430
- $this->log->add( 'mercadopago', 'IPN Response: ' . print_r( $response, true ) );
431
-
432
- // Check to see if the request was valid.
433
- if ( ! is_wp_error( $response ) && 200 == $response['response']['code'] ) {
434
-
435
- $body = json_decode( $response['body'] );
436
-
437
- $this->log->add( 'mercadopago', 'Received valid IPN response from MercadoPago' );
438
-
439
- return $body;
440
- } else {
441
- if ( 'yes' == $this->debug )
442
- $this->log->add( 'mercadopago', 'Received invalid IPN response from MercadoPago.' );
443
- }
444
-
445
- return false;
446
- }
447
-
448
- /**
449
- * Check API Response.
450
- *
451
- * @return void
452
- */
453
- public function check_ipn_response() {
454
- @ob_clean();
455
-
456
- $data = $this->check_ipn_request_is_valid( $_GET );
457
-
458
- if ( $data ) {
459
- header( 'HTTP/1.1 200 OK' );
460
- do_action( 'valid_mercadopago_ipn_request', $data );
461
- } else {
462
- wp_die( __( 'MercadoPago Request Failure', 'woocommerce-mercadopago' ) );
463
- }
464
- }
465
-
466
- /**
467
- * Successful Payment!
468
- *
469
- * @param array $posted MercadoPago post data.
470
- *
471
- * @return void
472
- */
473
- public function successful_request( $posted ) {
474
-
475
- $data = $posted->collection;
476
- $order_key = $data->external_reference;
477
-
478
- if ( ! empty( $order_key ) ) {
479
- $order_id = (int) str_replace( $this->invoice_prefix, '', $order_key );
480
-
481
- $order = new WC_Order( $order_id );
482
-
483
- // Checks whether the invoice number matches the order.
484
- // If true processes the payment.
485
- if ( $order->id === $order_id ) {
486
-
487
- if ( 'yes' == $this->debug )
488
- $this->log->add( 'mercadopago', 'Payment status from order ' . $order->get_order_number() . ': ' . $data->status );
489
-
490
- switch ( $data->status ) {
491
- case 'approved':
492
-
493
- // Order details.
494
- if ( ! empty( $data->id ) ) {
495
- update_post_meta(
496
- $order_id,
497
- __( 'MercadoPago Transaction ID', 'woocommerce-mercadopago' ),
498
- $data->id
499
- );
500
- }
501
- if ( ! empty( $data->payer->email ) ) {
502
- update_post_meta(
503
- $order_id,
504
- __( 'Payer email', 'woocommerce-mercadopago' ),
505
- $data->payer->email
506
- );
507
- }
508
- if ( ! empty( $data->payment_type ) ) {
509
- update_post_meta(
510
- $order_id,
511
- __( 'Payment type', 'woocommerce-mercadopago' ),
512
- $data->payment_type
513
- );
514
- }
515
-
516
- // Payment completed.
517
- $order->add_order_note( __( 'MercadoPago: Payment approved.', 'woocommerce-mercadopago' ) );
518
- $order->payment_complete();
519
-
520
- break;
521
- case 'pending':
522
- $order->add_order_note( __( 'MercadoPago: The user has not completed the payment process yet.', 'woocommerce-mercadopago' ) );
523
-
524
- break;
525
- case 'in_process':
526
- $order->update_status( 'on-hold', __( 'MercadoPago: Payment under review.', 'woocommerce-mercadopago' ) );
527
-
528
- break;
529
- case 'rejected':
530
- $order->add_order_note( __( 'MercadoPago: The payment was declined. The user can try again.', 'woocommerce-mercadopago' ) );
531
-
532
- break;
533
- case 'refunded':
534
- $order->update_status( 'refunded', __( 'MercadoPago: The payment was returned to the user.', 'woocommerce-mercadopago' ) );
535
-
536
- break;
537
- case 'cancelled':
538
- $order->update_status( 'cancelled', __( 'MercadoPago: Payment canceled.', 'woocommerce-mercadopago' ) );
539
-
540
- break;
541
- case 'in_mediation':
542
- $order->add_order_note( __( 'MercadoPago: It started a dispute for payment.', 'woocommerce-mercadopago' ) );
543
-
544
- break;
545
-
546
- default:
547
- // No action xD.
548
- break;
549
- }
550
- }
551
- }
552
- }
553
-
554
- /**
555
- * Adds error message when not configured the client_id.
556
- *
557
- * @return string Error Mensage.
558
- */
559
- public function client_id_missing_message() {
560
- echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'You should inform your Client_id. %s', 'woocommerce-mercadopago' ), '<a href="' . admin_url( 'admin.php?page=woocommerce_settings&tab=payment_gateways&section=WC_MercadoPago_Gateway' ) . '">' . __( 'Click here to configure!', 'woocommerce-mercadopago' ) . '</a>' ) . '</p></div>';
561
- }
562
-
563
- /**
564
- * Adds error message when not configured the client_secret.
565
- *
566
- * @return string Error Mensage.
567
- */
568
- public function client_secret_missing_message() {
569
- echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'You should inform your Client_secret. %s', 'woocommerce-mercadopago' ), '<a href="' . admin_url( 'admin.php?page=woocommerce_settings&tab=payment_gateways&section=WC_MercadoPago_Gateway' ) . '">' . __( 'Click here to configure!', 'woocommerce-mercadopago' ) . '</a>' ) . '</p></div>';
570
- }
571
-
572
- /**
573
- * Adds error message when an unsupported currency is used.
574
- *
575
- * @return string
576
- */
577
- public function currency_not_supported_message() {
578
- echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'Currency <code>%s</code> is not supported. Please make sure that you use one of the following supported currencies: ARS, BRL, MXN, USD or VEF.', 'woocommerce-mercadopago' ), get_woocommerce_currency()) . '</p></div>';
579
- }
580
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-wc-mercadopago-gateway.php ADDED
@@ -0,0 +1,639 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WC MercadoPago Gateway Class.
4
+ *
5
+ * Built the MercadoPago method.
6
+ */
7
+ class WC_MercadoPago_Gateway extends WC_Payment_Gateway {
8
+
9
+ /**
10
+ * Constructor for the gateway.
11
+ *
12
+ * @return void
13
+ */
14
+ public function __construct() {
15
+
16
+ // Standards
17
+ $this->id = 'mercadopago';
18
+ $this->icon = apply_filters( 'woocommerce_mercadopago_icon', plugins_url( 'images/mercadopago.png', plugin_dir_path( __FILE__ ) ) );
19
+ $this->has_fields = false;
20
+ $this->method_title = __( 'MercadoPago', 'woocommerce-mercadopago' );
21
+
22
+ // API URLs.
23
+ $this->payment_url = 'https://api.mercadolibre.com/checkout/preferences?access_token=';
24
+ $this->ipn_url = 'https://api.mercadolibre.com/collections/notifications/';
25
+ $this->sandbox_ipn_url = 'https://api.mercadolibre.com/sandbox/collections/notifications/';
26
+ $this->oauth_token = 'https://api.mercadolibre.com/oauth/token';
27
+
28
+ // Load the form fields.
29
+ $this->init_form_fields();
30
+
31
+ // Load the settings.
32
+ $this->init_settings();
33
+
34
+ // Define user set variables.
35
+ $this->title = $this->get_option( 'title' );
36
+ $this->description = $this->get_option( 'description' );
37
+ $this->client_id = $this->get_option( 'client_id' );
38
+ $this->client_secret = $this->get_option( 'client_secret' );
39
+ $this->invoice_prefix = $this->get_option( 'invoice_prefix', 'WC-' );
40
+ $this->method = $this->get_option( 'method', 'modal' );
41
+ $this->sandbox = $this->get_option( 'sandbox', false );
42
+ $this->debug = $this->get_option( 'debug' );
43
+
44
+ // Actions.
45
+ add_action( 'woocommerce_api_wc_mercadopago_gateway', array( $this, 'check_ipn_response' ) );
46
+ add_action( 'valid_mercadopago_ipn_request', array( $this, 'successful_request' ) );
47
+ add_action( 'woocommerce_receipt_mercadopago', array( $this, 'receipt_page' ) );
48
+ add_action( 'wp_head', array( $this, 'css' ) );
49
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
50
+
51
+ // Checks if client_id is not empty.
52
+ if ( empty( $this->client_id ) ) {
53
+ add_action( 'admin_notices', array( $this, 'client_id_missing_message' ) );
54
+ }
55
+
56
+ // Checks if client_secret is not empty.
57
+ if ( empty( $this->client_secret ) ) {
58
+ add_action( 'admin_notices', array( $this, 'client_secret_missing_message' ) );
59
+ }
60
+
61
+ // Checks that the currency is supported
62
+ if ( ! $this->using_supported_currency() ) {
63
+ add_action( 'admin_notices', array( $this, 'currency_not_supported_message' ) );
64
+ }
65
+
66
+ // Active logs.
67
+ if ( 'yes' == $this->debug ) {
68
+ if ( class_exists( 'WC_Logger' ) ) {
69
+ $this->log = new WC_Logger();
70
+ } else {
71
+ $this->log = $this->woocommerce_instance()->logger();
72
+ }
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Backwards compatibility with version prior to 2.1.
78
+ *
79
+ * @return object Returns the main instance of WooCommerce class.
80
+ */
81
+ protected function woocommerce_instance() {
82
+ if ( function_exists( 'WC' ) ) {
83
+ return WC();
84
+ } else {
85
+ global $woocommerce;
86
+ return $woocommerce;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Returns a bool that indicates if currency is amongst the supported ones.
92
+ *
93
+ * @return bool
94
+ */
95
+ protected function using_supported_currency() {
96
+ return in_array( get_woocommerce_currency(), array( 'ARS', 'BRL', 'MXN', 'USD', 'VEF' ) );
97
+ }
98
+
99
+ /**
100
+ * Returns a value indicating the the Gateway is available or not. It's called
101
+ * automatically by WooCommerce before allowing customers to use the gateway
102
+ * for payment.
103
+ *
104
+ * @return bool
105
+ */
106
+ public function is_available() {
107
+ // Test if is valid for use.
108
+ $available = ( 'yes' == $this->settings['enabled'] ) &&
109
+ ! empty( $this->client_id ) &&
110
+ ! empty( $this->client_secret ) &&
111
+ $this->using_supported_currency();
112
+
113
+ return $available;
114
+ }
115
+
116
+ /**
117
+ * Initialise Gateway Settings Form Fields.
118
+ *
119
+ * @return void
120
+ */
121
+ public function init_form_fields() {
122
+
123
+ $api_secret_locale = sprintf( '<a href="https://www.mercadopago.com/mla/herramientas/aplicaciones" target="_blank">%1$s</a>, <a href="https://www.mercadopago.com/mlb/ferramentas/aplicacoes" target="_blank">%2$s</a>, <a href="https://www.mercadopago.com/mlm/herramientas/aplicaciones" target="_blank">%3$s</a> %5$s <a href="https://www.mercadopago.com/mlv/herramientas/aplicaciones" target="_blank">%4$s</a>', __( 'Argentine', 'woocommerce-mercadopago' ), __( 'Brazil', 'woocommerce-mercadopago' ), __( 'Mexico', 'woocommerce-mercadopago' ), __( 'Venezuela', 'woocommerce-mercadopago' ), __( 'or', 'woocommerce-mercadopago' ) );
124
+
125
+ $this->form_fields = array(
126
+ 'enabled' => array(
127
+ 'title' => __( 'Enable/Disable', 'woocommerce-mercadopago' ),
128
+ 'type' => 'checkbox',
129
+ 'label' => __( 'Enable MercadoPago standard', 'woocommerce-mercadopago' ),
130
+ 'default' => 'yes'
131
+ ),
132
+ 'title' => array(
133
+ 'title' => __( 'Title', 'woocommerce-mercadopago' ),
134
+ 'type' => 'text',
135
+ 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-mercadopago' ),
136
+ 'desc_tip' => true,
137
+ 'default' => __( 'MercadoPago', 'woocommerce-mercadopago' )
138
+ ),
139
+ 'description' => array(
140
+ 'title' => __( 'Description', 'woocommerce-mercadopago' ),
141
+ 'type' => 'textarea',
142
+ 'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-mercadopago' ),
143
+ 'default' => __( 'Pay via MercadoPago', 'woocommerce-mercadopago' )
144
+ ),
145
+ 'client_id' => array(
146
+ 'title' => __( 'MercadoPago Client_id', 'woocommerce-mercadopago' ),
147
+ 'type' => 'text',
148
+ 'description' => __( 'Please enter your MercadoPago Client_id.', 'woocommerce-mercadopago' ) . ' ' . sprintf( __( 'You can to get this information in MercadoPago from %s.', 'woocommerce-mercadopago' ), $api_secret_locale ),
149
+ 'default' => ''
150
+ ),
151
+ 'client_secret' => array(
152
+ 'title' => __( 'MercadoPago Client_secret', 'woocommerce-mercadopago' ),
153
+ 'type' => 'text',
154
+ 'description' => __( 'Please enter your MercadoPago Client_secret.', 'woocommerce-mercadopago' ) . ' ' . sprintf( __( 'You can to get this information in MercadoPago from %s.', 'woocommerce-mercadopago' ), $api_secret_locale ),
155
+ 'default' => ''
156
+ ),
157
+ 'invoice_prefix' => array(
158
+ 'title' => __( 'Invoice Prefix', 'woocommerce-mercadopago' ),
159
+ 'type' => 'text',
160
+ 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your MercadoPago account for multiple stores ensure this prefix is unqiue as MercadoPago will not allow orders with the same invoice number.', 'woocommerce-mercadopago' ),
161
+ 'desc_tip' => true,
162
+ 'default' => 'WC-'
163
+ ),
164
+ 'method' => array(
165
+ 'title' => __( 'Integration method', 'woocommerce-mercadopago' ),
166
+ 'type' => 'select',
167
+ 'description' => __( 'Choose how the customer will interact with the MercadoPago. Modal Window (Inside your store) Redirect (Client goes to MercadoPago).', 'woocommerce-mercadopago' ),
168
+ 'desc_tip' => true,
169
+ 'default' => 'modal',
170
+ 'options' => array(
171
+ 'modal' => __( 'Modal Window', 'woocommerce-mercadopago' ),
172
+ 'redirect' => __( 'Redirect', 'woocommerce-mercadopago' ),
173
+ )
174
+ ),
175
+ 'testing' => array(
176
+ 'title' => __( 'Gateway Testing', 'woocommerce-mercadopago' ),
177
+ 'type' => 'title',
178
+ 'description' => '',
179
+ ),
180
+ 'sandbox' => array(
181
+ 'title' => __( 'MercadoPago Sandbox', 'woocommerce-mercadopago' ),
182
+ 'type' => 'checkbox',
183
+ 'label' => __( 'Enable MercadoPago sandbox', 'woocommerce-mercadopago' ),
184
+ 'default' => 'no',
185
+ 'description' => __( 'MercadoPago sandbox can be used to test payments.', 'woocommerce-mercadopago' ),
186
+ ),
187
+ 'debug' => array(
188
+ 'title' => __( 'Debug Log', 'woocommerce-mercadopago' ),
189
+ 'type' => 'checkbox',
190
+ 'label' => __( 'Enable logging', 'woocommerce-mercadopago' ),
191
+ 'default' => 'no',
192
+ 'description' => sprintf( __( 'Log MercadoPago events, such as API requests, inside %s', 'woocommerce-mercadopago' ), '<code>woocommerce/logs/mercadopago-' . sanitize_file_name( wp_hash( 'mercadopago' ) ) . '.txt</code>' ),
193
+ )
194
+ );
195
+ }
196
+
197
+ /**
198
+ * Generate the payment arguments.
199
+ *
200
+ * @param object $order Order data.
201
+ *
202
+ * @return array Payment arguments.
203
+ */
204
+ public function get_payment_args( $order ) {
205
+
206
+ $args = array(
207
+ 'back_urls' => array(
208
+ 'success' => esc_url( $this->get_return_url( $order ) ),
209
+ 'failure' => esc_url( $order->get_cancel_order_url() ),
210
+ 'pending' => esc_url( $this->get_return_url( $order ) )
211
+ ),
212
+ 'payer' => array(
213
+ 'name' => $order->billing_first_name,
214
+ 'surname' => $order->billing_last_name,
215
+ 'email' => $order->billing_email
216
+ ),
217
+ 'external_reference' => $this->invoice_prefix . $order->id,
218
+ 'items' => array(
219
+ array(
220
+ 'quantity' => 1,
221
+ 'unit_price' => (float) $order->order_total,
222
+ 'currency_id' => get_woocommerce_currency(),
223
+ // 'picture_url' => 'https://www.mercadopago.com/org-img/MP3/home/logomp3.gif'
224
+ )
225
+ )
226
+ );
227
+
228
+ // Cart Contents.
229
+ $item_names = array();
230
+
231
+ if ( sizeof( $order->get_items() ) > 0 ) {
232
+ foreach ( $order->get_items() as $item ) {
233
+ if ( $item['qty'] ) {
234
+ $item_names[] = $item['name'] . ' x ' . $item['qty'];
235
+ }
236
+ }
237
+ }
238
+
239
+ $args['items'][0]['title'] = sprintf( __( 'Order %s', 'woocommerce-mercadopago' ), $order->get_order_number() ) . ' - ' . implode( ', ', $item_names );
240
+
241
+ // Shipping Cost item.
242
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
243
+ $shipping_total = $order->get_total_shipping();
244
+ } else {
245
+ $shipping_total = $order->get_shipping();
246
+ }
247
+
248
+ if ( $shipping_total > 0 ) {
249
+ $args['items'][0]['title'] .= ', ' . __( 'Shipping via', 'woocommerce-mercadopago' ) . ' ' . ucwords( $order->shipping_method_title );
250
+ }
251
+
252
+ $args = apply_filters( 'woocommerce_mercadopago_args', $args, $order );
253
+
254
+ return $args;
255
+ }
256
+
257
+ /**
258
+ * Generate the MercadoPago payment url.
259
+ *
260
+ * @param object $order Order Object.
261
+ *
262
+ * @return string MercadoPago payment url.
263
+ */
264
+ protected function get_mercadopago_url( $order ) {
265
+ $args = json_encode( $this->get_payment_args( $order ) );
266
+
267
+ if ( 'yes' == $this->debug ) {
268
+ $this->log->add( 'mercadopago', 'Payment arguments for order ' . $order->get_order_number() . ': ' . print_r( $this->get_payment_args( $order ), true ) );
269
+ }
270
+
271
+ $url = $this->payment_url . $this->get_client_credentials();
272
+
273
+ $params = array(
274
+ 'body' => $args,
275
+ 'sslverify' => false,
276
+ 'timeout' => 30,
277
+ 'headers' => array( 'content-type' => 'application/json;charset=UTF-8' )
278
+ );
279
+
280
+ $response = wp_remote_post( $url, $params );
281
+
282
+ if ( ! is_wp_error( $response ) && $response['response']['code'] == 201 && ( strcmp( $response['response']['message'], 'Created' ) == 0 ) ) {
283
+ $checkout_info = json_decode( $response['body'] );
284
+
285
+ if ( 'yes' == $this->debug ) {
286
+ $this->log->add( 'mercadopago', 'Payment link generated with success from MercadoPago' );
287
+ }
288
+
289
+ if ( 'yes' == $this->sandbox ) {
290
+ return esc_url( $checkout_info->sandbox_init_point );
291
+ } else {
292
+ return esc_url( $checkout_info->init_point );
293
+ }
294
+
295
+ } else {
296
+ if ( 'yes' == $this->debug ) {
297
+ $this->log->add( 'mercadopago', 'Generate payment error response: ' . print_r( $response, true ) );
298
+ }
299
+ }
300
+
301
+ return false;
302
+ }
303
+
304
+ /**
305
+ * Generate the form.
306
+ *
307
+ * @param int $order_id Order ID.
308
+ *
309
+ * @return string Payment form.
310
+ */
311
+ public function generate_form( $order_id ) {
312
+
313
+ $order = new WC_Order( $order_id );
314
+ $url = $this->get_mercadopago_url( $order );
315
+
316
+ if ( $url ) {
317
+
318
+ // Display checkout.
319
+ $html = '<p>' . __( 'Thank you for your order, please click the button below to pay with MercadoPago.', 'woocommerce-mercadopago' ) . '</p>';
320
+
321
+ $html .= '<a id="submit-payment" href="' . $url . '" name="MP-Checkout" class="button alt" mp-mode="modal">' . __( 'Pay via MercadoPago', 'woocommerce-mercadopago' ) . '</a> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order &amp; restore cart', 'woocommerce-mercadopago' ) . '</a>';
322
+
323
+ // Add MercadoPago JS.
324
+ $html .= '<script type="text/javascript">(function(){function $MPBR_load(){window.$MPBR_loaded !== true && (function(){var s = document.createElement("script");s.type = "text/javascript";s.async = true;s.src = ("https:"==document.location.protocol?"https://www.mercadopago.com/org-img/jsapi/mptools/buttons/":"http://mp-tools.mlstatic.com/buttons/")+"render.js";var x = document.getElementsByTagName("script")[0];x.parentNode.insertBefore(s, x);window.$MPBR_loaded = true;})();}window.$MPBR_loaded !== true ? (window.attachEvent ? window.attachEvent("onload", $MPBR_load) : window.addEventListener("load", $MPBR_load, false)) : null;})();</script>';
325
+
326
+ return $html;
327
+ } else {
328
+ // Display message if a problem occurs.
329
+ $html = '<p>' . __( 'An error has occurred while processing your payment, please try again. Or contact us for assistance.', 'woocommerce-mercadopago' ) . '</p>';
330
+
331
+ $html .= '<a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Click to try again', 'woocommerce-mercadopago' ) . '</a>';
332
+
333
+ return $html;
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Fix MercadoPago CSS.
339
+ *
340
+ * @return string Styles.
341
+ */
342
+ public function css() {
343
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
344
+ $page_id = wc_get_page_id( 'checkout' );
345
+ } else {
346
+ $page_id = woocommerce_get_page_id( 'checkout' );
347
+ }
348
+
349
+ if ( is_page( $page_id ) ) {
350
+ echo '<style type="text/css">#MP-Checkout-dialog { z-index: 9999 !important; }</style>' . PHP_EOL;
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Process the payment and return the result.
356
+ *
357
+ * @param int $order_id Order ID.
358
+ *
359
+ * @return array Redirect.
360
+ */
361
+ public function process_payment( $order_id ) {
362
+
363
+ $order = new WC_Order( $order_id );
364
+
365
+ // Redirect or modal window integration.
366
+ if ( 'redirect' == $this->method ) {
367
+ return array(
368
+ 'result' => 'success',
369
+ 'redirect' => $this->get_mercadopago_url( $order )
370
+ );
371
+ } else {
372
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
373
+ return array(
374
+ 'result' => 'success',
375
+ 'redirect' => $order->get_checkout_payment_url( true )
376
+ );
377
+ } else {
378
+ return array(
379
+ 'result' => 'success',
380
+ 'redirect' => add_query_arg( 'order', $order->id, add_query_arg( 'key', $order->order_key, get_permalink( woocommerce_get_page_id( 'pay' ) ) ) )
381
+ );
382
+ }
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Output for the order received page.
388
+ *
389
+ * @return void
390
+ */
391
+ public function receipt_page( $order ) {
392
+ echo $this->generate_form( $order );
393
+ }
394
+
395
+ /**
396
+ * Get cliente token.
397
+ *
398
+ * @return mixed Sucesse return the token and error return null.
399
+ */
400
+ protected function get_client_credentials() {
401
+
402
+ if ( 'yes' == $this->debug ) {
403
+ $this->log->add( 'mercadopago', 'Getting client credentials...' );
404
+ }
405
+
406
+ // Set postdata.
407
+ $postdata = 'grant_type=client_credentials';
408
+ $postdata .= '&client_id=' . $this->client_id;
409
+ $postdata .= '&client_secret=' . $this->client_secret;
410
+
411
+ // Built wp_remote_post params.
412
+ $params = array(
413
+ 'body' => $postdata,
414
+ 'sslverify' => false,
415
+ 'timeout' => 30
416
+ );
417
+
418
+ $response = wp_remote_post( $this->oauth_token, $params );
419
+
420
+ // Check to see if the request was valid and return the token.
421
+ if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && ( strcmp( $response['response']['message'], 'OK' ) == 0 ) ) {
422
+
423
+ $token = json_decode( $response['body'] );
424
+
425
+ if ( 'yes' == $this->debug ) {
426
+ $this->log->add( 'mercadopago', 'Received valid response from MercadoPago' );
427
+ }
428
+
429
+ return $token->access_token;
430
+ } else {
431
+ if ( 'yes' == $this->debug ) {
432
+ $this->log->add( 'mercadopago', 'Received invalid response from MercadoPago. Error response: ' . print_r( $response, true ) );
433
+ }
434
+ }
435
+
436
+ return null;
437
+ }
438
+
439
+ /**
440
+ * Check IPN.
441
+ *
442
+ * @param array $data MercadoPago post data.
443
+ *
444
+ * @return mixed False or posted response.
445
+ */
446
+ public function check_ipn_request_is_valid( $data ) {
447
+
448
+ if ( ! isset( $data['id'] ) ) {
449
+ return false;
450
+ }
451
+
452
+ if ( 'yes' == $this->debug ) {
453
+ $this->log->add( 'mercadopago', 'Checking IPN request...' );
454
+ }
455
+
456
+ if ( 'yes' == $this->sandbox ) {
457
+ $ipn_url = $this->sandbox_ipn_url;
458
+ } else {
459
+ $ipn_url = $this->ipn_url;
460
+ }
461
+
462
+ $url = $ipn_url . $data['id'] . '?access_token=' . $this->get_client_credentials();
463
+
464
+ // Send back post vars.
465
+ $params = array(
466
+ 'sslverify' => false,
467
+ 'timeout' => 30
468
+ );
469
+
470
+ // GET a response.
471
+ $response = wp_remote_get( $url, $params );
472
+
473
+ if ( 'yes' == $this->debug ) {
474
+ $this->log->add( 'mercadopago', 'IPN Response: ' . print_r( $response, true ) );
475
+ }
476
+
477
+ // Check to see if the request was valid.
478
+ if ( ! is_wp_error( $response ) && 200 == $response['response']['code'] ) {
479
+
480
+ $body = json_decode( $response['body'] );
481
+
482
+ $this->log->add( 'mercadopago', 'Received valid IPN response from MercadoPago' );
483
+
484
+ return $body;
485
+ } else {
486
+ if ( 'yes' == $this->debug ) {
487
+ $this->log->add( 'mercadopago', 'Received invalid IPN response from MercadoPago.' );
488
+ }
489
+ }
490
+
491
+ return false;
492
+ }
493
+
494
+ /**
495
+ * Check API Response.
496
+ *
497
+ * @return void
498
+ */
499
+ public function check_ipn_response() {
500
+ @ob_clean();
501
+
502
+ $data = $this->check_ipn_request_is_valid( $_GET );
503
+
504
+ if ( $data ) {
505
+ header( 'HTTP/1.1 200 OK' );
506
+ do_action( 'valid_mercadopago_ipn_request', $data );
507
+ } else {
508
+ wp_die( __( 'MercadoPago Request Failure', 'woocommerce-mercadopago' ) );
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Successful Payment!
514
+ *
515
+ * @param array $posted MercadoPago post data.
516
+ *
517
+ * @return void
518
+ */
519
+ public function successful_request( $posted ) {
520
+
521
+ $data = $posted->collection;
522
+ $order_key = $data->external_reference;
523
+
524
+ if ( ! empty( $order_key ) ) {
525
+ $order_id = (int) str_replace( $this->invoice_prefix, '', $order_key );
526
+
527
+ $order = new WC_Order( $order_id );
528
+
529
+ // Checks whether the invoice number matches the order.
530
+ // If true processes the payment.
531
+ if ( $order->id === $order_id ) {
532
+
533
+ if ( 'yes' == $this->debug )
534
+ $this->log->add( 'mercadopago', 'Payment status from order ' . $order->get_order_number() . ': ' . $data->status );
535
+
536
+ switch ( $data->status ) {
537
+ case 'approved':
538
+
539
+ // Order details.
540
+ if ( ! empty( $data->id ) ) {
541
+ update_post_meta(
542
+ $order_id,
543
+ __( 'MercadoPago Transaction ID', 'woocommerce-mercadopago' ),
544
+ $data->id
545
+ );
546
+ }
547
+ if ( ! empty( $data->payer->email ) ) {
548
+ update_post_meta(
549
+ $order_id,
550
+ __( 'Payer email', 'woocommerce-mercadopago' ),
551
+ $data->payer->email
552
+ );
553
+ }
554
+ if ( ! empty( $data->payment_type ) ) {
555
+ update_post_meta(
556
+ $order_id,
557
+ __( 'Payment type', 'woocommerce-mercadopago' ),
558
+ $data->payment_type
559
+ );
560
+ }
561
+
562
+ // Payment completed.
563
+ $order->add_order_note( __( 'MercadoPago: Payment approved.', 'woocommerce-mercadopago' ) );
564
+ $order->payment_complete();
565
+
566
+ break;
567
+ case 'pending':
568
+ $order->add_order_note( __( 'MercadoPago: The user has not completed the payment process yet.', 'woocommerce-mercadopago' ) );
569
+
570
+ break;
571
+ case 'in_process':
572
+ $order->update_status( 'on-hold', __( 'MercadoPago: Payment under review.', 'woocommerce-mercadopago' ) );
573
+
574
+ break;
575
+ case 'rejected':
576
+ $order->add_order_note( __( 'MercadoPago: The payment was declined. The user can try again.', 'woocommerce-mercadopago' ) );
577
+
578
+ break;
579
+ case 'refunded':
580
+ $order->update_status( 'refunded', __( 'MercadoPago: The payment was returned to the user.', 'woocommerce-mercadopago' ) );
581
+
582
+ break;
583
+ case 'cancelled':
584
+ $order->update_status( 'cancelled', __( 'MercadoPago: Payment canceled.', 'woocommerce-mercadopago' ) );
585
+
586
+ break;
587
+ case 'in_mediation':
588
+ $order->add_order_note( __( 'MercadoPago: It started a dispute for payment.', 'woocommerce-mercadopago' ) );
589
+
590
+ break;
591
+
592
+ default:
593
+ // No action xD.
594
+ break;
595
+ }
596
+ }
597
+ }
598
+ }
599
+
600
+ /**
601
+ * Gets the admin url.
602
+ *
603
+ * @return string
604
+ */
605
+ protected function admin_url() {
606
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
607
+ return admin_url( 'admin.php?page=wc-settings&tab=checkout&section=wc_mercadopago_gateway' );
608
+ }
609
+
610
+ return admin_url( 'admin.php?page=woocommerce_settings&tab=payment_gateways&section=WC_MercadoPago_Gateway' );
611
+ }
612
+
613
+ /**
614
+ * Adds error message when not configured the client_id.
615
+ *
616
+ * @return string Error Mensage.
617
+ */
618
+ public function client_id_missing_message() {
619
+ echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'You should inform your Client_id. %s', 'woocommerce-mercadopago' ), '<a href="' . $this->admin_url() . '">' . __( 'Click here to configure!', 'woocommerce-mercadopago' ) . '</a>' ) . '</p></div>';
620
+ }
621
+
622
+ /**
623
+ * Adds error message when not configured the client_secret.
624
+ *
625
+ * @return string Error Mensage.
626
+ */
627
+ public function client_secret_missing_message() {
628
+ echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'You should inform your Client_secret. %s', 'woocommerce-mercadopago' ), '<a href="' . $this->admin_url() . '">' . __( 'Click here to configure!', 'woocommerce-mercadopago' ) . '</a>' ) . '</p></div>';
629
+ }
630
+
631
+ /**
632
+ * Adds error message when an unsupported currency is used.
633
+ *
634
+ * @return string
635
+ */
636
+ public function currency_not_supported_message() {
637
+ echo '<div class="error"><p><strong>' . __( 'MercadoPago Disabled', 'woocommerce-mercadopago' ) . '</strong>: ' . sprintf( __( 'Currency <code>%s</code> is not supported. Please make sure that you use one of the following supported currencies: ARS, BRL, MXN, USD or VEF.', 'woocommerce-mercadopago' ), get_woocommerce_currency() ) . '</p></div>';
638
+ }
639
+ }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: claudiosanches
3
  Donate link: http://claudiosmweb.com/doacoes/
4
  Tags: woocommerce, mercadopago, payment
5
  Requires at least: 3.5
6
- Tested up to: 3.7.1
7
- Stable tag: 1.7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -32,6 +32,10 @@ O plugin WooCommerce MercadoPago foi desenvolvido sem nenhum incentivo do Mercad
32
 
33
  Este plugin foi feito baseado na [documentação oficial do MercadoPago](http://developers.mercadopago.com/).
34
 
 
 
 
 
35
  = Instalação: =
36
 
37
  Confira o nosso guia de instalação e configuração do WooCommerce MercadoPago na aba [Installation](http://wordpress.org/extend/plugins/woocommerce-mercadopago/installation/).
@@ -90,7 +94,7 @@ Você pode acessar as suas informações de Client_id e Client_secret em:
90
 
91
  Deve ser configurada a sua página de retorno como por exemplo:
92
 
93
- http://seusite.com/?wc-api=WC_MercadoPago_Gateway
94
 
95
  = Configurações do Plugin: =
96
 
@@ -116,7 +120,7 @@ Para corrigir isso é necessário ir em "WooCommerce" > "Configurações" > "Inv
116
 
117
  = What is needed to use this plugin? =
118
 
119
- * WooCommerce installed and active
120
  * Only one account on [MercadoPago](https://www.mercadopago.com/ "MercadoPago").
121
  * Get the information of Client_id and Client_secret from MercadoPago.
122
  * Set page of automatic return data.
@@ -135,7 +139,7 @@ Este plugin esta licenciado como GPL.
135
 
136
  = O que eu preciso para utilizar este plugin? =
137
 
138
- * Ter instalado o plugin WooCommerce.
139
  * Possuir uma conta no MercadoPago.
140
  * Pegar as informações de Client_id e Client_secret.
141
  * Configurar a página de retorno automático de dados.
@@ -184,6 +188,12 @@ Entre em contato [clicando aqui](http://claudiosmweb.com/plugins/mercadopago-par
184
 
185
  == Changelog ==
186
 
 
 
 
 
 
 
187
  = 1.7.0 - 03/11/2013 =
188
 
189
  * Corrigido o textdomain para suportar o padrão do WordPress 3.7.
@@ -210,7 +220,7 @@ Entre em contato [clicando aqui](http://claudiosmweb.com/plugins/mercadopago-par
210
  * Adicionada compatibilidade com o WooCommerce 2.1 ou superior.
211
  * Atualização das traduções em pt_BR e es_AR.
212
 
213
- = 1.3 - 07/04/2013 =
214
 
215
  * Correção do retorno automático de dados na versão 2.0.0 ou superior do WooCommerce.
216
  * Atualização das traduções em pt_BR e es_AR.
@@ -227,7 +237,7 @@ Entre em contato [clicando aqui](http://claudiosmweb.com/plugins/mercadopago-par
227
 
228
  * Corrigido o hook responsavel por salvar as opções para a versão 2.0 RC do WooCommerce.
229
 
230
- = 1.2 - 01/12/2012 =
231
 
232
  * Adicionada tradução para es_AR por [Gustavo Coronel](http://profiles.wordpress.org/gcoronel/)
233
 
@@ -235,19 +245,20 @@ Entre em contato [clicando aqui](http://claudiosmweb.com/plugins/mercadopago-par
235
 
236
  * Correção dos logs de erro.
237
 
238
- = 1.1 - 30/11/2012 =
239
 
240
  * Adicionada opção para logs de erro.
241
 
242
- = 1.0 =
243
 
244
  * Versão Inicial.
245
 
246
  == Upgrade Notice ==
247
 
248
- = 1.7.0 =
249
 
250
- * Adicionada compatibilidade com o plugin Currency Switcher for WooCommerce
 
251
 
252
  == License ==
253
 
3
  Donate link: http://claudiosmweb.com/doacoes/
4
  Tags: woocommerce, mercadopago, payment
5
  Requires at least: 3.5
6
+ Tested up to: 3.8
7
+ Stable tag: 1.8.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
32
 
33
  Este plugin foi feito baseado na [documentação oficial do MercadoPago](http://developers.mercadopago.com/).
34
 
35
+ = Compatibilidade =
36
+
37
+ Compatível com as versões 2.0.x e 2.1.x do WooCommerce.
38
+
39
  = Instalação: =
40
 
41
  Confira o nosso guia de instalação e configuração do WooCommerce MercadoPago na aba [Installation](http://wordpress.org/extend/plugins/woocommerce-mercadopago/installation/).
94
 
95
  Deve ser configurada a sua página de retorno como por exemplo:
96
 
97
+ http://seusite.com/?wc-api=WC_MercadoPago_Gateway
98
 
99
  = Configurações do Plugin: =
100
 
120
 
121
  = What is needed to use this plugin? =
122
 
123
+ * WooCommerce version 2.0 or latter installed and active.
124
  * Only one account on [MercadoPago](https://www.mercadopago.com/ "MercadoPago").
125
  * Get the information of Client_id and Client_secret from MercadoPago.
126
  * Set page of automatic return data.
139
 
140
  = O que eu preciso para utilizar este plugin? =
141
 
142
+ * Ter instalado o plugin WooCommerce 2.0 ou superior.
143
  * Possuir uma conta no MercadoPago.
144
  * Pegar as informações de Client_id e Client_secret.
145
  * Configurar a página de retorno automático de dados.
188
 
189
  == Changelog ==
190
 
191
+ = 1.8.0 - 04/12/2013 =
192
+
193
+ * Corrigido padrões de código.
194
+ * Removida compatibilidade com versões 1.6.x ou inferiores do WooCommerce.
195
+ * Adicionada compatibilidade com WooCommerce 2.1 ou superior.
196
+
197
  = 1.7.0 - 03/11/2013 =
198
 
199
  * Corrigido o textdomain para suportar o padrão do WordPress 3.7.
220
  * Adicionada compatibilidade com o WooCommerce 2.1 ou superior.
221
  * Atualização das traduções em pt_BR e es_AR.
222
 
223
+ = 1.3.0 - 07/04/2013 =
224
 
225
  * Correção do retorno automático de dados na versão 2.0.0 ou superior do WooCommerce.
226
  * Atualização das traduções em pt_BR e es_AR.
237
 
238
  * Corrigido o hook responsavel por salvar as opções para a versão 2.0 RC do WooCommerce.
239
 
240
+ = 1.2.0 - 01/12/2012 =
241
 
242
  * Adicionada tradução para es_AR por [Gustavo Coronel](http://profiles.wordpress.org/gcoronel/)
243
 
245
 
246
  * Correção dos logs de erro.
247
 
248
+ = 1.1.0 - 30/11/2012 =
249
 
250
  * Adicionada opção para logs de erro.
251
 
252
+ = 1.0.0 =
253
 
254
  * Versão Inicial.
255
 
256
  == Upgrade Notice ==
257
 
258
+ = 1.8.0 =
259
 
260
+ * Removida compatibilidade com versões 1.6.x ou inferiores do WooCommerce.
261
+ * Adicionada compatibilidade com WooCommerce 2.1 ou superior.
262
 
263
  == License ==
264
 
wc-mercadopago.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: MercadoPago gateway for Woocommerce.
6
  * Author: claudiosanches
7
  * Author URI: http://claudiosmweb.com/
8
- * Version: 1.7.0
9
  * License: GPLv2 or later
10
  * Text Domain: woocommerce-mercadopago
11
  * Domain Path: /languages/
@@ -15,7 +15,7 @@
15
  * WooCommerce fallback notice.
16
  */
17
  function wcmercadopago_woocommerce_fallback_notice() {
18
- echo '<div class="error"><p>' . sprintf( __( 'WooCommerce MercadoPago Gateway depends on the last version of %s to work!', 'woocommerce-mercadopago' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a>' ) . '</p></div>';
19
  }
20
 
21
  /**
@@ -23,34 +23,34 @@ function wcmercadopago_woocommerce_fallback_notice() {
23
  */
24
  function wcmercadopago_gateway_load() {
25
 
26
- if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
27
- add_action( 'admin_notices', 'wcmercadopago_woocommerce_fallback_notice' );
28
 
29
- return;
30
- }
31
 
32
- /**
33
- * Load textdomain.
34
- */
35
- load_plugin_textdomain( 'woocommerce-mercadopago', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
36
 
37
- /**
38
- * Add the gateway to WooCommerce.
39
- *
40
- * @param array $methods Default methods.
41
- *
42
- * @return array Methods with MercadoPago gateway.
43
- */
44
- function wcmercadopago_add_gateway( $methods ) {
45
- $methods[] = 'WC_MercadoPago_Gateway';
46
 
47
- return $methods;
48
- }
49
 
50
- add_filter( 'woocommerce_payment_gateways', 'wcmercadopago_add_gateway' );
51
 
52
- // Include the WC_MercadoPago_Gateway class.
53
- require_once plugin_dir_path( __FILE__ ) . 'class-wc-mercadopago-gateway.php';
54
 
55
  }
56
 
@@ -62,35 +62,16 @@ add_action( 'plugins_loaded', 'wcmercadopago_gateway_load', 0 );
62
  * @return void
63
  */
64
  function wcmercadopago_legacy_ipn() {
65
- if ( isset( $_GET['topic'] ) && ! isset( $_GET['wc-api'] ) ) {
66
- global $woocommerce;
67
-
68
- $woocommerce->payment_gateways();
69
-
70
- do_action( 'woocommerce_api_wc_mercadopago_gateway' );
71
- }
 
 
 
72
  }
73
 
74
  add_action( 'init', 'wcmercadopago_legacy_ipn' );
75
-
76
- /**
77
- * Adds custom settings url in plugins page.
78
- *
79
- * @param array $links Default links.
80
- *
81
- * @return array Default links and settings link.
82
- */
83
- function wcmercadopago_action_links( $links ) {
84
-
85
- $settings = array(
86
- 'settings' => sprintf(
87
- '<a href="%s">%s</a>',
88
- admin_url( 'admin.php?page=woocommerce_settings&tab=payment_gateways&section=WC_MercadoPago_Gateway' ),
89
- __( 'Settings', 'woocommerce-mercadopago' )
90
- )
91
- );
92
-
93
- return array_merge( $settings, $links );
94
- }
95
-
96
- add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wcmercadopago_action_links' );
5
  * Description: MercadoPago gateway for Woocommerce.
6
  * Author: claudiosanches
7
  * Author URI: http://claudiosmweb.com/
8
+ * Version: 1.8.0
9
  * License: GPLv2 or later
10
  * Text Domain: woocommerce-mercadopago
11
  * Domain Path: /languages/
15
  * WooCommerce fallback notice.
16
  */
17
  function wcmercadopago_woocommerce_fallback_notice() {
18
+ echo '<div class="error"><p>' . sprintf( __( 'WooCommerce MercadoPago Gateway depends on the last version of %s to work!', 'woocommerce-mercadopago' ), '<a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a>' ) . '</p></div>';
19
  }
20
 
21
  /**
23
  */
24
  function wcmercadopago_gateway_load() {
25
 
26
+ if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
27
+ add_action( 'admin_notices', 'wcmercadopago_woocommerce_fallback_notice' );
28
 
29
+ return;
30
+ }
31
 
32
+ /**
33
+ * Load textdomain.
34
+ */
35
+ load_plugin_textdomain( 'woocommerce-mercadopago', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
36
 
37
+ /**
38
+ * Add the gateway to WooCommerce.
39
+ *
40
+ * @param array $methods Default methods.
41
+ *
42
+ * @return array Methods with MercadoPago gateway.
43
+ */
44
+ function wcmercadopago_add_gateway( $methods ) {
45
+ $methods[] = 'WC_MercadoPago_Gateway';
46
 
47
+ return $methods;
48
+ }
49
 
50
+ add_filter( 'woocommerce_payment_gateways', 'wcmercadopago_add_gateway' );
51
 
52
+ // Include the WC_MercadoPago_Gateway class.
53
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-wc-mercadopago-gateway.php';
54
 
55
  }
56
 
62
  * @return void
63
  */
64
  function wcmercadopago_legacy_ipn() {
65
+ if ( isset( $_GET['topic'] ) && ! isset( $_GET['wc-api'] ) ) {
66
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.1', '>=' ) ) {
67
+ WC()->payment_gateways();
68
+ } else {
69
+ global $woocommerce;
70
+ $woocommerce->payment_gateways();
71
+ }
72
+
73
+ do_action( 'woocommerce_api_wc_mercadopago_gateway' );
74
+ }
75
  }
76
 
77
  add_action( 'init', 'wcmercadopago_legacy_ipn' );