Eliminar un pago antes que el pagador termine

En algunas ocaciones es necesario borrar un cobro que se ha generado, por ejemplo si nos quedamos sin stock o si encontramos algún problema para entregar el producto/servicio. Para poder borrar un cobro este no debe haber sido pagado o marcado como pagado.

Para borrar un cobro generado solo necesitaremos su identificador. Veamos un código de ejemplo:

<?php
require __DIR__ . '/vendor/autoload.php';

$configuration = new KhipuConfiguration();
$configuration->setSecret('secret-key');
$configuration->setReceiverId(receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$payments = new KhipuClientPaymentsApi($client);

try {
    $response = $payments->paymentsPost('Prueba de cobro', 'CLP', 1000);
    $response = $payments->paymentsIdDelete($response->getPaymentId());
    print_r($response);

} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, "secret-key");
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);
PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);
PaymentsCreateResponse response = paymentsApi.paymentsPost("Prueba de cobro", "CLP", 1000d);

System.out.println(paymentsApi.paymentsIdDelete(response.getPaymentId()));
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = 'secret-key'
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  # c.debugging = true
end

client = Khipu::PaymentsApi.new
response = client.payments_post('Prueba de cobro', 'CLP', 1000, {})
print client.payments_id_delete(response.payment_id)
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    PaymentsCreateResponse response = a.PaymentsPost("Compra de prueba de la API", "CLP", 100.0);

    System.Console.WriteLine(response);

    SuccessResponse deleteResponse = a.PaymentsIdDelete(response.PaymentId);
}
catch (ApiException e)
{
    Console.WriteLine(e);
}



Crear una cuenta de cobro hija de integrador

Las cuentas hijas se crean usando una llamada especial. Esta llamada devolverá las credenciales de una nueva cuenta de cobro. Debemos guardar estas credenciales para poder generar cobros a nombre de esta nueva cuenta.

En esta llamada debemos enviar los siguientes datos:

  • Email y nombre del dueño de la cuenta. Si el correo existe en Khipu, se usará el usuario existente. Sí no, se creará un nuevo usuario y se asociará la cuenta a él.
  • País para la cuenta: El país donde operará la cuenta.
  • Datos de facturación: Datos para emitir una boleta o factura.
  • Datos de contacto: Datos para que Khipu pueda ponerse en contacto con el administrador de la cuenta de cobro.

Es muy importante saber que esta cuenta no está lista para cobrar. El proceso de creación envía un e-mail al correo indicado para que el dueño de la cuenta (el dueño del e-mail) pueda completar el proceso de pago. Solo una vez completado este proceso la cuenta podrá comenzar a operar.

Es muy importante recordar también que la llamada para crear una cuenta de cobro debe ser hecha con las credenciales de la cuenta padre. Las llamadas para generar los cobros deben ser hechas con las credenciales de las cuentas hijas.

<?php
require __DIR__ . '/vendor/autoload.php';

$configuration = new KhipuConfiguration();
$configuration->setSecret($secret);
$configuration->setReceiverId($receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$receivers = new KhipuClientReceiversApi(new KhipuApiClient($configuration));

try {
    $response = $receivers->receiversPost('Pablo'
        , 'Pereira'
        , 'pablo@micomercio.com'
        , 'CL'
        , '123456789'
        , 'Varios'
        , 'Mi comercio'
        , '+565555555'
        , 'Mi dirección'
        , 'Mi ciudad'
        , 'Mi región'
        , 'Juan Perez'
        , 'encargado de contacto'
        ,  'contacto@micomercio.com'
        , '+566666666');
    print_r($response);

} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, secret);
ReceiversApi receiversApi = new ReceiversApi();
receiversApi.setApiClient(apiClient);

ReceiversCreateResponse response =  receiversApi.receiversPost(
        "Pablo"
        , "Pereira"
        , "pablo@micomercio.com"
        , "CL"
        , "123456789"
        , "Varios"
        , "Mi comercio"
        , "+565555555"
        , "Mi dirección"
        , "Mi ciudad"
        , "Mi región"
        , "Juan Perez"
        , "encargado de contacto"
        , "contacto@micomercio.com"
        , "+566666666");

System.out.println(response);
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = secret
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  #c.debugging = true
end

client = Khipu::ReceiversApi.new

response = client.receivers_post('Pablo',
                                 'Pereira',
                                 'pablo@micomercio.com',
                                 'CL', '123456789',
                                 'Varios',
                                 'Mi comercio',
                                 '+565555555',
                                 'Mi dirección',
                                 'Mi ciudad',
                                 'Mi región',
                                 'Juan Perez',
                                 'encargado de contacto',
                                 'contacto@micomercio.com',
                                 '+566666666')

Crear un cobro con comisión de integrador es identico a crear un cobro normal pero con dos detalles:

  • Se debe enviar el parámetro “integrator_fee” con el monto que recibirá el integrador. Este monto no pude ser superior al monto original menos la comisión de Khipu.
  • Las credenciales que se usan para la llamada deben ser las credenciales de la cuenta hija. Esto es porque el cobro debe quedar a nombre de esta cuenta.

El siguiente es un código de ejemplo:

<?php
require __DIR__ . '/vendor/autoload.php';

$configuration = new KhipuConfiguration();
$configuration->setSecret('secret-key');
$configuration->setReceiverId(receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$payments = new KhipuClientPaymentsApi($client);

try {
    $opts = array(
        "integrator_fee" => 10
    );
    $response = $payments->paymentsPost('Prueba de cobro', 'CLP', 1000, $opts);
    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, "secret-key");
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);
PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);

Map<String, Object> options = new HashMap<>();
options.put("integratorFee", 10d);

PaymentsCreateResponse response = paymentsApi.paymentsPost("Prueba de cobro", "CLP", 1000d, options);

System.out.println(response);
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = 'secret-key'
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  # c.debugging = true
end

client = Khipu::PaymentsApi.new
response = client.payments_post('Prueba de cobro', 'CLP', 1000, {integrator_fee: 10})
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    PaymentsCreateResponse response = a.PaymentsPost("Compra de prueba de la API", "CLP", 100.0
                        , integratorFee: 10.0);

    System.Console.WriteLine(response);

}
catch (ApiException e)
{
    Console.WriteLine(e);
}

En este creamos un cobro por 1000. De esos 1000, 10 serán entregados al integrador de la cuenta hija.

Modificar el usuario dueño de un cobro

Cada cobro en Khipu tiene asociado un “responsible user” (usuario responsable) que es el dueño del cobro. El recibe copia de los comprobantes de pago y copia de los recordatorios semanales. Si se está usando la interfaz web de Khipu, el responsable siempre es el que crea el cobro. Si más de una persona tiene acceso a la cuenta de cobro del comercio uno puede especificar usando la API quien es el dueño de cada cobro creado.

Para poder especificar un usuario como dueño de un cobro el usuario debe poder cobrar usando la cuenta del comercio.

Veamos el siguiente código de ejemplo:

<?php
$configuration = new KhipuConfiguration();
$configuration->setSecret('secret-key');
$configuration->setReceiverId(receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$payments = new KhipuClientPaymentsApi($client);

try {
    $opts = array(
        "responsible_user_email" => "jconnor@the-future.com"
    );
    $response = $payments->paymentsPost('Prueba de cobro', 'CLP', 1000, $opts);
    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, "secret-key");
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);

PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);

Map<String, Object> options = new HashMap<>();
options.put("responsibleUserEmail", "jconnor@the-future.com");

PaymentsCreateResponse response = paymentsApi.paymentsPost("Prueba de cobro", "CLP", 1000d, options);
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = 'secret-key'
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  # c.debugging = true
end

client = Khipu::PaymentsApi.new
response = client.payments_post('Prueba de cobro', 'CLP', 1000, {responsible_user_email: 'jconnor@the-future.com'})
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    PaymentsCreateResponse response = a.PaymentsPost("Compra de prueba de la API", "CLP", 100.0
                        , responsibleUserEmail: : "jconnor@the-future.com");

    System.Console.WriteLine(response);

}
catch (ApiException e)
{
    Console.WriteLine(e);
}

Cobro con autenticación

Es posible crear cobros que solo puedan ser pagados usando una cuenta bancaria perteneciente a alguien en particular. Esto se hace especificando el identificador personal del usuario. Por ejemplo una cuenta bancaria en Chile está asociada a un RUT. Si se especifica un RUT en particular para un cobro, este solo podrá ser pagado utilizando una cuenta asociada a ese RUT.

Veamos un ejemplo:

<?php
require __DIR__ . '/vendor/autoload.php';

$configuration = new KhipuConfiguration();
$configuration->setSecret('secret-key');
$configuration->setReceiverId(receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$payments = new KhipuClientPaymentsApi($client);

try {
    $opts = array(
      "fixed_payer_personal_identifier" => "12.345.678-9"
    );
    $response = $payments->paymentsPost('Prueba de cobro', 'CLP', 1000, $opts);
    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, "secret-key");
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);
PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);

Map<String, Object> options = new HashMap<>();
options.put("fixedPayerPersonalIdentifier", "12.345.678-9");

PaymentsCreateResponse response = paymentsApi.paymentsPost("Prueba de cobro", "CLP", 1000d, options);
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = 'secret-key'
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  # c.debugging = true
end

client = Khipu::PaymentsApi.new
response = client.payments_post('Prueba de cobro', 'CLP', 1000, {fixed_payer_personal_identifier: '12.345.678-9'})
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    PaymentsCreateResponse response = a.PaymentsPost("Compra de prueba de la API", "CLP", 100.0
                        , fixedPayerPersonalIdentifier: "12.345.678-9");

    System.Console.WriteLine(response);

}
catch (ApiException e)
{
    Console.WriteLine(e);
}

Reembolsar un cobro que no ha sido rendido

En el intervalo de tiempo entre que se realiza un pago y Khipu aún no ha entregado los fondos al comercio, es posible reembolsar el cobro, el cliente recibirá un correo electrónico explicandole que el comercio no ha podido completar la transacción y que los fondos serán devueltos a su cuenta bancaria.

Veamos un ejemplo:

<?php
require __DIR__ . '/vendor/autoload.php';

$configuration = new KhipuConfiguration();
$configuration->setSecret('secret-key');
$configuration->setReceiverId(receiver_id);
$configuration->setPlatform('demo-client', '2.0');
# $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$payments = new KhipuClientPaymentsApi($client);

try {
    $payments->paymentsIdRefundsPost("id-del-pago");
    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, "secret-key");
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);
PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);
paymentsApi.paymentsIdRefundsPost("id-del-pago");
require 'khipu-api-client'

Khipu.configure do |c|
  c.secret = 'secret-key'
  c.receiver_id = receiver_id
  c.platform = 'demo-client'
  c.platform_version = '2.0'
  # c.debugging = true
end

client = Khipu::PaymentsApi.new
response = client.payments_id_refunds_post('id-del-pago'})
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    SuccessResponse response = a.PaymentsIdRefundsPost("id-del-pago");

    System.Console.WriteLine(response);

}
catch (ApiException e)
{
    Console.WriteLine(e);
}

Recibiendo y validando notificación de rendición por web service

Khipu permite recibir notificaciones en tu sitio web de manera automática con el detalle de cada rendición realizada hacia la cuenta corriente asociada a tu cuenta de cobro.

Configuración:

Para recibir notificaciones primero debes ingresar a tu cuenta Khipu e ir a “Opciones de la cuenta”. En la sección Notificación instantanea de rendiciones debes agregar la URL en donde tu sitio web escuchará las notificaciones y definir la versión de la API de notificaciones que quieres usar.

Ejemplo en PHP

Las notificaciones de rendición se hacen utilizando un mensaje en estándar JOSE JWS, y ensobrado gzip.

Los mensajes de las notificaciones de rendición se firman con el siguiente certificado.

 Descargar el certificado de clave pública

Si estás usando una cuenta de cobro de desarrollo entonces deberás usar el certificado de desarrollo de Khipu.

 Descargar el certificado de clave pública (desarrollo)

En este ejemplo se hace uso de la librería Namshi/Jose.

<?php
require_once 'vendor/autoload.php';

use NamshiJOSEJWS;

$jws_text=gzdecode($HTTP_RAW_POST_DATA);

$jws=JWS::load($jws_text);

// Leemos el certificado con la clave publica
$filename = 'khipu_signer.pem';
$fp = fopen($filename, "r");
$cert = fread($fp, filesize($filename));
fclose($fp);
$pubkey = openssl_get_publickey($cert);

$payload = $jws->getPayload();

if ($jws->isValid($public_key)) {
/*
   Si la firma del mensaje es valida se puede procesar el mensaje
*/

    $report=$payload['report'];
    $fecha_desde=$report['startDate']; // fecha de inicio de la rendición
    $fecha_hasta=$report['endDate']; //fecha de termino de la rendición
    $report_items=$report['items']; //pagos incluidos en la rendición
    foreach($report_items as $item){
       $customer=$item['customer']; //datos del pagador
       local_process($item['paymentDate'],       //fecha del pago
                     $item['paymentSubject'],    //asunto del pago
                     $item['khOperationCodeUID'],//código único de operación khipu
                     $item['merchantTxID'],      //id de transacción informado por el comercio
                     $item['customer']['customerName'], //nombre del pagador
                     $item['customer']['customerUID'],  //rut del pagador
                     $item['customer']['customerEmail'],//correo electrónico del pagador
                     $item['customer']['customerBankName'], //nombre del banco origen
                     $item['feeScheme'], //esquema de comisión
                     $item['txAmount'],  //monto de la transacción
                     $item['khipuFee']); //comisión khipu
    }
}