Introducción


La gema de ComproPago Ruby SDK le permite interactuar con el API de ComproPago en su aplicación. También cuenta con los métodos necesarios para facilitar el desarrollo por medio de los servicios más utilizados (SDK). Con ComproPago puede recibir pagos en 7Eleven, Extra y más tiendas en todo México.

Requerimientos


  • Ruby >= 1.9
  • json
  • net/http

Instalación


Instalación por Github

Puedes descargar alguna de las versiones publicadas u obtener el repositorio directamente:

git clone https://github.com/compropago/compropago-ruby.git

Finalizada la descarga del código de la gema descomprime el archivo descargado e ingresa en la carpeta resultante. En una terminal con el siguiente comando:
./build_gem

Instalación por Ruby Gems

Puede instalar localmente la gema con el siguiente comando:

gem install compropago_sdk

O puede incluirlo como dependencia dentro de su Gemfile de proyecto de la siguiente forma:
gem 'compropago_sdk'

Configuración


Importación

Para hacer uso de la librería es necesario incluir el archivo principal de la gema de la siguiente forma:

require 'compropago_sdk'
Este archivo generará automáticamente las importaciones de las clases necesarias para el desarrollo con la Gema.

Configurar el cliente

Para poder hacer uso del paquete y llamados al API es necesario que primero configures tus Llaves de conexión y crees un instancia de Client. Tus llaves las encontrarás en el Panel de ComproPago en el menú Configuración.

# @param string publickey     Llave pública correspondiente al modo de la tienda
# @param string privatekey    Llave privada correspondiente al modo de la tienda
# @param bool   live          Modo de la tienda (false = Test | true = Live)

client = Client.new(
    'pk_test_xxxxxxxxxxxxxxxxx',  # publickey
    'sk_test_xxxxxxxxxxxxxxxxx',  # privatekey
    false,                        # live
)

Métodos


listProviders

La función list_providers le proporciona un listado con los puntos de cobro disponibles para su tienda con parámetros para su fácil filtrado, la cual regresa un arreglo de objetos de tipo Provider con los cuales puede acceder a sus atributos.

Prototipo
# @param [float]  limit    Límite de transacción que deberán tener los proveedores
# @param [string] currency Divisa del monto en el parámetro limit
# @return [array]
def list_providers(limit = 0, currency = 'MXN')
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
limit float 0 Límite mínimo que deben de soportar los proveedores listados
currency string MXN Divisa en la cual se procesa el campo limit, para poder ocupar este campo es necesario que el campo auth este configurado como true o en su caso siempre se tomará el valor por defecto. Los valores soportados son: Pesos mexicanos (MXN), Dólar americano(USD), Euro(EUR), Libra Esterlina(GBP).
Ejemplo
providers = client.api.list_providers

providers.each do |provider|
    puts provider.name
end

# 7Eleven
# Coppel
# ...

placeOrder

Este método le permite registrar ordenes en las cuales sus clientes podrán pagar posteriormente. El método recibe como parámetro un objeto de tipo PlaceOrderInfo y como resultado genera un objeto de tipo NewOrderInfo la cual contendra la información resultante de la generacón de la orden.

Prototipo
# @param [PlaceOrderInfo] info
# @return [NewOrderInfo]
def place_order(info)
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
info PlaceOrderInfo Objeto con la información de la orden generado mediente la clase Factory
Ejemplo
# Se genera el objeto con la información de la orden
# @param string order_id       Id de la orden.
# @param string order_name     Nombre del producto o productos de la orden.
# @param double order_price    Monto total de la orden.
# @param string customer_name  Nombre completo del cliente.
# @param string customer_email Correo electrónico del cliente.
# @param string payment_type   Valor del atributo internal_name' de un objeto 'Provider'.
# @param string currency       Código de la moneda con la que se está creando el cargo.
order_info = [
    :order_id => 12,
    :order_name => 'M4 php sdk',
    :order_price => 123.45,
    :customer_name => 'Eduardo',
    :customer_email => '[email protected]',
    :payment_type => 'SEVEN_ELEVEN',
    :currency => 'MXN'
]
order = Factory::get_instance_of('PlaceOrderInfo', order_info)

# Llamada al método 'place_order' del API para generar la orden
neworder = client.api.place_order(order)

verifyOrder

Para verificar el estatus de una órden generada es necesario llamar al método verify_order que provee el atributo api del objeto Client y el cual regresa una instancia CpOrderInfo. Este método recibe como parámetro el ID generado por ComproPago para cada orden. También puede obtener este ID desde un objeto NewOrderInfo accediendo al atributo id.

Prototipo
# @param string order_id
# @return CpOrderInfo
def verify_order( order_id )
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
order_id string Id generado al registrar una orden en ComproPago
Ejemplo
# Guardar el ID de la orden
order_id = 'ch_xxxx_xxx_xxx_xxxx'

# U obtenerlo de un objetdo NewOrderInfo
order_id = neworder.id

# Se manda llamar al método del API para recuperar la informacion de la orden
info = client.api.verify_order(order_id)

sendSmsInstructions

Para realizar el el envío de las instrucciones de compra vía SMS es necesario llamar al método sendSmsInstructions que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo SmsInfo.

Prototipo
# @param string number
# @param string order_id
# @return SmsInfo
def send_sms_instructions(number, order_id)
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
number string Numero telefónico del cliente al cual se enviara el mensaje de taxto
order_id string ID de la orden de compropago la cual fue generada previamente.
Ejemplo
# Número al cual se enviaran las instrucciones
phone_number = '55xxxxxxxx'

# Id de la orden de compra de cual se enviarán las instrucciones
order_id = 'ch_xxxxx-xxxxx-xxxxx-xxxxx'

# Llamada al método del API para envío de las instrucciones
smsinfo = client.api.send_sms_instructions(phone_number , order_id)

listWebhooks

Para obtener la lista de webhooks registrados en una cuenta, se debe de llamar al método list_webhook que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo list la cual contiene objetos de tipo Webhook.

Prototipo
# @return array
def list_webhooks()
end
Ejemplo
webhooks = client.api.list_webhooks

webhooks.each do |webhook|
    puts webhook.url
end

# https://misitio.com/webhook/
# https://misitio.com/webhook/dos/
# ...

createWebhook

Para crear un nuevo Webhook en la cuenta, se debe de llamar al método create_webhook que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo Webhook.

Prototipo
# @param string url
# @return Webhook
def create_webhook(url)
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
url string Url que sera registrada como EndPoint del webhook.
Ejemplo
# Se pasa como paramtro la URL al webhook
webhook = client.api.create_webhook('http://sitio.com/webhook')

updateWebhook

Para actualizar la url de un webhook, se debe de llamar al método update_webhook que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo Webhook.

Prototipo
# @param string webhook_id
# @param string url
# @return Webhook
def update_webhook(webhook_id, url)
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
webhook_id string Id de un webhook previamente registrado. Puede ser obtenido de una instancia Webhook accediendo al atributo id.
url string Nueva url del webhook
Ejemplo
updated = client.apiupdate_webhook(webhook.id, 'http://sitio.com/nuevo_webhook')

deactiveWebhook

Para eliminar un webhook, se debe de llamar al método delete_webhook que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo Webhook.

Prototipo
# @param string webhook_id
# @return Webhook
def delete_webhook(webhook_id)
end
Parámetros
Parámetro Tipo Valor por defecto Descripción
webhook_id string ID de un webhook previamente registrado. Puede ser obteido de una instancia Webhook accediendo al atributo id.
Ejemplo

deleteWebhook

Para eliminar un webhook, se debe de llamar al método delete_webhook que se encuentra alojado en el atributo api del objeto Client y el cual regresa una instancia de tipo Webhook.

Prototipo

# @param string webhook_id
# @return Webhook
def delete_webhook(webhook_id)
end

Parámetros
Parámetro Tipo Valor por defecto Descripción
webhook_id string Id de un webhook previamente registrado. Puede ser obteido de una instancia Webhook accediendo al atributo id.
Ejemplo

deleted = client.api.delete_webhook( webhook.id )

Webhook Endpoint


Los Webhook EndPoints, son rutas a las cuales ComproPago envia las notificaciones de cambio de estatus con las cuales podra generar la lógica necesaria para sus procesos internos en su sitio. A continuación se muestra un ejemplo de la estructura y control de flujo de un Webhook EndPoint con el framework Sinatra.

Nota: Es importante recalcar que para la correcta recepción de los webhooks, así como la correcta notificación a los servicios de ComproPago, es necesario regresar una cadena de texto siempre que finalice la ejecución de sus rutinas como se muestra a continuación. Tambien se debe de tomar en cuenta que para el procesamiento optimo su sistema no debe de tardar mas de 30 segundos en regresar esta respuesta.

require 'sinatra'
require 'json'
require 'compropago_sdk'

post '/webhook' do
  content_type :json

  data = request.body.read

  resp_webhook = Factory::get_instance_of('CpOrderInfo', data)

  if resp_webhook.nil?
    return {
      status: 'error',
      message: 'invalid request',
      short_id: nil,
      reference: nil
    }.to_json
  end

  if resp_webhook.short_id == '000000'
    return {
      status: 'success',
      message: 'OK - test',
      short_id: resp_webhook.short_id,
      reference: resp_webhook.order_info.order_id
    }.to_json
  end

  publickey = 'pk_test_638e8b14112423a086'
  privatekey = 'sk_test_9c95e149614142822f'
  mode = false

  begin
    client = Client.new(publickey, privatekey, mode)

    verified = client.api.verify_order(resp_webhook.id)

    case verified.type
      when 'charge.success'
        # TODO: Actions for success payments
        break
      when 'charge.pending'
        # TODO: Actions for pending payments
        break
      when 'charge.expired'
        # TODO: Actions for expired payments
        break
      else
        return {
          status: 'error',
          message: 'invalid request type',
          short_id: verified.short_id,
          reference: verified.order_info.order_id
        }.to_json
    end

    return {
      status: 'success',
      message: 'OK - ' + verified.type,
      short_id: verified.short_id,
      reference: verified.order_info.order_id
    }.to_json
  rescue => ex
    return {
      status: 'error',
      message: ex.message,
      short_id: nil,
      reference: nil
    }.to_json
  end
end

Iframe de recibo


Para facilitar el despliegue de instrucciones de pago, puedes incluir un Iframe en tu sitio apuntando alos recibos de ComproPago de la siguiente manera.

<div class="compropagoDivFrame" id="compropagodContainer" style="width: 100%;">
    <iframe style="width: 100%;"
        id="compropagodFrame"
        src="https://www.compropago.com/comprobante/?confirmation_id=ch_xxxxx_xxxx_xxx_xxxxx"
        frameborder="0"
        scrolling="yes"> </iframe>
</div>
<script type="text/javascript">
    function resizeIframe() {
        var container=document.getElementById("compropagodContainer");
        var iframe=document.getElementById("compropagodFrame");
        if(iframe && container){
            var ratio=585/811;
            var width=container.offsetWidth;
            var height=(width/ratio);
            if(height>937){ height=937;}
            iframe.style.width=width + 'px';
            iframe.style.height=height + 'px';
        }
    }
    window.onload = function(event) {
        resizeIframe();
    };
    window.onresize = function(event) {
        resizeIframe();
    };
</script>