Pagos con CoDi®
El objetivo de esta guía es explicar paso a paso como generar referencias de pago con CoDi®.
CoDi® es una plataforma desarrollada por Banco de México para facilitar las transacciones de pago y cobro a través de transferencias electrónicas de forma rápida, segura y eficiente, a través de teléfonos móviles.
CoDi® usa la tecnología de los Códigos QR, son códigos de barras bidimensionales de uso libre, son fáciles de implementar y de leer por medio de cualquier dispositivo móvil y NFC que es una tecnología basada en la creación de un campo electromagnético en el que, mediante inducción, se genera un intercambio de información entre dispositivos (terminal y móvil). Esto con la finalidad de facilitar que tanto comercios como usuarios puedan realizar transacciones sin dinero en efectivo.
Para mas información consulta el sitio oficial CoDi®.
Cargos con QR
A continuación se presentará el flujo para la generación de cargos con código QR dinámico, el cual tiene un tiempo de vida de cinco minutos.
Pasos:
El comercio solicita la generación de un código QR para realizar el cargo.
Desde el API de Openpay se regresa el código QR al comercio para que éste pueda realizar el cargo.
El comercio expone el código QR por el medio de su elección (Impreso, Pantalla, etc.) para que su cliente pueda realizar el pago.
El cliente escanea el código QR desde la app móvil de su banco.
El cliente confirma el pago desde la app móvil de su banco.
El banco donde se encuentra la cuenta del cliente envía la notificación de pago a Banxico.
Banxico notifica a Openpay que el cargo se realizó correctamente.
Openpay confirma el cargo al comercio.
En esta guía veremos los pasos número 1 y 2.
Generar código QR (Paso 1 y 2)
Para generar un código QR es necesario crear un cargo indicando en el campo
method
el tipo codi
y la opcion codi_options
con el atributo mode
el valor QR_CODE
de la siguiente manera:
@openpay = OpenpayApi . new ( "mzdtln0bmtms6o3kck8f" , "sk_e568c42a6c384b7ab02cd47d2e407cab" )
@charges = @openpay . create ( :charges )
request_hash = {
"method" => "codi" ,
"amount" => 200 . 00 ,
"description" => "Cargo con código QR" ,
"order_id" => "codi-00051" ,
"due_date" => "2020-12-20T13:45:00" ,
"codi_options" => {
"mode" : "QR_CODE"
},
"customer" => {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210"
}
}
response_hash = @charges . create ( request_hash . to_hash )
<?php
$openpay = Openpay :: getInstance ( 'mzdtln0bmtms6o3kck8f' ,
'sk_e568c42a6c384b7ab02cd47d2e407cab' );
$chargeData = array (
'method' => 'codi' ,
'amount' => 200.00 ,
'description' => 'Cargo con código QR' ,
'order_id' => 'codi-00051' ,
'codi_options' => ''
'due_date' => '2020-12-20T13:45:00' ,
'codi_options' => {
'mode' : 'QR_CODE'
},
'customer' => {
'name' : 'Ricardo' ,
'last_name' : 'Martinez' ,
'email' : 'this.is.a@customer.test' ,
'phone_number' : '4421217210'
}
);
$charge = $openpay -> charges -> create ( $chargeData );
?>
OpenpayAPI api = new OpenpayAPI ( "https://sandbox-api.openpay.mx" ,
"sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
Charge charge = api . charges (). create ( new CreateBankChargeParams ()
. method ( "codi" )
. description ( "Cargo con código QR" )
. amount ( new BigDecimal ( "200.00" )) // Amount is in MXN
. orderId ( "codi-00051" )) // Optional transaction identifier
. dueDate ( "2020-12-20T13:45:00" )
. codiOptions (). mode ( "QR_CODE" )
. customer (). name ( "Ricardo" )
. customer (). lastName ( "Martinez" )
. customer (). email ( "this.is.a@customer.test" )
. customer (). phoneNumber ( "4421217210" );
OpenpayAPI api = new OpenpayAPI ( "sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
ChargeRequest request = new ChargeRequest ();
request . Method = "codi" ;
request . Amount = new Decimal ( 200.00 );
request . Description = "Cargo con código QR" ;
request . OrderId = "codi-00051" ;
request . DueDate = "" 2020 - 12 - 20 T13 : 45 : 00 "" ;
request . CodiOptions . Mode = "QR_CODE" ;
request . Customer . Name = "Ricardo" ;
request . Customer . LastName = "Martinez" ;
request . Customer . Email = "this.is.a@customer.test" ;
request . Customer . PhoneNumber = "4421217210" ;
Charge charge = api . ChargeService . Create ( request );
var openpay = new Openpay ( 'gdntnaxvkcdviesgaxem' , 'sk_b97e606487d34b44ab66e03d5bd14747' );
var bankChargeRequest = {
'method' : 'codi' ,
'amount' : 200 ,
'description' : 'Cargo con código QR' ,
'order_id' : 'codi-00051' ,
'due_date' : '2020-12-20T13:45:00' ,
'codi_options' : {
'mode' : "QR_CODE"
},
'customer' => {
'name' : "Ricardo" ,
'last_name' : "Martinez" ,
'email' : "this.is.a@customer.test" ,
'phone_number' : "4421217210"
}
};
openpay . customers . charges . create ( customerId , bankChargeRequest , function ( error , charge ) {
// ...
});
import openpay
openpay . api_key = "sk_e568c42a6c384b7ab02cd47d2e407cab"
openpay . merchant_id = "mzdtln0bmtms6o3kck8f"
charge = openpay . Charge . create (
method = "codi" ,
amount = 200.00 ,
description = "Cargo con código QR" ,
order_id = "codi-00051" ,
due_date = "2020-12-20T13:45:00" ,
codi_options = {
"mode" : "QR_CODE"
},
customer = {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210"
}
);
Al momento de crearse el cargo se regresará un objeto json.
Respuesta:
{
"id" : "tr47lahm4etz1rqz1nbs" ,
"authorization" : null ,
"operation_type" : "in" ,
"transaction_type" : "charge" ,
"status" : "charge_pending" ,
"conciliated" : false ,
"creation_date" : "2020-07-15T16:58:16-05:00" ,
"operation_date" : "2020-07-15T16:58:16-05:00" ,
"description" : "PUSH_NOTIFICATION" ,
"error_message" : null ,
"order_id" : "codi-929678" ,
"due_date" : "2020-07-20T13:45:00-05:00" ,
"amount" : 76.99 ,
"customer" : {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210" ,
"address" : null ,
"creation_date" : "2020-07-15T16:58:15-05:00" ,
"external_id" : null ,
"clabe" : null
},
"payment_method" : {
"type" : "codi" ,
"barcode_url" : "https://dev-api.openpay.mx/codi-qrcode/tr47lahm4etz1rqz1nbs" ,
"barcode_base64" : "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" ,
"mode" : "qr_code"
},
"currency" : "MXN" ,
"method" : "codi"
}
Con este código QR, tu cliente puede efectuar el pago escaneándolo desde la app movil de su banco.
Cargos con QR estático
A continuación se presentará el flujo para la generación de cargos con código QR estático el cual tiene un tiempo de vida mas largo que el dinámico.
Pasos:
El comercio solicita la generación de un código QR estático para realizar el cargo.
Desde el API de Openpay se envía el código QR al comercio para que éste pueda realizar el cargo, este código tiene vigencia de un mes.
El comercio expone el código QR por el medio de su elección (Impreso, Pantalla, etc.) para que su cliente pueda realizar el pago.
El cliente escanea el código QR desde la app móvil de su banco.
El cliente confirma el pago desde la app móvil de su banco.
El banco donde se encuentra la cuenta del cliente envía la notificación de pago a Banxico
Banxico notifica a Openpay que el cargo se realizó correctamente.
Openpay confirma el cargo al comercio.
En esta guía veremos los pasos número 1 y 2.
Generar código QR estático (Paso 1 y 2)
Para generar un código QR es necesario crear un cargo indicando los datos del producto de la siguiente manera:
@openpay = OpenpayApi . new ( "mzdtln0bmtms6o3kck8f" , "sk_e568c42a6c384b7ab02cd47d2e407cab" )
@charges = @openpay . create ( :charges )
request_hash = {
"amount" => 200 . 00 ,
"description" => "Cargo con código QR Estático" ,
"external_id" => "codi-00051" ,
"due_date" => "2020-07-20T13:45:00"
}
response_hash = @charges . create ( request_hash . to_hash )
<?php
$openpay = Openpay :: getInstance ( 'mzdtln0bmtms6o3kck8f' ,
'sk_e568c42a6c384b7ab02cd47d2e407cab' );
$chargeData = array (
'amount' => 200.00 ,
'description' => 'Cargo con código QR Estático' ,
'external_id' => 'codi-00051' ,
'due_date' => '2020-07-20T13:45:00'
);
$charge = $openpay -> charges -> create ( $chargeData );
?>
OpenpayAPI api = new OpenpayAPI ( "https://sandbox-api.openpay.mx" ,
"sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
Charge charge = api . charges (). create ( new CreateBankChargeParams ()
. description ( "Cargo con código QR Estático" )
. amount ( new BigDecimal ( "200.00" )) // Amount is in MXN
. externalId ( "codi-00051" )) // Optional transaction identifier
. dueDate ( "2020-07-20T13:45:00" );
}
OpenpayAPI api = new OpenpayAPI ( "sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
ChargeRequest request = new ChargeRequest ();
request . Amount = new Decimal ( 200.00 );
request . Description = "Cargo con código QR Estático" ;
request . ExternalId = "codi-00051" ;
request . DueDate = "2020-07-20T13:45:00" ;
Charge charge = api . ChargeService . Create ( request );
var openpay = new Openpay ( 'gdntnaxvkcdviesgaxem' , 'sk_b97e606487d34b44ab66e03d5bd14747' );
var bankChargeRequest = {
'amount' : 200 ,
'description' : 'Cargo con código QR Estático' ,
'external_id' : 'codi-00051' ,
'due_date' : '2020-07-20T13:45:00'
};
openpay . customers . charges . create ( customerId , bankChargeRequest , function ( error , charge ) {
// ...
});
import openpay
openpay . api_key = "sk_e568c42a6c384b7ab02cd47d2e407cab"
openpay . merchant_id = "mzdtln0bmtms6o3kck8f"
charge = openpay . Charge . create (
amount = 200.00 ,
description = "Cargo con código QR Estático" ,
external_id = "codi-00051" ,
due_date = "2020-07-20T13:45:00"
);
Al momento de crearse el cargo se regresará una objeto json.
Respuesta:
{
"id" : 54 ,
"amount" : 6999.99 ,
"due_date" : "2020-07-20T13:45:00-05:00" ,
"description" : "Product X99" ,
"external_id" : "Store-1003" ,
"metadata" : "{"param1":"val1","param2":"val2"}" ,
"barcode" : null ,
"barcode_url" : "https://dev-api.openpay.mx/codi/open_codes/54/qr_code" ,
"barcode_base64" : "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"
}
Con este código QR, tu cliente puede efectuar el pago escaneándolo desde la app móvil de su banco.
Notificación de pago
A continuación se presentará el flujo para la generación de cargos por notificación de pago.
Pasos:
El usuario solicita al comercio que realice la solicitud de pago.
El comercio solicita a Openpay que realice la solicitud de pago a Banxico.
Banxico realiza la solicitud de pago al banco correspondiente .
El banco al que pertenece la cuenta del usuario realiza la solicitud de pago al cliente y solicita la confirmación.
El cliente autoriza o declina el cargo que le solicita el banco.
En esta guía veremos los pasos número 1 y 2.
Envío de Notificación de Pago (Paso 1 y 2)
Para realizar un cobro por notificación de pago es necesario crear un cargo indicando en el campo method
el tipo codi
y la opción codi_options
con los siguientes atributos mode
el valor PUSH_NOTIFICATION
, use_customer_phone
el valor false
, phone_number
el número telefónico de cliente, de la siguiente manera:
@openpay = OpenpayApi . new ( "mzdtln0bmtms6o3kck8f" , "sk_e568c42a6c384b7ab02cd47d2e407cab" )
@charges = @openpay . create ( :charges )
request_hash = {
"method" => "codi" ,
"amount" => 200 . 00 ,
"description" => "Cargo por Notificación de Pago" ,
"order_id" => "codi-00051" ,
"due_date" => "2020-12-20T13:45:00" ,
"codi_options" => {
"mode" : "PUSH_NOTIFICATION" ,
"use_customer_phone" : false ,
"phone_number" : "4421217210"
},
"customer" => {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210"
}
}
response_hash = @charges . create ( request_hash . to_hash )
<?php
$openpay = Openpay :: getInstance ( 'mzdtln0bmtms6o3kck8f' ,
'sk_e568c42a6c384b7ab02cd47d2e407cab' );
$chargeData = array (
'method' => 'codi' ,
'amount' => 200.00 ,
'description' => 'Cargo por Notificación de Pago' ,
'order_id' => 'codi-00051' ,
'codi_options' => ''
'due_date' => '2020-12-20T13:45:00' ,
'codi_options' => {
'mode' : 'PUSH_NOTIFICATION' ,
'use_customer_phone' : false ,
'phone_number' : '4421217210'
},
'customer' => {
'name' : 'Ricardo' ,
'last_name' : 'Martinez' ,
'email' : 'this.is.a@customer.test' ,
'phone_number' : '4421217210'
}
);
$charge = $openpay -> charges -> create ( $chargeData );
?>
OpenpayAPI api = new OpenpayAPI ( "https://sandbox-api.openpay.mx" ,
"sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
Charge charge = api . charges (). create ( new CreateBankChargeParams ()
. method ( "codi" );
. description ( "Cargo por Notificación de Pago" )
. amount ( new BigDecimal ( "200.00" )) // Amount is in MXN
. orderId ( "codi-00051" )) // Optional transaction identifier
. dueDate ( "2020-12-20T13:45:00" )
. codiOptions (). mode ( "PUSH_NOTIFICATION" )
. codiOptions (). useCustomerPhone ( false )
. codiOptions (). phoneNumber ( 4421217210 )
. customer (). name ( "Ricardo" )
. customer (). lastName ( "Martinez" )
. customer (). email ( "this.is.a@customer.test" )
. customer (). phoneNumber ( "4421217210" );
OpenpayAPI api = new OpenpayAPI ( "sk_e568c42a6c384b7ab02cd47d2e407cab" , "mzdtln0bmtms6o3kck8f" );
ChargeRequest request = new ChargeRequest ();
request . Method = "codi" ;
request . Amount = new Decimal ( 200.00 );
request . Description = "Cargo por Notificación de Pago" ;
request . OrderId = "codi-00051" ;
request . DueDate = "" 2020 - 12 - 20 T13 : 45 : 00 "" ;
request . CodiOptions . Mode = "PUSH_NOTIFICATION" ;
request . CodiOptions . UseCustomerPhone ( false );
request . CodiOptions . PhoneNumber ( 4421217210 );
request . Customer . Name = "Ricardo" ;
request . Customer . LastName = "Martinez" ;
request . Customer . Email = "this.is.a@customer.test" ;
request . Customer . PhoneNumber = "4421217210" ;
Charge charge = api . ChargeService . Create ( request );
var openpay = new Openpay ( 'gdntnaxvkcdviesgaxem' , 'sk_b97e606487d34b44ab66e03d5bd14747' );
var bankChargeRequest = {
'method' : 'codi' ,
'amount' : 200 ,
'description' : 'Cargo por Notificación de Pago' ,
'order_id' : 'codi-00051' ,
'due_date' : '2020-12-20T13:45:00' ,
'codi_options' : {
'mode' : "QR_CODE"
},
'customer' => {
'name' : "Ricardo" ,
'last_name' : "Martinez" ,
'email' : "this.is.a@customer.test" ,
'phone_number' : "4421217210"
}
};
openpay . customers . charges . create ( customerId , bankChargeRequest , function ( error , charge ) {
// ...
});
import openpay
openpay . api_key = "sk_e568c42a6c384b7ab02cd47d2e407cab"
openpay . merchant_id = "mzdtln0bmtms6o3kck8f"
charge = openpay . Charge . create (
method = "codi" ,
amount = 200.00 ,
description = "Cargo por Notificación de Pago" ,
order_id = "codi-00051" ,
due_date = "2020-12-20T13:45:00" ,
codi_options = {
"mode" : "PUSH_NOTIFICATION" ,
"use_customer_phone" : false ,
"phone_number" : "4421217210"
},
customer = {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210"
}
);
Al momento de crearse el cargo se regresará un objeto json.
Respuesta:
{
"id" : "trs1clzwqweqwznutfmt" ,
"authorization" : null ,
"operation_type" : "in" ,
"transaction_type" : "charge" ,
"status" : "charge_pending" ,
"conciliated" : false ,
"creation_date" : "2020-07-15T16:58:33-05:00" ,
"operation_date" : "2020-07-15T16:58:33-05:00" ,
"description" : "PUSH_NOTIFICATION" ,
"error_message" : null ,
"order_id" : "codi-121795" ,
"due_date" : "2020-07-20T13:45:00-05:00" ,
"amount" : 76.99 ,
"customer" : {
"name" : "Ricardo" ,
"last_name" : "Martinez" ,
"email" : "this.is.a@customer.test" ,
"phone_number" : "4421217210" ,
"address" : null ,
"creation_date" : "2020-07-15T16:58:33-05:00" ,
"external_id" : null ,
"clabe" : null
},
"payment_method" : {
"type" : "codi" ,
"mode" : "push_notification" ,
"phone_number" : "4421217210"
},
"currency" : "MXN" ,
"method" : "codi"
}
Con esta notificación de pago, tu cliente puede efectuar el pago desde la app móvil de su banco.