Pagos en Banorte

En este tutorial aprenderás a generar y recibir pagos seguros por medio de Banorte.

Tutorial para sobre

1 Entendiendo el flujo

Para empezar a recibir pagos banorte, primero deberás crear un cargo en Conekta con datos como el importe, el tipo de moneda y la descripción. En la respuesta recibirás una referencia única del pago, número y nombre del servicio. Tendrás que enviar esta información a tu cliente para que pueda completar la compra.

Debido a que el usuario tiene que realizar el pago fuera de tu tienda, el proceso de pago es asíncrono y el cargo no tendrá inmediatamente el estatus de pagado. Para lidiar con el flujo asíncrono, necesitarás implementar un receptor de notificaciones (Webhook) para recibir notificaciones de pago.


2 Realizar Cargo

El primer paso es incluir una de nuestras librerías en tu proyecto. Una vez instalada la librería de tu preferencia necesitarás utilizar tu key privada, de esta manera podrás autenticar todas las llamadas que realices.

Recuerda que solamente las llaves de producción pueden procesar pagos reales. Las llaves sandbox están diseñadas para realizar pruebas solamente. También, toma en cuenta que las llamadas del lado del servidor deberán utilizar las llaves privadas ya que, por cuestiones de seguridad, las llaves públicas tienen permisos limitados.

#N/A: curl -u {global_api_key}: \
require "conekta"
Conekta.api_key = "{global_api_key}"
require_once("/path/to/lib/Conekta.php");
\Conekta\Conekta::setApiKey("{global_api_key}");
import conekta
conekta.api_key = "{global_api_key}"
var conekta = require('conekta');
conekta.api_key = "{global_api_key}";
import com.conekta;
Conekta.setApiKey("{global_api_key}");
using conekta;
conekta.Api.apiKey = "{global_api_key}"; 

Necesitarás hacer una petición a Conekta con el importe, el tipo de moneda y la descripción de la compra. También necesitarás especificar el tipo de cargo que estás realizando (en este caso bank) y especificar el tipo de pago en efectivo (con el sub parámetro type). Podrás enviar opcionalmente una referencia que ayuda a relacionar el cargo con tus propias órdenes, y una fecha de expiración dentro del objeto de pago para prevenir que los usuarios paguen después de cierta fecha.

JSONObject payment_params;

payment_params = new JSONObject("{"
  + "'description':'Stogies',"
  + "'amount': 20000,"
  + "'currency':'MXN',"
  + "'reference_id':'9839-wolf_pack',"
  + "'bank':{'type':'banorte', 'expires_at': {global_expiration_date_timestamp}},"
  + "'details': {"
    + "'name': 'Arnulfo Quimare',"
    + "'phone': '403-342-0642',"
    + "'email': 'logan@x-men.org',"
    + "'customer': {"
      + "'logged_in': true,"
      + "'successful_purchases': 14,"
      + "'created_at': 1379784950,"
      + "'updated_at': 1379784950,"
      + "'offline_payments': 4,"
      + "'score': 9"
    + "},"
    + "'line_items': [{"
      + "'name': 'Box of Cohiba S1s',"
      + "'description': 'Imported From Mex.',"
      + "'unit_price': 20000,"
      + "'quantity': 1,"
      + "'sku': 'cohb_s1',"
      + "'category': 'food'"
    + "}],"
    + "'billing_address': {"
      + "'street1':'77 Mystery Lane',"
      + "'street2': 'Suite 124',"
      + "'street3': null,"
      + "'city': 'Darlington',"
      + "'state':'NJ',"
      + "'zip': '10192',"
      + "'country': 'Mexico',"
      + "'tax_id': 'xmn671212drx',"
      + "'company_name':'X-Men Inc.',"
      + "'phone': '77-777-7777',"
      + "'email': 'purshasing@x-men.org'"
    + "}"
  + "}"
+ "}");

Charge conektaCharge = Charge.create(payment_params);
conekta.Charge.create({
  "description":"Stogies",
  "amount": 20000,
  "currency":"MXN",
  "reference_id":"9839-wolf_pack",
  "bank": {
    "type": "banorte",
    "expires_at": {global_expiration_date_timestamp}
  },
  "details": {
    "name": "Arnulfo Quimare",
    "phone": "403-342-0642",
    "email": "logan@x-men.org",
    "customer": {
      "logged_in": true,
      "successful_purchases": 14,
      "created_at": 1379784950,
      "updated_at": 1379784950,
      "offline_payments": 4,
      "score": 9
    },
    "line_items": [{
      "name": "Box of Cohiba S1s",
      "description": "Imported From Mex.",
      "unit_price": 20000,
      "quantity": 1,
      "sku": "cohb_s1",
      "category": "food"
    }],
    "billing_address": {
      "street1":"77 Mystery Lane",
      "street2": "Suite 124",
      "street3": null,
      "city": "Darlington",
      "state":"NJ",
      "zip": "10192",
      "country": "Mexico",
      "tax_id": "xmn671212drx",
      "company_name":"X-Men Inc.",
      "phone": "77-777-7777",
      "email": "purshasing@x-men.org"
    }
  }
}, function(err, res) {
    console.log(res.toObject());
});
charge = conekta.Charge.create({
  "description":"Stogies",
  "amount": 20000,
  "currency":"MXN",
  "reference_id":"9839-wolf_pack",
  "bank": {
    "type": "banorte",
    "expires_at": {global_expiration_date_timestamp}
  },
  "details": {
    "name": "Arnulfo Quimare",
    "phone": "403-342-0642",
    "email": "logan@x-men.org",
    "customer": {
      "logged_in": true,
      "successful_purchases": 14,
      "created_at": 1379784950,
      "updated_at": 1379784950,
      "offline_payments": 4,
      "score": 9
    },
    "line_items": [{
      "name": "Box of Cohiba S1s",
      "description": "Imported From Mex.",
      "unit_price": 20000,
      "quantity": 1,
      "sku": "cohb_s1",
      "category": "food"
    }],
    "billing_address": {
      "street1":"77 Mystery Lane",
      "street2": "Suite 124",
      "street3": null,
      "city": "Darlington",
      "state":"NJ",
      "zip": "10192",
      "country": "Mexico",
      "tax_id": "xmn671212drx",
      "company_name":"X-Men Inc.",
      "phone": "77-777-7777",
      "email": "purshasing@x-men.org"
    }
  }
})
$charge = Conekta_Charge::create(array(
  'description'=> 'Stogies',
  'reference_id'=> '9839-wolf_pack',
  'amount'=> 20000,
  'currency'=>'MXN',
  ‘bank’=> array(
    'type'=> ‘banorte’,
    'expires_at'=> {global_expiration_date_timestamp}
  ),
  'details'=> array(
    'name'=> 'Arnulfo Quimare',
    'phone'=> '403-342-0642',
    'email'=> 'logan@x-men.org',
    'customer'=> array(
      'corporation_name'=> 'Conekta Inc.',
      'logged_in'=> true,
      'successful_purchases'=> 14,
      'created_at'=> 1379784950,
      'updated_at'=> 1379784950,
      'offline_payments'=> 4,
      'score'=> 9
    ),
    'line_items'=> array(
      array(
        'name'=> 'Box of Cohiba S1s',
        'description'=> 'Imported From Mex.',
        'unit_price'=> 20000,
        'quantity'=> 1,
        'sku'=> 'cohb_s1',
        'type'=> 'food'
      )
    ),
    'billing_address'=> array(
      'street1'=>'77 Mystery Lane',
      'street2'=> 'Suite 124',
      'street3'=> null,
      'city'=> 'Darlington',
      'state'=>'NJ',
      'zip'=> '10192',
      'country'=> 'Mexico',
      'phone'=> '77-777-7777',
      'email'=> 'purshasing@x-men.org'
    )
  )
));
curl -H "Accept: application/vnd.conekta-v1.0.0+json" \
     -H "Content-type: application/json" \
     -u {global_api_key}: \
     -X POST -d '{
      "description":"Stogies",
      "amount": 20000,
      "currency":"MXN",
      "reference_id":"9839-wolf_pack",
      "bank": {
        "type":"banorte",
        "expires_at": {global_expiration_date_timestamp}
      },
      "details": {
        "name": "Arnulfo Quimare",
        "phone": "403-342-0642",
        "email": "logan@x-men.org",
        "customer": {
          "logged_in": true,
          "successful_purchases": 14,
          "created_at": 1379784950,
          "updated_at": 1379784950,
          "offline_payments": 4,
          "score": 9
        },
        "line_items": [{
          "name": "Box of Cohiba S1s",
          "description": "Imported From Mex.",
          "unit_price": 20000,
          "quantity": 1,
          "sku": "cohb_s1",
          "category": "food"
        }],
        "billing_address": {
          "street1":"77 Mystery Lane",
          "street2": "Suite 124",
          "street3": null,
          "city": "Darlington",
          "state":"NJ",
          "zip": "10192",
          "country": "Mexico",
          "tax_id": "xmn671212drx",
          "company_name":"X-Men Inc.",
          "phone": "77-777-7777",
          "email": "purshasing@x-men.org"
        }
      }
    }' https://api.conekta.io/charges
begin
  charge = Conekta::Charge.create({
    "description"=> "Stogies",
    "amount"=> 20000,
    "currency"=> "MXN",
    "reference_id"=> "9839-wolf_pack",
    "bank"=> {
      "type"=> "banorte",
      "expires_at"=> {global_expiration_date_timestamp}
    },
    "details"=> {
      "name"=> "Arnulfo Quimare",
      "phone"=> "403-342-0642",
      "email"=> "logan@x-men.org",
      "customer"=> {
        "logged_in"=> true,
        "successful_purchases"=> 14,
        "created_at"=> 1379784950,
        "updated_at"=> 1379784950,
        "offline_payments"=> 4,
        "score"=> 9
      },
      "line_items"=> [{
        "name"=> "Box of Cohiba S1s",
        "description"=> "Imported From Mex.",
        "unit_price"=> 20000,
        "quantity"=> 1,
        "sku"=> "cohb_s1",
        "category"=> "food"
      }],
      "billing_address"=> {
        "street1"=>"77 Mystery Lane",
        "street2"=> "Suite 124",
        "city"=> "Darlington",
        "state"=>"NJ",
        "zip"=> "10192",
        "country"=> "Mexico",
        "tax_id"=> "xmn671212drx",
        "company_name"=>"X-Men Inc.",
        "phone"=> "77-777-7777",
        "email"=> "purshasing@x-men.org"
      }
    }
  })
rescue Conekta::ParameterValidationError => e
  puts e.message_to_purchaser 
  #alguno de los parámetros fueron inválidos

rescue Conekta::ProcessingError => e
  puts e.message_to_purchaser 
  #la tarjeta no pudo ser procesada

rescue Conekta::Error => e
  puts e.message_to_purchaser 
  #un error ocurrió que no sucede en el flujo normal de cobros como por ejemplo un auth_key incorrecto

end
conekta.Charge charge = new conekta.Charge ().create(@"{
  ""description"":""Stogies"",
  ""amount"": 20000,
  ""currency"":""MXN"",
  ""reference_id"":""9839-wolf_pack"",
  ""bank"": {
    ""type"": ""banorte"",
    ""expires_at"": 1461823641
  },
  ""details"": {
    ""name"": ""Arnulfo Quimare"",
    ""phone"": ""403-342-0642"",
    ""email"": ""logan@x-men.org"",
    ""customer"": {
      ""logged_in"": true,
      ""successful_purchases"": 14,
      ""created_at"": 1379784950,
      ""updated_at"": 1379784950,
      ""offline_payments"": 4,
      ""score"": 9
    },
    ""line_items"": [{
      ""name"": ""Box of Cohiba S1s"",
      ""description"": ""Imported From Mex."",
      ""unit_price"": 20000,
      ""quantity"": 1,
      ""sku"": ""cohb_s1"",
      ""category"": ""food""
    }],
    ""billing_address"": {
      ""street1"":""77 Mystery Lane"",
      ""street2"": ""Suite 124"",
      ""street3"": null,
      ""city"": ""Darlington"",
      ""state"":""NJ"",
      ""zip"": ""10192"",
      ""country"": ""Mexico"",
      ""tax_id"": ""xmn671212drx"",
      ""company_name"":""X-Men Inc."",
      ""phone"": ""77-777-7777"",
      ""email"": ""purshasing@x-men.org""
    }
  }
}");

3 Procesar la respuesta

Al haber creado el cargo, deberás de procesar la respuesta y enviar la referencia del pago a tu cliente.

# N/A
charge.payment_method.service_name
charge.payment_method.service_number
charge.payment_method.reference
charge.payment_method.type
echo $charge->payment_method->service_name;
echo $charge->payment_method->service_number;
echo $charge->payment_method->reference;
echo $charge->payment_method->type;
print charge.payment_method.service_name
print charge.payment_method.service_number
print charge.payment_method.reference
print charge.payment_method.type
console.log(charge.toObject().payment_method.service_name);
console.log(charge.toObject().payment_method.service_number);
console.log(charge.toObject().payment_method.reference);
console.log(charge.toObject().payment_method.type);
System.out.println(conektaCharge.payment_method.service_name);
System.out.println(conektaCharge.payment_method.service_number);
System.out.println(conektaCharge.payment_method.reference);
System.out.println(conektaCharge.payment_method.type);
Console.WriteLine(conektaCharge.payment_method.service_name);
Console.WriteLine(conektaCharge.payment_method.service_number);
Console.WriteLine(conektaCharge.payment_method.reference);
Console.WriteLine(conektaCharge.payment_method.type);

4 Recibir la notificación

Al momento de procesar pagos de manera asíncrona, necesitarás recibir notificaciones para confirmar que los cargos realizados han sido pagados. Conekta enviará webhooks de todas las notificaciones de pagos asíncronas a tu servidor. Estas notificaciones son mensajes POST de tipo HTTP jSON. Cada notificación contiene un objeto jSON con información particular del evento y suscripción asociada.

Al configurar notificaciones de pago, necesitarás configurar los webhooks dentro de la sección de webhooks del admin. La configuración es simple. Todo lo que necesitas hacer es especificar el URL (o los URL) a donde te gustaría recibir notificaciones y Conekta enviará todas las notificaciones al (los) URL especificado(s).

Para operar las notificaciones en tu servidor, deberás configurar una ruta para el webhook que creaste, escribir código para analizar el mensaje POST y operar sobre él. Para más información sobre webhooks, ve a la sección de webhooks.

Ten en cuenta que el URL usado en la configuración de webhook debe poder ser accedido de manera pública. Si no tienes un IP público o un domino a tu disposición, sugerimos usar un servicio local->público como ultrahook o localtunnel. Abajo te compartimos un ejemplo de cómo usar ultrahook. Antes de utilizar ultrahook deberás registrarte en ultrahook para obtener una llave de API.

$ gem install ultrahook
$ echo "api_key: my-ultrahook-api-hey" > ~/.ultrahook
$ ultrahook webhook-test 5000

  Authenticated as conekta
  Forwarding activated...
  http://webhook-test.conekta.ultrahook.com -> http://localhost:5000

Para recibir notificaciones de webhooks, puedes usar el siguiente código:

# N/A
require 'json'

#example in sinatra
post '/my/webhook/url' do

  #Analizar la información del evento en forma de json
  event_json = JSON.parse(request.body.read)

  case event_json['type']
  when 'charge.paid'
    
  #Hacer algo con la información como actualizar los atributos de la orden en tu base de datos
      
  #charge = Charge.find(event_json['object']['id'])

  end
end
// Analizar la información del evento en forma de json
$body = @file_get_contents('php://input');
$event_json = json_decode($body);
http_response_code(200); // Return 200 OK

if ($event_json->type == 'charge.paid'){
 
 //Hacer algo con la información como actualizar los atributos de la orden en tu base de datos
 
 //charge = $this->Charge->find('first', array(
 
 //  'conditions' => array('Charge.id' => $event_json->object->id)
 
 //))
}
import json

# Analizar la información del evento en forma de json en Django
event_json = json.loads(HttpRequest.body)

if event_json.type == 'charge.paid':
  
#Hacer algo con la información como actualizar los atributos de la orden en tu base de datos
  
#charge = EcommerceCharge.objects.get(pk=event_json['object']['id'])
// Analizar la información del evento en forma de json en javascript
event_json = typeof req.body == 'string' ? JSON.parse(req.body) : req.body;

if (event_json.type == 'charge.paid') {
   //Hacer algo con la información como actualizar los atributos de la orden en tu base de datos
}
import org.json.JSONObject;
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
      BufferedReader get_body = request.getReader();
     
      //Parsear JSON y manejar respuesta
    }
// Analizar la información del evento en forma de json
var event = JObject.Parse('req.body');

if (event['type'] == 'charge.paid') {
   //Hacer algo con la información como actualizar los atributos de la orden en tu base de datos
}

Además de recibir notificaciones de charge.paid, también recibirás otra información útil como charge.created. Puedes ver una lista completa de eventos en la la referencia de eventos. Revisa la sección de webhooks para más información.