Introducción


El paquete de ComproPago Python 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).

Para hacer uso de la librería es necesario que tenga una cuenta previamente creada en compropago.com, la cual le otorgara un set de llaves de acceso para configurar el cliente de la librería.

Requerimientos


  • Python >= 3.0
  • requests >= 2.9.1
  • six >= 1.10.0

Instalación


Puedes descargar directamente el SDK de compropago desde Pypi con el siguiente comando.

pip3 install compropago

Tambien puedes consultar nuestro listado de versiones directamente en Github, o si lo prefieres puedes clonar directamente el cádigo fuente para incluirlo en tu proyecto.

git clone https://github.com/compropago/sdk-python.git

Configuración


Importación

Para poder hacer uso de la librería es necesario incluir las clases principales de la libreria.

from compropago.client import Client
from compropago.factory.factory import Factory

La clase Client corresponde a la clase principal del SDK y es con la cual se tiene acceso a todas las funcionalidades del API. Por su lado la clase Factory es la encargada de la generación de todos los modelos dentro del SDK y es ocupada para la instaciación de clases como PlaceOrderInfo al momento de generar los cargos.

Configurar el clinete

Para hacer uso de la libreria y llamados al API es necesario que primero configures tus Llaves de conexión y crees un instancia de Client. Tus llaves las encontraras en su Panel de ComproPago en el menú Configuración.

# @param string publickey     Llave publica 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(
    '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 disponobles para su tienda con parámetros para su facil filtrado, la cual regresa una lista de objetos de tipo Provider con los cuales puede acceder a sus atributos.

Prototipo

# @param [Boolean] auth
# @param [Float]   limit
# @param [string]  currency
# @return [list]
def list_providers(self, auth = False, limit = 0, currency = 'MXN')

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. Los valores soportados son: Pesos mexicanos (MXN), Dólar americano(USD), Euro(EUR), Libra Esterlina(GBP).
Ejemplo

>>> provs = client.api.list_providers()
>>> for prov in provs:
...     print(prov.name)
7Eleven
Coppel
...
>>> 

placeOrder

Éste método le permite registrar órdenes 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 contendrá la información resultante de la generación de la orden.

Prototipo

# @param [PlaceOrderInfo] info
# @return [NewOrderInfo]
def place_order(self, info)

Parámetros
Parámetro Tipo Valor por defecto Descripción
info PlaceOrderInfo Objeto con la información de la orden generado mediante la clase Factory
Ejemplo

# Hash con la información que contendrá el objeto
"""
# @param string order_id          Id de la orden.
# @param string order_name        Nombre del producto o productos de la orden.
# @param float  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      (default = SEVEN_ELEVEN) Valor del atributo internal_name' de un objeto 'Provider'.
# @param string currency          (default = MXN) Código de la moneda con la que se esta creando el cargo.
"""
order_info = {
    'order_id': 123,
    'order_name': 'M4 unit python',
    'order_price': 123.45,
    'customer_name': 'Eduardo Aguilar',
    'customer_email': '[email protected]',
    'payment_type': 'SEVEN_ELEVEN',
    'currency': 'MXN'
}

# Creación del objeto PlaceOrderInfo
order = Factory.get_instance_of('PlaceOrderInfo', order_info)

# Llamada al método 'place_order' del API para generar la órden
new_order = 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] id
# @return [CpOrderInfo]
def verify_order(self, id)

Parámetros
Parámetro Tipo Valor por defecto Descripción
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 = new_order.id

# Se manda llamar al método del API para recuperar la información 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 send_sms_instructions 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] id
# @return [SmsInfo]
def send_sms_instructions(self, number, id)

Parámetros
Parámetro Tipo Valor por defecto Descripción
number string Numero telefónico del cliente al cual se enviará el mensaje de texto.
id string ID de la orden de compropago la cual fue generada previamente.
Ejemplo

# Número al cual se enviarán las instrucciones
phone_number = "55xxxxxxxx";

# Id de la órden 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 [list]
def list_webhooks(self)

Ejemplo

>>> webhooks = client.api.list_webhooks()
>>> for webhook in webhooks:
...     print(webhook.url)
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(self, url)

Parámetros
Parámetro Tipo Valor por defecto Descripción
url string Url que será registrada como EndPoint del webhook.
Ejemplo

# Se pasa como parámetro 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] url
# @param [String] id
# @return [Webhook]
def update_webhook(self, id, url)

Parámetros
Parámetro Tipo Valor por defecto Descripción
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

# @param [String] webhook_id
def deactive_webhook(self, webhook_id)

deactiveWebhook

Para desactivar un webhook y evitar que reciba notificaciones sin eliminarlo debe de ocupar la función deactive_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
def deactive_webhook(self, webhook_id)

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.
Ejemplo

deactive = client.api.deactive_webhook(webhook.id)

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] id
# @return [Webhook]
def delete_webhook(self, id)

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

deleted_webhook = 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 podrás 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 web CherryPy.

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.

import cherrypy
import json
from compropago.client import Client
from compropago.factory.factory import Factory

class HelloWorld(object):
    @cherrypy.tools.json_out()
    @cherrypy.expose
    def webhook(self):
        cl = cherrypy.request.headers['Content-Length']
        if cl == '0':
            return {
                'status': 'error',
                'message': 'No data in request',
                'short_id': None,
                'reference': None
            }

        rawbody = cherrypy.request.body.read(int(cl)).decode("iso-8859-1")
        resp_webhook = Factory.get_instance_of('CpOrderInfo', rawbody)

        if len(resp_webhook.id) == 0:
            return {
                'status': 'error',
                'message': 'Invalid request',
                'short_id': None,
                'reference': None
            }

        if resp_webhook.short_id == '000000':
            return {
                'status': 'success',
                'message': 'test_success',
                'short_id': resp_webhook.short_id,
                'reference': None
            }

        publickey = 'pk_test_638e8b14112423a086'
        privatekey = 'sk_test_9c95e149614142822f'
        mode = False

        try:
            client = Client(publickey, privatekey, mode)

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

            if verified.type == 'charge.success':
                # TODO: Actions for success payments
            elif verified.type == 'charge.pending':
                # TODO: Actions for pending payments
            elif verified.type == 'charge.expired':
                # TODO: Actions for expired payments
            else:
                return {
                    'status': 'error',
                    'message': 'Invalid status',
                    'short_id': verified.short_id,
                    'reference': verified.order_info.order_id
                }

            return {
                'status': 'success',
                'message': 'OK',
                'short_id': verified.short_id,
                'reference': verified.order_info.order_id
            }
        except Exception as e:
            print(e.args)
            return {
                'status': 'error',
                'message': 'Unexpected error',
                'short_id': None,
                'reference': None
            }

cherrypy.quickstart(HelloWorld())

Iframe de recibo


Para facilitar el despliegue de las instrucciones de pago, puedes incluir un Iframe en tu sitio apuntando a los 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>


Dentro del parámetro src del Iframe, se especifica la ruta del recibo, la cual contiene un parámetro confirmation_id el cual debera contener el Id de la ordene generada, el cual se puede obtener del atributo id de los objetos NewOrderInfo o CpOrderInfo.