Skip to content

Instantly share code, notes, and snippets.

@plencovich
Last active August 27, 2024 19:22
Show Gist options
  • Save plencovich/acde7aac03c23146c2d5a0cff5656bc3 to your computer and use it in GitHub Desktop.
Save plencovich/acde7aac03c23146c2d5a0cff5656bc3 to your computer and use it in GitHub Desktop.
Breve explicación para poder crear una app en Mercadopago para tener un marketplace

Plenco

Mercadopago Marketplace

Mini tutorial para crear una app de marketplace en mercadopago usando PHP y DX-PHP

Es una ayuda memora en referencia a la excelente información que está en Mercadopago Developers

Creación de APP y Conexión de Usuarios.

  1. 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
  2. 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 y redirect_uri es la misma url que setearon al crear la app.

  3. 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.
        ........
    }

Funciones de cURL GET y POST que utilizo en una librería

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;
        }
    }

Creación de preferencia de pago para checkout

// 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');

Información adicional en las preferencias de pago para la prevención de fraude y contracargos:

Configuración del Webhooks

  1. 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, usar https://dominio.com/webhook/mercadopago y al presionar probar, le debe dar un response ok 200

  2. 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;
}
@plencovich
Copy link
Author

@Wagimo entonces tendrías que asegurarte que las 3 partes sean usuarios de prueba. cuenta marketplace. cuenta vendedor, cuenta cliente.
Y sino podes hacer en tu cuenta de mercadopago, crear un marketplace; con otra cuenta real de mercadopago conectarte a ese marketplace como vendedor; y con otra cuenta de mercadopago ser el cliente; y en la configuración de tu proyecto usas siempre las credenciales de sandbox, con el sandbox_init_point.

@joaquincanete
Copy link

Hola estimado desde ya gracias por compartir tu experiencia es de mucha ayuda para muchos !!!, te cuento que no estoy pudiendo agregar la preferencia de payer para especificar si compra por primera ves. uso el plugin de mercado pago para woocommerce en wordpress y estoy rindiendo la certificación de integración y no logro colocar la preferencia en el archivo que corresponde.

la preferencia de warranty = true ya la coloque en class-wc-woomercadopago-preference-abstract.php y funciono no estoy dando donde sumar la preferencia de si es primer compra. muchas gracias

@faaguilars
Copy link

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.

@apastrana-auntap
Copy link

Buenas colegas, gracias por compartir esta información. Quería hacer una consulta, me encuentro trabajando con la API de checkout de MP y puedo configurar todas las opciones sin problema, salvo marketplace_fee. En la documentación oficial https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post dice que solo se puede enviar si esta configurado un marketplace valido (otra propiedades dentro de la preferencia).

Mi consulta seria si alguno sabe a que hace referencia el campo marketplace y donde se obtiene el string (campo alfanumérico) para indicarlo?

Desde ya muchas gracias por la ayuda.

@tomasmalio
Copy link

Hola, ¿cómo estás? Disculpa que te moleste pero me llama la atención la poca documentación de MercadoPago y estaba viendo el código de lo que implementaste.

HIce un desarrollo similar en Node JS pero me está fallando el Checkout. Tengo generado el access_token del vendedor pero cuando armo todo para hacer el POST, me tira un error de que es invalido:

{ "message": "collector_id invalid", "error": "invalid_collector_id", "status": 400, "cause": null }

Lo que no estoy usando ahora es el access_token del marketplace, únicamente el access_token del vendedor, el marketplace_fee que lo tengo definido estático y listo.

Muchas gracias desde ya por tu ayuda, un saludo.
Tomás

@josebuffalo
Copy link

revisa la configuracion de la aplicacion en mercadopago, tiene que estar definida como MARKETPLACE para tener collector_id definido.

@agustinzamar
Copy link

Buenas colegas, gracias por compartir esta información. Quería hacer una consulta, me encuentro trabajando con la API de checkout de MP y puedo configurar todas las opciones sin problema, salvo marketplace_fee. En la documentación oficial https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post dice que solo se puede enviar si esta configurado un marketplace valido (otra propiedades dentro de la preferencia).

Mi consulta seria si alguno sabe a que hace referencia el campo marketplace y donde se obtiene el string (campo alfanumérico) para indicarlo?

Desde ya muchas gracias por la ayuda.

Hola, como estas? Año 2023 y sigue sin decir nada la documentacion oficial. Pudiste resolver eso? De donde se obtiene el valor del campo marketplace?

@plencovich
Copy link
Author

Buenas colegas, gracias por compartir esta información. Quería hacer una consulta, me encuentro trabajando con la API de checkout de MP y puedo configurar todas las opciones sin problema, salvo marketplace_fee. En la documentación oficial https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post dice que solo se puede enviar si esta configurado un marketplace valido (otra propiedades dentro de la preferencia).
Mi consulta seria si alguno sabe a que hace referencia el campo marketplace y donde se obtiene el string (campo alfanumérico) para indicarlo?
Desde ya muchas gracias por la ayuda.

Hola, como estas? Año 2023 y sigue sin decir nada la documentacion oficial. Pudiste resolver eso? De donde se obtiene el valor del campo marketplace?
@agustinzamar
marketplace_fee es la comisión que vas a cobrar

marketplace_fee
number
Tarifa de Marketplace cobrada por el propietario de la aplicación. Es una cantidad fija y su valor por defecto es 0 en moneda local. Esta propiedad solo se puede enviar si también se ha definido un marketplace válido; de lo contrario, la solicitud fallará.

Lo dice en el link que citas: https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post

@agustinzamar
Copy link

Buenas colegas, gracias por compartir esta información. Quería hacer una consulta, me encuentro trabajando con la API de checkout de MP y puedo configurar todas las opciones sin problema, salvo marketplace_fee. En la documentación oficial https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post dice que solo se puede enviar si esta configurado un marketplace valido (otra propiedades dentro de la preferencia).
Mi consulta seria si alguno sabe a que hace referencia el campo marketplace y donde se obtiene el string (campo alfanumérico) para indicarlo?
Desde ya muchas gracias por la ayuda.

Hola, como estas? Año 2023 y sigue sin decir nada la documentacion oficial. Pudiste resolver eso? De donde se obtiene el valor del campo marketplace?
@agustinzamar
marketplace_fee es la comisión que vas a cobrar

marketplace_fee
number
Tarifa de Marketplace cobrada por el propietario de la aplicación. Es una cantidad fija y su valor por defecto es 0 en moneda local. Esta propiedad solo se puede enviar si también se ha definido un marketplace válido; de lo contrario, la solicitud fallará.

Lo dice en el link que citas: https://www.mercadopago.com.co/developers/es/reference/preferences/_checkout_preferences/post

Exacto pero ese campo debe ir acompañado del otro que se llama solo 'marketplace' como muestra la documentacion, es necesario indicar un marketplace valido pero no explica de donde sale ese valor alfanumerico

image

@plencovich
Copy link
Author

@agustinzamar si, pero no hace falta poner nada; ya que si usas el access_token de la persona que queres cobrar en nombre de, va vacio.
cuando el vendedor conecta su cuenta de mercadopago a tu "tienda", vos obtenes la credencial del vendedor; y utilizas ese access_token a la hora de cobrar.

@MartinOliverio
Copy link

@apastrana-auntap @agustinzamar buenas, de casualidad buscando sobre otra duda que tengo sobre marketplace me encontré con esto, y es algo que también me trabó y que pude resolver a base de deducción porque la documentación no lo indica:

El marketplace está compuesto del String "MP-MKT-{$clientId}"

Por ejemplo si nuestro client Id es 6295877106812064, el marketplace será:

MP-MKT-6295877106812064

Espero les sirva, saludos!

@epontoni
Copy link

access_token

Es decir, uso el access_token entregado por el endpoint /oauth/token en

import { MercadoPagoConfig, Preference } from "mercadopago"; // SDK de Mercado Pago

const client = new MercadoPagoConfig({
accessToken: access_token,
})

y al crear la preferencia lleno los campos marketplace_fee y marketplace: "MP-MKT-{$clientId}"

@jsolanas7
Copy link

Como marketplace es crucial que el dinero quede 'bloqueado' hasta que el comprador confirme que recibio el producto/servicio. Se puede hacer esto con la API de mercado pago? Ya que si se le envia el dinero al vendedor al momento en que el usuario realiza la compra y luego no provee el servicio/envia el producto, no hay forma de devolverle el dinero (como marketplace) al comprador. Alguna idea? @epontoni @plencovich

@plencovich
Copy link
Author

@jsolanas7 si, si haces un refund, se devuevel el dinero saliendo de ambas cuentas.

@jsolanas7
Copy link

jsolanas7 commented Jun 11, 2024

Y que pasa si el vendedor retira el dinero, como se hace el reembolso en ese caso? No sabes si hay alguna forma de no permitir el retiro del dinero? @plencovich

@plencovich
Copy link
Author

@jsolanas7 el refund se hace igual, te quedará saldo negativo y MP cuando ingreses dinero te lo descuenta

@jsolanas7
Copy link

jsolanas7 commented Jun 14, 2024

@plencovich Pero la cuenta no es mia, es del vendedor. Puedo hacer eso con la cuenta del vendedor?
Ya que estamos te hago una pregunta, cree un usuario de prueba para el marketplace (le hice la aplicacion aqui) y otro de prueba que actua como vendedor. Estoy intentando darle acceso con oauth al markeplace desde la cuenta de test del vendedor pero cuando presiono el boton Authorizar me dice que me envio un email con un codigo de 6 digitos al mail del usuario de test (el cual yo no tengo acceso porq es de test). Ya probe con los 6 ultimos digitos del ID del usuario pero nada. ALguna idea?

@conrado-l
Copy link

@plencovich Pero la cuenta no es mia, es del vendedor. Puedo hacer eso con la cuenta del vendedor? Ya que estamos te hago una pregunta, cree un usuario de prueba para el marketplace (le hice la aplicacion aqui) y otro de prueba que actua como vendedor. Estoy intentando darle acceso con oauth al markeplace desde la cuenta de test del vendedor pero cuando presiono el boton Authorizar me dice que me envio un email con un codigo de 6 digitos al mail del usuario de test (el cual yo no tengo acceso porq es de test). Ya probe con los 6 ultimos digitos del ID del usuario pero nada. ALguna idea?

Según esto los valores de los 6 dígitos pueden ser estos:
"Como se trata de usuarios ficticios, no tendrás acceso a este e-mail que recibirá el código. En cambio, debes realizar esa validación introduciendo los últimos 6 dígitos que componen el User ID de la cuenta de prueba o los últimos 6 dígitos que componen su Access Token productivo."
https://www.mercadopago.com.ar/developers/es/docs/your-integrations/test/accounts

@conrado-l
Copy link

conrado-l commented Jul 27, 2024

Todavía no puedo hacer funcionar la integración de marketplace.

Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".

Alguien pudo hacer funcionar esto?

Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.

No tuve problema para generar el access token.

También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.

Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

@plencovich
Copy link
Author

@conrado-l

"Oh no, algo salió mal".

es debido a que estás logueado con la cuenta del MKT, no podés pagarte vos mismo. probalo en modo incognito o deslogueate de la cuenta de MP

@floresmatias0
Copy link

Todavía no puedo hacer funcionar la integración de marketplace.

Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".

Alguien pudo hacer funcionar esto?

Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.

No tuve problema para generar el access token.

También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.

Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Estoy en la misma que vos, pudiste solucionarlo?

@conrado-l
Copy link

Todavía no puedo hacer funcionar la integración de marketplace.
Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".
Alguien pudo hacer funcionar esto?
Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.
No tuve problema para generar el access token.
También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.
Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Estoy en la misma que vos, pudiste solucionarlo?

No, todavía no pude, estoy buscando ayuda.

Vos pudiste solucionarlo? estás usando Checkout API o Checkout Pro? y usas algún SDK?

Gracias!

@agustinzamar
Copy link

Todavía no puedo hacer funcionar la integración de marketplace.
Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".
Alguien pudo hacer funcionar esto?
Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.
No tuve problema para generar el access token.
También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.
Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Estoy en la misma que vos, pudiste solucionarlo?

No, todavía no pude, estoy buscando ayuda.

Vos pudiste solucionarlo? estás usando Checkout API o Checkout Pro? y usas algún SDK?

Gracias!

Mi integracion usando checkout pro:
Con una cuenta real de MP crear 3 cuentas de prueba. Con una de esas cuentas ingresar al panel de developer y crear una aplicación. Esa será la cuenta marketplace. Las otras 2 comprador y vendedor.

El campo marketplace debe tener el valor true booleano.

El campo MP-MKT-etc no se envia.

La public_key a utilizar debe ser la del marketplace (si estan usando el sdk de react esto se setea en el componente Payment)

El access token debe ser el del vendedor que debe haber sido obtenido previamente mediante la api de auth.

Cuando prueben la integración haganlo en un navegador sin sesiones de MP abiertas o ventana de incógnito ya que si tienen la sesion abierta con la cuenta Marketplace o vendedora van a recibir errores al momento de pagar.

@agustinzamar
Copy link

agustinzamar commented Aug 7, 2024

Todavía no puedo hacer funcionar la integración de marketplace.

Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".

Alguien pudo hacer funcionar esto?

Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.

No tuve problema para generar el access token.

También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.

Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Creo que aca el problema es que estas usando como marketplace una cuenta de produccion y como vendedor y comprador cuentas de prueba. Puede ser? La cuenta mktplace debe ser de prueba tambien

@conrado-l
Copy link

conrado-l commented Aug 8, 2024

Todavía no puedo hacer funcionar la integración de marketplace.
Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".
Alguien pudo hacer funcionar esto?
Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.
No tuve problema para generar el access token.
También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.
Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Estoy en la misma que vos, pudiste solucionarlo?

No, todavía no pude, estoy buscando ayuda.
Vos pudiste solucionarlo? estás usando Checkout API o Checkout Pro? y usas algún SDK?
Gracias!

Mi integracion usando checkout pro: Con una cuenta real de MP crear 3 cuentas de prueba. Con una de esas cuentas ingresar al panel de developer y crear una aplicación. Esa será la cuenta marketplace. Las otras 2 comprador y vendedor.

El campo marketplace debe tener el valor true booleano.

El campo MP-MKT-etc no se envia.

La public_key a utilizar debe ser la del marketplace (si estan usando el sdk de react esto se setea en el componente Payment)

El access token debe ser el del vendedor que debe haber sido obtenido previamente mediante la api de auth.

Cuando prueben la integración haganlo en un navegador sin sesiones de MP abiertas o ventana de incógnito ya que si tienen la sesion abierta con la cuenta Marketplace o vendedora van a recibir errores al momento de pagar.

Muchas gracias por la info Agustín.

Cuando uso las 3 cuentas de prueba, marketplace, comprador y vendedor, al momento de obtener el token de OAuth me dice:

"message":"the client_id does not match the original", "error":"invalid_grant"

y cuando uso las credenciales de producción para pedir el OAuth token sí anda, pero al momento de pagar, falla con "Oh no, algo anda mal" o similar.

No estoy usando el flujo PKCE y estoy usando el SDK de Javascript, no el de React especificamente.

Me pasarías un contacto? Ya estoy hace varias semanas con este problema y necesito integrarlo para sacar algo al público, te pago la consulta por supuesto, si estás dispuesto a ayudarme unos minutos.

Muchísimas gracias Agustín.

@agustinzamar
Copy link

Todavía no puedo hacer funcionar la integración de marketplace.
Ya intenté sin el campo "marketplace", con el campo "marketplace" usando mi client id, después usando "MP-MKT-miClientId" y cuando voy a pagar me dice "Oh no, algo salió mal".
Alguien pudo hacer funcionar esto?
Lo estoy probando todo con cuentas de prueba claro, y el clientId es el administrador de las cuentas de prueba, o sea el que las creó.
No tuve problema para generar el access token.
También probé utilizando el public_key del vendedor como "marketplace" pero tampco anduvo.
Muchas gracias y espero que mejoren la documentación de Mercado Pago algún día.

Estoy en la misma que vos, pudiste solucionarlo?

No, todavía no pude, estoy buscando ayuda.
Vos pudiste solucionarlo? estás usando Checkout API o Checkout Pro? y usas algún SDK?
Gracias!

Mi integracion usando checkout pro: Con una cuenta real de MP crear 3 cuentas de prueba. Con una de esas cuentas ingresar al panel de developer y crear una aplicación. Esa será la cuenta marketplace. Las otras 2 comprador y vendedor.
El campo marketplace debe tener el valor true booleano.
El campo MP-MKT-etc no se envia.
La public_key a utilizar debe ser la del marketplace (si estan usando el sdk de react esto se setea en el componente Payment)
El access token debe ser el del vendedor que debe haber sido obtenido previamente mediante la api de auth.
Cuando prueben la integración haganlo en un navegador sin sesiones de MP abiertas o ventana de incógnito ya que si tienen la sesion abierta con la cuenta Marketplace o vendedora van a recibir errores al momento de pagar.

Muchas gracias por la info Agustín.

Cuando uso las 3 cuentas de prueba, marketplace, comprador y vendedor, al momento de obtener el token de OAuth me dice:

"message":"the client_id does not match the original", "error":"invalid_grant"

y cuando uso las credenciales de producción para pedir el OAuth token sí anda, pero al momento de pagar, falla con "Oh no, algo anda mal" o similar.

No estoy usando el flujo PKCE y estoy usando el SDK de Javascript, no el de React especificamente.

Me pasarías un contacto? Ya estoy hace varias semanas con este problema y necesito integrarlo para sacar algo al público, te pago la consulta por supuesto, si estás dispuesto a ayudarme unos minutos.

Muchísimas gracias Agustín.

Al momento de pedir el token creo que tenes que setear "test_token": "true" en el request que envias a /oauth/token (Solo cuando estas usando las cuentas de prueba). Deberias tener ahi un condicional en base al .env ques setee eso en true para local/uat y false para produccion

No tengo mucha mas idea del tema la verdad. Tambien cuando lo integre tuve problemas por todos lados y me acuerdo alguna que otra cosa pero hasta ahi

@conrado-l
Copy link

conrado-l commented Aug 13, 2024

Par todos los que tienen problemas con esto, básicamente las cuentas de prueba no andan pero si conectan todo a la cuenta administradora y ponen cuentas reales como compradora y vendedora, así me funcionó a mí después de probar semanas con cuentas de prueba.

Prueben con transacciones reales pero de bajo monto, como 10$ por ejemplo.

Si ponen 1$ leí que pueden fallar.

Horrible como MercadoPago maneja esto.

@floresmatias0
Copy link

Muchachos, lo pude hacer andar, marketplace solo funciona en production, los pagos de prueba los hice con dos cuentas de prueba, el vendedor crea la preferencia y el comprador paga, el tema mas importante es que en mi caso le estaba pasando queries a la url de notificacion porque necesitaba esos datos, se ve que hay un limite de caracteres, entonces corregi la url de notificacion y solo pase algunos datos

Dejo el código:

const { MercadoPagoConfig, Preference } = require('mercadopago'); // --> PRUEBA NUEVO METODO

server.post('/create', async (req, res) => {
try {
const { unit_price, user_email, tutor_email, startDateTime, endDateTime, patient, symptoms } = req.body;
const doctor = await findUserByEmail(user_email);

    if(doctor) {
        const access_token = doctor?.mercadopago_access?.access_token

        const client = new MercadoPagoConfig({ accessToken: access_token }); //--> PRUEBA NUEVO METODO
        const preference = new Preference(client); // --> PRUEBA NUEVO METODO

        const idsSimptoms = symptoms?.map(symptom => symptom._id);

        const notificationData = { 
            d: user_email,
            u: tutor_email,
            sd: new Date(startDateTime).getTime(),
            ed: new Date(endDateTime).getTime(),
            p: patient,
            s: idsSimptoms
        };

        let commision = (unit_price * 10) / 100;

        const generateUniqueId = (length = 16) => {
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let result = '';
            const charactersLength = characters.length;
            for (let i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * charactersLength));
            }
            return result;
        }
        
        const uniqueId = generateUniqueId();

        const body = {
            items: [
              {
                  id: `Medic ${uniqueId}`,
                  title: 'Consulta medica',
                  description: "Reunion privada con un medico especializado",
                  category_id: "turns",
                  currency_id: "ARS",
                  quantity: 1,
                  unit_price
              },
            ],
            marketplace_fee: commision,
            back_urls: {
              success: `${process.env.FRONTEND_URL}/turnos?status=approved`,
              failure: `${process.env.FRONTEND_URL}/turnos?status=failure`,
              pending: `${process.env.FRONTEND_URL}/turnos?status=pending`,
            },
            expires: false,
            auto_return: 'all',
            binary_mode: true,
            marketplace: 'marketplace',
            notification_url: `${process.env.NOTIFICATION_URL}?d=${notificationData.d}&u=${notificationData.u}&sd=${notificationData.sd}&ed=${notificationData.ed}&p=${notificationData.p}&s=${notificationData.s}`,
            operation_type: 'regular_payment',
            statement_descriptor: 'Zona Pediatrica',
        };

        const data = await preference.create({ body }) // --> PRUEBA NUEVO METODO

        return res.status(200).json({
            success: true,
            data
        });
    }

    return res.status(401).json({
        success: false,
        error: "Usuario no encontrado"
    });
}catch(err) {
    console.log(err?.message)
    return res.status(500).json({
        success: false,
        error: err.message
    });
}

})

@jointothedarkside
Copy link

@floresmatias0 Buen día no encuentro mucha documentación sobre una operación que quiero hacer y tampoco encuentro gente experta que me sepa orientar a si se puede hacer este ejemplo, ojalá y tu puedas ayudarme con información:
Si una persona en el marketplace compra 3 productos de 3 vendedores diferentes, uno del vendedor A por $25, otro del vendedor b por $75 y otro al vendedor C por $100
Lo que quiero que suceda es que al cliente se le cobren $200 pero que el vendedor A reciba $25 en su cuenta de mercadopago, el vendedor b sus $75 y el C $100
Todos los ejemplos que veo son solo con un vendedor y me urge saber si es posible esa estructura de n vendedores para poder intentar desarrollarla para un sitio en magento2.
Saludos!

@conrado-l
Copy link

Muchachos, lo pude hacer andar, marketplace solo funciona en production, los pagos de prueba los hice con dos cuentas de prueba, el vendedor crea la preferencia y el comprador paga, el tema mas importante es que en mi caso le estaba pasando queries a la url de notificacion porque necesitaba esos datos, se ve que hay un limite de caracteres, entonces corregi la url de notificacion y solo pase algunos datos

Dejo el código:

const { MercadoPagoConfig, Preference } = require('mercadopago'); // --> PRUEBA NUEVO METODO

server.post('/create', async (req, res) => { try { const { unit_price, user_email, tutor_email, startDateTime, endDateTime, patient, symptoms } = req.body; const doctor = await findUserByEmail(user_email);

    if(doctor) {
        const access_token = doctor?.mercadopago_access?.access_token

        const client = new MercadoPagoConfig({ accessToken: access_token }); //--> PRUEBA NUEVO METODO
        const preference = new Preference(client); // --> PRUEBA NUEVO METODO

        const idsSimptoms = symptoms?.map(symptom => symptom._id);

        const notificationData = { 
            d: user_email,
            u: tutor_email,
            sd: new Date(startDateTime).getTime(),
            ed: new Date(endDateTime).getTime(),
            p: patient,
            s: idsSimptoms
        };

        let commision = (unit_price * 10) / 100;

        const generateUniqueId = (length = 16) => {
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let result = '';
            const charactersLength = characters.length;
            for (let i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * charactersLength));
            }
            return result;
        }
        
        const uniqueId = generateUniqueId();

        const body = {
            items: [
              {
                  id: `Medic ${uniqueId}`,
                  title: 'Consulta medica',
                  description: "Reunion privada con un medico especializado",
                  category_id: "turns",
                  currency_id: "ARS",
                  quantity: 1,
                  unit_price
              },
            ],
            marketplace_fee: commision,
            back_urls: {
              success: `${process.env.FRONTEND_URL}/turnos?status=approved`,
              failure: `${process.env.FRONTEND_URL}/turnos?status=failure`,
              pending: `${process.env.FRONTEND_URL}/turnos?status=pending`,
            },
            expires: false,
            auto_return: 'all',
            binary_mode: true,
            marketplace: 'marketplace',
            notification_url: `${process.env.NOTIFICATION_URL}?d=${notificationData.d}&u=${notificationData.u}&sd=${notificationData.sd}&ed=${notificationData.ed}&p=${notificationData.p}&s=${notificationData.s}`,
            operation_type: 'regular_payment',
            statement_descriptor: 'Zona Pediatrica',
        };

        const data = await preference.create({ body }) // --> PRUEBA NUEVO METODO

        return res.status(200).json({
            success: true,
            data
        });
    }

    return res.status(401).json({
        success: false,
        error: "Usuario no encontrado"
    });
}catch(err) {
    console.log(err?.message)
    return res.status(500).json({
        success: false,
        error: err.message
    });
}

})

Hola Matías, genial que lo hiciste andar. Lo hice andar justo ayer pero todo con plata real y cuentas reales, cómo hiciste para usar las cuentas de prueba?

Acá dejé documentado como traté de usarlo con cuentas de prueba: https://www.reddit.com/r/devsarg/comments/1equtk6/d%C3%ADas_intentando_integrar_mercadopago_marketplace/

Muchas gracias.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment