Khipu API to create charges and receive payments

A guide to integrate your merchant via our API

 

Previous Concepts

We will show you what’s needed before you start

Charging Account

How to create a charging account to receive payments

Security

Understanding the different security aspects

Create a Charge

To receive a payment

Begin the payment

How to create a charge

After the payment

Redirecting the customer to the merchant

Receive notification

Receives the notification and delivers the product/service

Introduction

Khipu API to create and receive payments, allows individuals or organizations, with an active charging account in Khipu, to generate charges.
With the following procedure for creation, payment and validation:

  1. The collector generates a charge using the API, which displays a button for the purchase.
  2. The payer clicks the payment button on the website, or a link within an email (or other means) and pays using Khipu.
  3. The payer is redirected to the return page defined by the collector, where “Payment Verification” or “Failed Payment” must be indicated.
  4. Moments later Khipu verifies the transaction and notifies the payer by email. Also, the merchant is notified by email and/or by a web service command.
  5. The collector then validates the payment notification and delivers the good to the payer (or discards the notification, if invalid).

Important! ! In the third step the payer is redirected to a return page (3a) or a possible payment rejection. The success means that the transaction is at the verification process, it doesn’t mean that it has been completed yet. It is necessary to complete the verification process (step 5) before delivering the goods or services. The same occurs with the Reject (3b), the user still has instances to pay and complete the transaction.

  1. Charging account

When the customer creates a user account in Khipu a “charging account” will be automatically created. This charging account will be the account where payments from other customers will be associated to.

To be able to collect, it is mandatory to activate the charging account by associating it with a bank account. The bank account is where the daily collections will be deposited the next business day. This bank account can be changed afterwards and will be affected by all payments still not rendered.

Initially, a charging account doesn’t have a bank account associated to. To associate one, you must go to your Khipu account and try to create a charge. The system will ask you to complete a payment using that bank account to ensure that you have access to it. The payment amount will be returned the next business day.

Important: New personal charging accounts, in the case of Chile, has a maximum charge amount of $50.000. To increase this amount, you must contact our support at: soporte@khipu.com.

  1. Multiple charging accounts

A Khipu user account can create (or have access to) multiple charging accounts. This could be used, for example, to have different merchants, each one with its own charging account. Each charging account must have a bank account configured, and several charging accounts can share the same bank account data where the money will be transferred.

  1. Credentials

Every charging account has credentials that allow to use the REST API. These credentials are generated when the charging account is created.

Credentials have two parameters:

  • receiverId: a unique identifier of a charging account and can’t be changed.
  • secret: the secret key of the charging account.

The most important of the credentials is “secret”. This key is used to sign all requirements of the API and shouldn’t be shared with anyone. Khipu support may eventually request the receiverId to follow up cases, but it will not request the secret key. You can always create a new key which will invalidate the former one.

  1. Security

Two different security mechanisms are used in the creation and validation of a payment. First, Khipu uses an extended validation certificate which allows the collector to always know that he is communicating effectively with the official Khipu servers, also, the merchant must sign every API call using its unique account credentials.

To understand the signature process in detail please review the signature documentation.

  1. Testing environment and final release

In this section we will show you the steps necessary to begin the integration of Khipu to your site. The most important to notice is that, during the development process and testings, developer charging accounts credentials must be used. Credentials must be changed to the final ones when your site is ready, and the integration prepared to make real payments.

  1. Charging account in developer mode

Khipu doesn’t have a separate from production testing environment, as other platforms. . Instead, main platform API and servers are used. A “developer charge account” is used for development testing. These charging accounts are identical to the normal ones, with some differences:

Checking accounts associated are not real, as no real money is transferred. They are created just for testing. Charges generated with them can only be paid using test banks.

To create a development account the following steps must be followed:

  • Register as a user here: https://khipu.com/user/register
  • Go to your user profile in Khipu.
  • In “Developer Options” activate the Developer Mode.
  • Go to Configure and select: “Charging Accounts”.
  • A “Create account in Developer Mode” button will appear.

Now that you have a development account, all you need from it is the account credentials. These are obtained in the “Account Options” in the option “To integrate Khipu to your website”.

  1. Test Banks

The developer charging accounts can only receive payments from test banks. These banks are created by Khipu for testing purposes.

A test bank allows for testing the completion of the payment process, including going to the bank and deposit Khipu or use the simplified transfer. As these banks do not use real money, you can make all the transfers you wish as your balance will never run out.

These banks, also, has on-screen instructions to allow for input, fill out codes and make transfers.

  1. Correct library installation

We’ve generated libraries for the most popular programming languages. The following code shows how to install these libraries:

In PHP we use “composer” for libraries and dependencies. We must add Khipu to the dependencies of the “composer.json” file:

{ 
  "require": { 
    "khipu/khipu-api-client": "2.9.1" 
  } 
}

And then execute:

$ composer install 
Installing dependencies (including require-dev) 
  - Installing khipu/khipu-api-client (2.9.1) 
  Downloading: 100% 
Writing lock file
Generating autoload files

Then, in our php files we must add the following line to have the library available:

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

In Java, using Maven to resolve dependencies, we need to add the following lines to our “pom.xml” file.

<dependency>
    <groupId>com.khipu</groupId>
    <artifactId>khipu-api-client</artifactId>
    <version>2.9.0</version>
</dependency>

The Khipu library is intended to be used with a virtual machine 1.7 or higher. Even so, it is possible to use it with java 1.6. For this it is necessary to add the following changes.

First, you need to add a newer crypto provider. For that you need to add this new dependency:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.54</version>
</dependency>

Then, for this cryptographic provider to be available, it is necessary to add it to the virtual machine’s available ones. In the source code of the application it is necessary to add the following lines:

import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
Security.addProvider(new BouncyCastleProvider());

It is also possible to leave this provider built into the virtual machine. With that we avoid including the lines of code and the provider is available for other applications. For this it is necessary to follow the instructions available on the page of http://www.bouncycastle.org

For Ruby we have prepared a gem. To install the gem, we must use the “gem” command:

$ gem install khipu-api-client

Then in your script you must add this line to have the client available:

require 'khipu-api-client'

For .NET we have available a library packaged in a NuGet that is installed using the Package Manager Console

PM> Install-Package KhipuApiClient
  1. Internet access

To be able to access Khipu’s API REST it is necessary to have an Internet connection. This is required to be able to create and modify payments.

Each time Khipu receives a payment, the merchant is notified so that it can deliver the goods or services to the final customer. This notification can be an email or using the API instant notifications. The recommended mechanism is the instant notification as it doesn’t require human intervention once it’s configured. These notifications are Khipu invocations that Khipu must perform to a web service in the merchant website. Therefore, this web service must be visible from Internet.

  1. Common use case

We will analyze the most common use case of the REST API, which is making a payment in a merchant’s web to obtain a product. The most common flow has the following steps:

  • The customer chooses the products and selects to pay.
  • The merchant creates a payment using the REST API.
  • The merchant sends the customers to Khipu for payment.
  • The customer pays.
  • The customer is redirected to the merchant’s web site and waits while Khipu verifies the payment.
  • The payment is verified, and the merchant is notified through web service.
  • The merchant delivers the product or service.

Let’s see now the steps where the integration with Khipu is necessary:

  1. Create a charge POST /payments

After the customer selects the product and chooses to pay, the payment process begins. The majority of electronic commerce software work in a similar way. They all have some type of object that symbolizes the purchase order. What we must do is relate this purchase order to a payment in Khipu.

Let’s see the following code:

<?php

// Debemos conocer el $receiverId y el $secretKey de ante mano.
$receiverId = obtener-al-crear-una-cuenta-de-cobro;
$secretKey = 'obtener-al-crear-una-cuenta-de-cobro';

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

$configuration = new KhipuConfiguration();
$configuration->setReceiverId($receiverId);
$configuration->setSecret($secretKey);
// $configuration->setDebug(true);

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

try {
    $opts = array(
        "transaction_id" => "MTI-100",
        "return_url" => "http://mi-ecomerce.com/backend/return",
        "cancel_url" => "http://mi-ecomerce.com/backend/cancel",
        "picture_url" => "http://mi-ecomerce.com/pictures/foto-producto.jpg",
        "notify_url" => "http://mi-ecomerce.com/backend/notify",
        "notify_api_version" => "1.3"
    );
    $response = $payments->paymentsPost(
        "Compra de prueba de la API", //Motivo de la compra
        "CLP", //Monedas disponibles CLP, USD, ARS, BOB
        100.0, //Monto. Puede contener ","
        $opts //campos opcionales
);

    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
int receiverId = obtener-al-crear-una-cuenta-de-cobro;
String secretKey = 'obtener-al-crear-una-cuenta-de-cobro';

ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, secretKey);
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);
PaymentsApi paymentsApi = new PaymentsApi();
paymentsApi.setApiClient(apiClient);

Map<String, Object> options = new HashMap<>();
options.put("transactionId", "MTI-100");
options.put("returnUrl", "http://mi-ecomerce.com/backend/return");
options.put("cancelUrl", "http://mi-ecomerce.com/backend/cancel");
options.put("pictureUrl", "http://mi-ecomerce.com/pictures/foto-producto.jpg");
options.put("notifyUrl", "http://mi-ecomerce.com/backend/notify");
options.put("notifyApiVersion", "1.3");

PaymentsCreateResponse response = paymentsApi.paymentsPost("Compra de prueba de la API" //Motivo de la compra
        , "CLP" //Monedas disponibles CLP, USD, ARS, BOB
        , 100.0 //Monto
        , options //campos opcionales
);

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

receiver_id = obtener-al-crear-una-cuenta-de-cobro
secret_key = 'obtener-al-crear-una-cuenta-de-cobro'

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('Motivo del cobro', 'CLP', 120000, {// Monedas disponibles CLP, USD, ARS, BOB. Monto puede contener ","
    transaction_id: 'FACT2001',
    expires_date: DateTime.new(2016, 4, 4),
    body: 'Descripción de la compra',
    picture_url: 'http://mi-ecomerce.com/pictures/foto-producto.jp',
    return_url: 'http://mi-ecomerce.com/backend/return',
    cancel_url: 'http://mi-ecomerce.com/backend/cancel',
    notify_url: 'http://mi-ecomerce.com/backend/notify',
    notify_api_version: '1.3'
})
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
PaymentsApi a = new PaymentsApi();

try
{
    DateTime dt = DateTime.Now;
    dt = dt.AddDays(5);
    PaymentsCreateResponse response = a.PaymentsPost(
        "Compra de prueba de la API", 
        "CLP",
        100.0, 
        transactionId: "FACT2001", 
        expiresDate: dt, 
        body: "Descripción de la compra", 
        pictureUrl: "http://mi-ecomerce.com/pictures/foto-producto.jpg", 
        returnUrl: "http://mi-ecomerce.com/backend/return", 
        cancelUrl: "http://mi-ecomerce.com/backend/cancel", 
        notifyUrl: "http://mi-ecomerce.com/backend/notify", 
        notifyApiVersion: "1.3"
     );
    System.Console.WriteLine(response);
}
catch (ApiException e)
{
    Console.WriteLine(e);
}

 

In the first step we obtain the purchase order object. This can be created now or recovered through the “id”. In the next step a payment is created in Khipu using the associated library.

In the transaction_id parameter of the call the purchase order identifier is sent. This is necessary so that at the time of reconciliation we can obtain the purchase order and consider it paid.

The answer to the call will be an object with information about the charge created. The “payment_id” field contains the identifier of our payment and the url to which we must send the user to pay.

List of banks (optional) POST /banks

This step is optional but may be useful for some businesses. In the previous call to create payments you can see the parameter “ID of the bank to pay”. This ID is used to create a payment with an already chosen bank (only from the banks supported by Khipu). To obtain this id, you can use the banksGet call that provides the list of banks supported by Khipu, their names, their id and other information.

Let’s look at the following example:

<?php

// Debemos conocer el $receiverId y el $secretKey de ante mano.
$receiverId = obtener-al-crear-una-cuenta-de-cobro;
$secretKey = 'obtener-al-crear-una-cuenta-de-cobro';

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

$configuration = new KhipuConfiguration();
$configuration->setReceiverId($receiverId);
$configuration->setSecret($secretKey);
// $configuration->setDebug(true);

$client = new KhipuApiClient($configuration);
$banksApi = new KhipuClientBanksApi($client);

try {
    $response = $banksApi->banksGet();
    print_r($response);
} catch (KhipuApiException $e) {
    echo print_r($e->getResponseBody(), TRUE);
}
int receiverId = obtener-al-crear-una-cuenta-de-cobro;
String secretKey = 'obtener-al-crear-una-cuenta-de-cobro';

ApiClient apiClient = new ApiClient();
apiClient.setKhipuCredentials(receiverId, secretKey);
apiClient.setPlatform("demo-client", "2.0");
// apiClient.setDebugging(true);

BanksApi banksApi = new BanksApi();
banksApi.setApiClient(apiClient);
BanksResponse response = banksApi.banksGet();
System.out.println(response);
require 'khipu-api-client'

receiver_id = obtener-al-crear-una-cuenta-de-cobro
secret_key = 'obtener-al-crear-una-cuenta-de-cobro'

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

banks = Khipu::BanksApi.new
response = banks.banks_get()
print response

The result of the call contains the value “banks” which is a banks listing. Each bank has a “bank_id” with the value we can use to create configured payments.

  1. Start Payment

Once a payment has been created, we must start the payment process. This can be done in two ways. The recommended way is to use our javascript library that will take care of the beginning of the payment. You can find extensive documentation on the github website. Also, you can use our library integration example that simulates a store that uses this library.

The other option to start the payment is simply to redirect the customer to the payment url in Khipu. This url corresponds to the payment_url parameter returned by the create payment call.

  1. Customer is redirected to the merchant

After the customer makes the payment in the Khipu portal he/she will be redirected to the merchant web site. This merchant web site url must be configured for each payment in the “return_url” field, although it could be the same one for all payments.

It is very important to notice that when the user returns to the merchant page this doesn’t mean that the payment has been verified, so in the merchant web page must be stated that the payment is in the verification process and that they must wait.

The web page must periodically consult the merchant’s server to look up the status of the purchase order and inform the user when the payment has been confirmed.

For this, there are three strategies:

  • Web-sockets: The merchant server informs the customer browser that the payment is confirmed so that it can be displayed. It is the most efficient way, but the most complex one to implement. More info at: https://en.wikipedia.org/wiki/WebSocket
  • AJAX calls: The page verifies through an AJAX call to the merchant server about the state of the order. When the answer is positive the page notifies the user that the payment has been completed.
  • Reload the page periodically. It’s the simplest mechanism and consists in using a timer to reload the page periodically, for example every 10 seconds. Every time the page loads the complete order is verified. If it is, the user is redirected to the success page. If not, it must indicate to the user that it is necessary to keep waiting and use a new timer.
  1. Receive the notification and deliver the product/service GET /payments

If you have configured a URL to receive a notification, then Khipu will invoke immediately after reconciling the payment. This notification is received by Khipu’s instant notification API. This API version defines the way in which Khipu notifies the merchant.

There are several versions of the API, we will focus on the most recent one: 1.3. In this version, 2 parameters per POST will arrive, one with the version of the API “api_version”, used to verify that it is the correct version. Tthe second parameter is “notification_token”, By using notification_token we can obtain the information of the payment to be able to consider the product as paid.

Important: Khipu waits 30 seconds to receive a notification response. If, after 30 seconds, no answer is received, Khipu will try to notify again later. Therefore, if the process of receiving the notification takes more than 30 seconds, it needs to be done in the background as to respond immediately.

Let’s look at the following code:

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

$receiver_id = obtener-al-crear-una-cuenta-de-cobro;
$secret = 'obtener-al-crear-una-cuenta-de-cobro';

$api_version = 'obtener-desde-los-parametros';  // Parámetro api_version
$notification_token = 'obtener-desde-los-parametros'; //Parámetro notification_token
$amount = monto-original-del-cobro;

try {
    if ($api_version == '1.3') {
        $configuration = new KhipuConfiguration();
        $configuration->setSecret($secret);
        $configuration->setReceiverId($receiver_id);
        // $configuration->setDebug(true);

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

        $response = $payments->paymentsGet($notification_token);
        if ($response->getReceiverId() == $receiver_id) {
            if ($response->getStatus() == 'done' && $response->getAmount() == $amount) {
                // marcar el pago como completo y entregar el bien o servicio
            }
        } else {
            // receiver_id no coincide
        }
    } else {
        // Usar versión anterior de la API de notificación
    }
} catch (KhipuApiException $exception) {
    print_r($exception->getResponseObject());
}
int receiverId = obtener-al-crear-una-cuenta-de-cobro;
String secret = 'obtener-al-crear-una-cuenta-de-cobro';
String apiVersion = "obtener-desde-los-parametros"; // Parámetro api_version
String notificationToken = "obtener-desde-los-parametros"; // Parámetro notification_token
double amount = monto-original-del-cobro;

if (apiVersion.equals("1.3")) {
    ApiClient apiClient = new ApiClient();
    apiClient.setKhipuCredentials(receiverId, secret);
    apiClient.setPlatform("demo-client", "2.0");
    // apiClient.setDebugging(true);
    PaymentsApi paymentsApi = new PaymentsApi();
    paymentsApi.setApiClient(apiClient);

    PaymentResponse response = paymentsApi.paymentsGet(notificationToken);
    if (response.getReceiverId().longValue() == receiverId) {
        if (response.getStatus().equals("done") && response.getAmount() == amount) {
            // marcar el pago como completo y entregar el bien o servicio
        }
    } else {
        // receiverId no coincide
    }
} else {
    // Usar versión anterior de la API de notificación
}
require 'khipu-api-client'
receiver_id = obtener-al-crear-una-cuenta-de-cobro
secret = 'obtener-al-crear-una-cuenta-de-cobro'
api_version = 'obtener-desde-los-parametros' # Parámetro api_version
notification_token = 'obtener-desde-los-parametros'  # Parámetro notification_token
amount = monto-original-del-pago

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

  client = Khipu::PaymentsApi.new
  response = client.payments_get(notification_token)
  if response.receiver_id == receiver_id
    if response.status == 'done' && response.amount == amount
      # marcar el pago como completo y entregar el bien o servicio
    end
  else
    # receiver_id no coincide
  end
else
  # Usar versión anterior de la API de notificación
end
Configuration.ReceiverId = obtener-al-crear-una-cuenta-de-cobro;
Configuration.Secret = "obtener-al-crear-una-cuenta-de-cobro";
string notificationToken = "obtener-desde-los-parametros-del-request";
string apiVersion = "obtener-desde-los-parametros-del-request";
double amount = monto-original-del-cobro;

if(apiVersion.Equals("1.3")) {
    PaymentsApi a = new PaymentsApi();
    try
    {
         PaymentsResponse response = a.PaymentsGet(notificationToken);
         if(response.ReceiverId.Equals(Configuration.ReceiverId)
                && response.Status.Equals("done") && response.Amount == amount)
         {
            # marcar el pago como completo y entregar el bien o servicio
         }
         else
         {
            # ignorar la invocación
         }
    }
    catch (ApiException e)
    {
        Console.WriteLine(e);
    }
}

Chile Address: Las Urbinas 53 oficina 132, Providencia, Santiago, Chile. Postal code 7510093

Argentina Address: Besares 1029, Chacras de Coria, Mendoza, Argentina. Postal code 5505.