Es una ayuda memora en referencia a la excelente información que está en Mercadopago Developers
-
Crear una aplicación para marketplace donde:
- en Redirect URI deben poner la url con https://dominio.com/auth/mercadopago ese formato uso en mi caso; esta url es la que los usuarios van a ser redireccionados luego de confirmar la autorización.
- tildar los scopes read, write, offline access
- topicos recomendados: items, orders, create orders, payments
- url de callback, es la url en donde van a recibir las notificaciones de MP, yo uso https://dominio.com/webhook/mercadopago
-
Crear un boton en el backend o panel de administración de tu vendedor, para que pueda vincular su cuenta de mercadopago al marketplace. Ese boton debe tener el siguiente formato:
https://auth.mercadopago.com.ar/authorization?client_id={APP_ID}&response_type=code&platform_id=mp&state={USER_ID_REF}&redirect_uri=https%3A%2F%2Fdominio.com/auth/mercadopago
, donde{APP_ID}
es el número que corresponde a tu app de marketplace;{USER_ID_REF}
es un código identificador para luego saber que usuario estás conectando yredirect_uri
es la misma url que setearon al crear la app. -
En el código, en la entrada en donde es redireccionado el vendedor, siguiendo el ejemplo
dominio.com/auth/mercadopago
tenes que tener un código similar a esto:
public function auth_provider()
{
$code = $this->input->get('code');
$state = $this->input->get('state');
// Compruebo que la url tenga el ?code= y el state de mercadopago
if (isset($code) AND isset($docId)) {
// Configuro para hacer el POST y obtener el token y datos del usuario
$url = 'https://api.mercadopago.com/oauth/token';
$post = '&client_secret='.$this->accessToken.'&grant_type=authorization_code&code='.$code.'&redirect_uri=https://dominio.com/auth/mercadopago';
$mpResp = $this->utility->curlAPIRestPOST($url,$post,$this->accessToken);
if ($mpResp->status == 200) {
// Actualizo en mi DB los datos obtenidos
$info = array(
'mp_access_token' => $mpResp->access_token,
'mp_public_key' => $mpResp->public_key,
'mp_refresh_token' => $mpResp->refresh_token,
'mp_user_id' => $mpResp->user_id,
'mp_expires_in' => $mpResp->expires_in,
'mp_created_at' => date('Y-m-d H:i:s', time()),
'mp_scope' => $mpResp->scope,
'mp_live_mode' => $mpResp->live_mode,
'mp_token_type' => $mpResp->token_type,
'mp_status' => 1
);
$update = $this->professionals->update_info($info, $docId);
// Esto no es necesario pero lo hago para obtener el nick en ML del usuario para que pueda identificar la cuenta
$url_get = 'https://api.mercadolibre.com/users/me';
$mpResp = $this->utility->curlAPIRestGET($url_get,$this->accessToken);
$info = array(
'doc_mp_nick_name' => $mpResp->nickname,
'doc_email_mercadopago' => $mpResp->email
);
$update = $this->professionals->update_info($info, $pdocIdid);
}
}
// Redireccionar a otra web o mostrarle una vista.
........
}
public function curlAPIRestPOST($url,$post,$accessToken)
{
$curl = curl_init();
curl_setopt_array($curl,[
CURLOPT_URL => $url,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $post,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPHEADER => array(
"Authorization: Bearer ".$accessToken,
),
]);
$response = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$contents = json_decode($response);
if ($httpcode == 200) {
$contents->status = 200;
return $contents;
} else {
$contents->status = 400;
return $contents;
}
}
public function curlAPIRestGET($url, $accessToken)
{
$curl = curl_init();
curl_setopt_array($curl,[
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPHEADER => array(
"Authorization: Bearer ".$accessToken,
),
]);
$response = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$contents = json_decode($response);
if ($httpcode == 200) {
$contents->status = 200;
return $contents;
} else {
$contents->status = 400;
return $contents;
}
}
// Set del Access Token del vendedor
MercadoPago\SDK::setAccessToken(ACCESS_TOKEN_DEL_VENDEDOR);
// Si son Mercadopago Dev Certificados, tienen ese código, sino omitir esa linea
MercadoPago\SDK::setIntegratorId(getenv('MP_DEV_CODE'));
$preference = new MercadoPago\Preference();
$item = new MercadoPago\Item();
$item->id = 22233;
$item->title = 'Nombre del Producto o texto para que el comprador identifique que está pagando';
$item->currency_id = 'ARS';
$item->description = 'Breve descripción';
$item->picture_url = 'URL de la imagen del producto';
$item->quantity = 1;
$item->unit_price = (float)$price;
$preference->items = array($item);
$payer = new MercadoPago\Payer();
$payer->name = 'Nombre del Comprador';
$payer->surname = 'Apellido del Comprador';
$payer->email = 'Dirección de Email;
$payer->date_created = 'Fecha de registro del usuario en nuestro sistema, en formato: date('Y-m-d\TH:i:s.vP')';
$payer->identification = array(
"type" => "DNI",
"number" => 'Número de DNI'
);
$payer->identification_type = 'DNI';
$payer->identification_number = 'Número de DNI';
$payer->phone = array(
"area_code" => "54",
"number" => 'Número de Teléfono'
);
$payer->area_code = '54';
$payer->number = 'Número de Teléfono';
$payer->address = array(
"street_name" => 'Domicilio',
"zip_code" => 'Código Postal'
);
$payer->authentication_type = 'Web Nativa'; // Pueden ser Gmail, Facebook, Web Nativa, Otro.
$payer->registration_date = 'Fecha de registro del usuario en nuestro sistema, en formato: date('Y-m-d\TH:i:s.vP')';
$payer->is_first_purchase_online = 'TRUE o FALSE si es la primera vez que compra.;
$payer->last_purchase = "Si is_first_purchase_online = TRUE deberán ingresar la fecha de la última vez que compró en formato: date('Y-m-d\TH:i:s.vP')";
$preference->payer = $payer;
// Opcional por si quieren quitar métodos de pago de la preferencia y setear las cuotas
$preference->payment_methods = array(
"excluded_payment_types" => array(
array("id" => "atm"),
array('id' => 'bank_transfer'),
array('id' => 'ticket')
),
"installments" => 12,
"default_installments" => 1
);
// Opcional para setear las url de pago aprobado, fallido o pendiente
$preference->back_urls = array(
"success" => 'https://dominio.com/mp/ok',
"failure" => 'https://dominio.com/mp/error',
"pending" => 'https://dominio.com/mp/pending'
);
// Retorna siempre
$preference->auto_return = "all";
// Para que no tenga estados pendientes de pago
$preference->binary_mode = TRUE;
// Creación de un código external reference para vincular el pago con un pedido en nuestra DB
$preference->external_reference = $codecart;
// Si van a cobrar una comision por venta
$preference->marketplace_fee = (float)$mp_fee_owner;
// Opcional para setear las url del webhook
$preference->notification_url = 'https://dominio.com/webhook/mercadopago';
// Crea la preferencia
$preference->save();
// Redirecciona al webcheckout de mercadopago, pueden usar este método u otros como poner el link en un boton y mostrar en una vista con el detalle de la compra y el boton pagar.
redirect($preference->{gcfg('mp_mode',NULL)},'refresh');
-
Acceder en la siguiente URL
https://www.mercadopago.com/mla/account/webhooks
y configurar en modo producción la url donde van a recibir las notificaciones de mercadopago, y tildar los eventos que desean captar, mis recomendados son: pagos, aplicaciones conectadas/desconectadas y split de pagos. Siguiente el ejemplo, usarhttps://dominio.com/webhook/mercadopago
y al presionar probar, le debe dar un response ok 200 -
Luego crear un código en la ruta del dominio seteado:
https://dominio.com/webhook/mercadopago
mi código es algo así:
public function webhook()
{
MercadoPago\SDK::setAccessToken(ACCESS_TOKEN_MARKETPLACE);
MercadoPago\SDK::setIntegratorId(getenv('MP_DEV_CODE'));
$info = json_decode($this->input->raw_input_stream);
if (isset($info->type)) {
switch ($info->type) {
case 'mp-connect':
// Desvinculo de mi sistema cuando el usuario desautoriza la app desde su cuenta de Mercadopago.
if ($info->action == 'application.deauthorized') {
$data_update = array(
'mp_access_token' => NULL,
'mp_public_key' => NULL,
'mp_refresh_token' => NULL,
'mp_user_id' => NULL,
'mp_expires_in' => NULL,
'mp_status' => 0
);
$this->producers->update_mp_connect($data_update, $info->user_id);
$this->output->set_status_header(200);
return;
}
// Pueden tomar otra acción si el $info->action = 'application.authrized'
break;
case 'payment':
// Actualizo la información de pago recibida.
$or_collection_id = $info->data->id;
$info = MercadoPago\Payment::find_by_id($or_collection_id);
$or_number = $info->external_reference;
$data_update = array(
'or_collection_status' => $info->status,
'or_collection_status_detail' => $info->status_detail,
'or_payment_type' => $info->payment_type_id,
'or_payment_method' => $info->payment_method_id,
'or_status' => gcfg($info->status,'or_status_collection_status')
);
$this->cart->update_ipn_order($data_update,$or_number);
break;
default:
$this->output->set_status_header(200);
return;
break;
}
}
$this->output->set_status_header(200);
return;
}
Estoy en la misma que vos, pudiste solucionarlo?