Open esteban-turnocheck opened 5 years ago
Muy bueno, te comparto uno que uso en codeigniter: (tiene el IPN también)
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Mercadopago extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('backend/Producers_model','producers');
$this->load->model('frontend/Cart_model', 'cart');
}
public function auth_provider_get($producer_id_encode)
{
$producer_id = $this->pcrypt->data('decode', $producer_id_encode);
$get_code = $this->input->get('code');
$mp = new MP(wmscp('access_token','mercadopago'));
$request = array(
"uri" => "/oauth/token",
"data" => array(
"client_id" => wmscp('client_id','mercadopago'),
"client_secret" => wmscp('client_secret','mercadopago'),
"grant_type" => "authorization_code",
"code" => $get_code,
"redirect_uri" => 'https://'.$this->config->item('app','url_website').'/auth/code/'.$producer_id_encode
),
"headers" => array(
"content-type" => "application/x-www-form-urlencoded"
),
"authenticate" => false
);
$mp_resp = $mp->post($request);
$info = array(
'p_mp_access_token' => $mp_resp['response']['access_token'],
'p_mp_public_key' => $mp_resp['response']['public_key'],
'p_mp_refresh_token' => $mp_resp['response']['refresh_token'],
'p_mp_user_id' => $mp_resp['response']['user_id'],
'p_mp_expires_in' => $mp_resp['response']['expires_in'],
'p_mp_scope' => $mp_resp['response']['scope'],
'p_mp_live_mode' => $mp_resp['response']['live_mode'],
'p_mp_token_type' => $mp_resp['response']['token_type'],
'p_mp_status' => 1
);
$update = $this->producers->update_item($info, $producer_id);
redirect(wmscp('url_access_producers'),'refresh');
}
public function mercadopago_ipn_get()
{
$mp = new MP(wmscp('mp_client_id'), wmscp('mp_client_secret'));
if (!isset($_GET["id"], $_GET["topic"]) || !ctype_digit($_GET["id"])) {
$this->output->set_status_header(400);
return;
}
$params = ["access_token" => $mp->get_access_token()];
$collection_id = $_GET["id"];
if($_GET["topic"] == 'payment'){
$payment_info = $mp->get("/v1/payments/" . $_GET["id"], $params, false);
$merchant_order_info = $mp->get("/merchant_orders/" . $payment_info["response"]["order"]["id"], $params, false);
} else if($_GET["topic"] == 'merchant_order'){
$merchant_order_info = $mp->get("/merchant_orders/" . $_GET["id"], $params, false);
}
if ($merchant_order_info["status"] == 200) {
$payments=$merchant_order_info["response"]["payments"];
$payment_status = 'pending';
foreach ($payments as $payment) {
if($payment['status'] == 'approved'){
$payment_status = 'approved';
}
}
$info = array(
'or_collection_status' => $payment_status
);
$update_order = $this->cart->update_order_ipn($info,$collection_id);
}
}
}
Por otro lado, todavía no pude probar si un vendedor, desautoriza la app, cómo me notifica a mi mercadopago? Tenes idea?
Abrazo
Qué interesante. Ahí en tu código veo que decidiste no escuchar las IPN que vienen con topic=merchant_order, que fue una de las cosas que originaron todo este asunto y derivaron en este repo/foro. Porque (lo digo por ahí en el post más largo) cuando te viene el topic=merchant_order, vos tenés que ir a buscar esa merchant_order con el id que te viene. Pero para eso necesitás las credenciales del vendedor en tu marketplace que generó esa merchant order, y no lo tenés, ni tenés en ningún momento la posibilidad de asociar al vendedor con la merchant order. Una opción que yo planteaba era esa, la que hiciste vos, que es no darle bola al topic=merchant_order. La otra, la que finalmente implementé yo, es no usar ni IPN ni webhooks. Hice un cronjob que corre cada tanto, y que me trae todos los payments, y en función del external reference voy procesando cada uno para cada vendedor. Yo yampoco pude probar qué pasa cuando un vendedor te desautoriza la app, pero en un rato voy a correr unos test con un cliente, y ahí hago esa prueba y comento después acá, es buena pregunta. Me imagino que te debe dar un famoso "invalid_caller_id" cuando vas a buscar la merchant_order, pero ya lo probaré.
Si, hay que probar con guardar el log, a ver que informa mercadopago al ipn puesto en la app, cuando un vendedor desautoriza. yo apenas pueda lo hago.
En cuanto a ese IPN, lo uso en un sitio ecommerce de una sola persona. En el que tengo con marketplace, hice como hiciste vos, directamente no uso IPN y tengo un cron que comprueba por external_reference
o merchant_order_id
$search_result = (is_null($order_info->or_merchant_order_id)) ? $mp->get('/v1/payments/search?external_reference='.$order_info->or_number) : $mp->search_payment(array('merchant_order_id' => $order_info->or_merchant_order_id),0,10) ;