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;
}
Hola colegas, de antemano te agradezco mucho la información, realmente es de mucha ayuda en ese tema del marketplace con mercado pago que para mi experiencia no es muy claro de como utilizar, ahora tengo una duda sobre su integración, quizá me puedas dar una luz frente a como usar esta integración cuando un solo comprador va a realizar la compra mediante un carrito de compras a dos o más diferentes vendedores?, es decir el le va a comprar n artículos al vendedor x y n artículos al vendedor y, ¿Qué debo hacer para cobrar en nombre de los dos al mismo tiempo?, ¿deben hacerse dos transacciones por separadas?, estoy demasiado confundido con esto y realmente es lo único que me tiene estancado en este desarrollo, te agradezco mucho tu ayuda.