PSE
¿Cómo Funciona?
- El usuario visualiza y selecciona PSE una opción de pago, que son débitos a cuentas de ahorro y corriente en Colombia.
- Luego se presenta la lista de bancos, que debe estar cacheada localmente y su refrescamiento debe ser una vez por día, y el tipo de banca a desplegar: personas o empresas.
- Al tiempo que el cliente confirma la operación, debe consumirse el servicio para realizar la petición de la transacción.
- Si la petición es exitosa, se retorna la URL a la cual debe enviarse al cliente para que realice la operación en el banco. En caso contrario, se muestra el motivo del rechazo de la transacción.
- Se almacenan los datos de la transacción retornados por el servicio (identificador de la transacción, autorización/cus, identificador sesión de Place to Pay).
- Se redirige el navegador a la URL retornada en caso de éxito.
- Una vez la transacción retorna (retorna a la URL especificada en el consumo de la transacción), se debe preguntar por el estado de la transacción mediante el consumo un servicio.
- Dependiendo de la respuesta del servicio, la transacción puede haber sido aprobada, rechazada o seguir pendiente de procesamiento.
- Informa al usuario el estado de la transacción.
- Si la transacción está pendiente, o si el cliente al abandonar el portal no ha regresado, se debe tener una sonda que pregunte por el estado de la transacción.
Despliegue de bancos disponibles
Una vez el cliente ha decidido pagar con débito a una cuenta corriente o de ahorros, verá la lista de los bancos que en el momento están disponibles para la transacción. Esta lista se obtiene mediante el consumo del método getBankList, el cual debe ser consumido una vez por día, lo que exige que esté disponible un mecanismo de caché que permita recuperar la lista si ya ha sido consumido el servicio en el día. Simultáneamente, el usuario también debe indicar qué tipo de persona es si natural o jurídica.
Si por algún motivo la lista de bancos no pudo ser obtenida, debe mostrarse un mensaje de “no se pudo obtener la lista de entidades financieras, por favor intente más tarde” y, consumir nuevamente el servicio de lista de bancos y poderla almacenar en el caché.
Ten presente que en operaciones de Multicrédito debes utilizar su código de servicio y que siempre deberá pasar todas las cuentas dependientes (entidad, servicio) para los créditos así algunas de ellas vayan con valores en cero. Es requerido que la lista de créditos corresponda con todos los subcódigos dependientes.
Confirmación y redirección al banco
Una vez se poseen los datos del pagador y comprador, así como el nombre e interfaz del banco, se deberá entonces consumir el servicio de createTransaction para obtener la URL a la cual deberá redirigir al cliente para finalizar la transacción.
Los datos solicitados para crear la transacción requieren la dirección IP desde la cual el cliente está realizando la transacción, así como la información del navegador usado. Si deseas, puedes proveer datos adicionales con la transacción que permitirán tener esta información disponible en la consola de consulta de transacciones de Place to Pay.
Si la respuesta del servicio es SUCCESS, entonces se deberá almacenar la información retornada en tu base de datos, especialmente el transactionID pues es con este identificador que podrá consultar el estado final de la transacción.
Ten en cuenta que una respuesta SUCCESS en este punto sólo implica que la transacción ha sido aprovisionada por el banco y está en espera que el cliente llegue a la interfaz del banco, se autentique y autorice la operación iniciada.
Al crear la transacción, esta puede fallar; algunos motivos incluyen: montos por fuera del rango permitido, no disponibilidad del banco, problemas de configuración de la cuenta recaudadora, entre otros. Utiliza la propiedad responseReasonText para obtener el mensaje de por qué falló la creación de la transacción. Algunos códigos no relacionados con el pagador pueden indicarle que genere una alerta sobre problemas con la disponibilidad del servicio, particularmente los relacionados con mala configuración.
Una vez has almacenado la información en tu base de datos y confirmado que es exitosa la petición, se redirigirá al cliente a la URL del banco. La redirección a la interfaz del banco no debe realizarse en un frame o cualquier otro mecanismo que oculte la URL en la cual el cliente ingresará sus datos de autenticación
Reingreso del cliente
Una vez el cliente ha finalizado la transacción en la interfaz del banco, el banco redirige al cliente a la URL especificada al crear la transacción, en este punto de entrada a tu aplicación, deberás consumir el servicio getTransactionInformation que determine el estado de la transacción. Solo si la transacción tiene como estado OK es porque la transacción fue autorizada, si por el contrario obtiene un estado PENDING es porque aún no tiene respuesta final del banco acerca de la transacción.
Ya sea que el cliente retorne al punto de reingreso y que la transacción esté pendiente, o que haya abandonado la operación y haya roto el flujo normal, se deberá consumir el servicio getTransactionInformation para todas las operaciones que desde que fue invocado el createTransaction llevan más de 7 minutos sin un estado final de operación.
Descripción de la interfaz del Webservice
Aquí describimos los métodos que el webservice brinda. Las operaciones descritas a continuación son tipo petición – respuesta y se muestran los parámetros de entrada a cada operación y vínculos a las estructuras de datos usadas.
getBankList
Obtiene la lista de bancos disponibles para el establecimiento de comercio en el sistema PSE de ACH Colombia. La respuesta de este servicio debe ser cacheada y el servicio, consumido una vez por día.
Parámetros
Nombre | Tipo | Descripción |
auth | Authentication | Datos de autenticación |
Retorno
Bank[]. Un arreglo con la lista de bancos habilitados.
createTransaction
En los datos de la solicitud se especifica quién es el pagador, el comprador y el despacho. Así mismo para cuál de los bancos habilitados se hace la petición y a que URL de retorno debe el banco redirigir al cuentahabiente.
Parámetros
Nombre | Tipo | Descripción |
auth | Authentication | Datos de autenticación |
transaction | PSETransactionRequest | Datos de la solicitud |
Retorno
PSETransactionResponse. Respuesta de la creación de la transacción, la URL del banco se entrega solo si la propiedad returnCode es SUCCESS.
PSETransactionResponse
PSETransactionResponse: estructura con la información de respuesta para la creación de una transacción.
Propiedades
Nombre | Tipo | Descripción |
transactionID | int | Identificador único de la transacción en Place to Pay |
sessionID | string[32] | Identificador único de la sesión en Place to Pay |
returnCode | string[30] | Código de respuesta de la transacción, uno de los siguientes valores:
SUCCESS FAIL_ENTITYNOTEXISTSORDISABLED FAIL_BANKNOTEXISTSORDISABLED FAIL_SERVICENOTEXISTS FAIL_INVALIDAMOUNT FAIL_INVALIDSOLICITDATE FAIL_BANKUNREACHEABLE FAIL_NOTCONFIRMEDBYBANK FAIL_CANNOTGETCURRENTCYCLE FAIL_ACCESSDENIED FAIL_TIMEOUT FAIL_DESCRIPTIONNOTFOUND FAIL_EXCEEDEDLIMIT FAIL_TRANSACTIONNOTALLOWED FAIL_RISK FAIL_NOHOST FAIL_NOTALLOWEDBYTIME FAIL_ERRORINCREDITS |
trazabilityCode | string[40] | Código único de seguimiento para la operación dado por la red ACH |
transactionCycle | int | Ciclo de compensación de la red |
bankCurrency | string[3] | Moneda aceptada por el banco acorde a ISO 4217 |
bankFactor | float | Factor de conversión de la moneda |
bankURL | string[255] | URL a la cual remitir la solicitud para iniciar la interfaz del banco, sólo disponible cuando returnCode = SUCCESS |
responseCode | int | Estado de la operación en PlacetoPay [ 0 = FAILED, 1 = APPROVED, 2 = DECLINED, 3 = PENDING ] |
responseReasonCode | string[3] | Código interno de respuesta de la operación en Place to Pay |
responseReasonText | string[255] | Motivo de respuesta de la operación en Place to Pay |
PSETransactionMultiCreditRequest
PSETransactionMultiCreditRequest: estructura que representa una solicitud de transacción con débitos a cuenta PSE.
Propiedades
Nombre | Tipo | Descripción |
bankCode | string[4] | Código de la entidad financiera con la cual realizar la transacción |
bankInterface | string[1] | Tipo de interfaz del banco a desplegar [0 = PERSONAS, 1 = EMPRESAS] |
returnURL | string[255] | URL de retorno especificada para la entidad financiera |
reference | string[32] | Referencia única de pago |
description | string[255] | Descripción del pago |
language | string[2] | Idioma esperado para las transacciones acorde a ISO 631-1, mayúscula sostenida |
currency | string[3] | Moneda a usar para el recaudo acorde a ISO 4217 |
totalAmount | double | Valor total a recaudar |
taxAmount | double | Discriminación del impuesto aplicado |
devolutionBase | double | Base de devolución para el impuesto |
tipAmount | double | Propina u otros valores exentos de impuesto (tasa aeroportuaria) y que deben agregarse al valor total a pagar |
payer | Person | Información del pagador |
buyer | Person | Información del comprador |
shipping | Person | Información del receptor |
ipAddress | string[15] | Dirección IP desde la cual el pagador realiza la transacción |
userAgent | string[255] | Agente de navegación utilizado por el pagador |
additionalData | Attribute[] | Datos adicionales para ser almacenados con la transacción |
credits | CreditConcept[] | Detalle de la dispersión a realizar |
PSETransactionRequest
PSETransactionRequest: estructura que representa una solicitud de transacción con débitos a cuenta PSE.
Propiedades
Nombre | Tipo | Descripción |
bankCode | string[4] | Código de la entidad financiera con la cual realizar la transacción |
bankInterface | string[1] | Tipo de interfaz del banco a desplegar [0 = PERSONAS, 1 = EMPRESAS] |
returnURL | string[255] | URL de retorno especificada para la entidad financiera |
reference | string[32] | Referencia única de pago |
description | string[255] | Descripción del pago |
language | string[2] | Idioma esperado para las transacciones acorde a ISO 631-1, mayúscula sostenida |
currency | string[3] | Moneda a usar para el recaudo acorde a ISO 4217 |
totalAmount | double | Valor total a recaudar |
taxAmount | double | Discriminación del impuesto aplicado |
devolutionBase | double | Base de devolución para el impuesto |
tipAmount | double | Propina u otros valores exentos de impuesto (tasa aeroportuaria) y que deben agregarse al valor total a pagar |
payer | Person | Información del pagador |
buyer | Person | Información del comprador |
shipping | Person | Información del receptor |
ipAddress | string[15] | Dirección IP desde la cual el pagador realiza la transacción |
userAgent | string[255] | Navegador utilizado por el pagador |
additionalData | Attribute[] | Datos adicionales para ser almacenados con la transacción |
createTransactionMultiCredit
Solicita la creación de una transacción con dispersión de fondos. En los datos de la solicitud se especifica quién es el pagador, el comprador y el despacho. Así mismo para cuál de los bancos habilitados se hace la petición y a que URL de retorno debe el banco redirigir al cuentahabiente. Así como cada uno de los créditos a aplicar para cada uno de los servicios asociados. Un servicio multicrédito tiene asociado unos servicios dependientes. Siempre deberás cobrar a todos los servicios dependientes así el valor para una de los créditos sea cero.
Parámetros
Nombre | Tipo | Descripción |
auth | Authentication | Datos de autenticación |
transaction | PSETransactionMultiCreditRequest | Datos de la solicitud |
Retorno
PSETransactionResponse. Respuesta de la creación de la transacción, tenga en cuenta que la URL del banco se entrega solo si la propiedad returnCode es SUCCESS.
getTransactionInformation
Obtiene la información de una transacción, debe ser consultado para cualquier operación previamente creada con el método createTransaction o createTransactionMultiCredit ya sea cuando regresa del banco o cuando al menos han transcurrido 7 minutos desde que el cliente fue redirigido a la interfaz del banco. Deberá consumirse en intervalos de al menos cada 12 minutos hasta que tenga un estado de transacción transactionState diferente a PENDING.
Parámetros
Nombre | Tipo | Descripción |
auth | Authentication | Datos de autenticación |
transactionID | int | Identificador único de la transacción en PlacetoPay, equivale al retornado en la creación de la transacción |
Retorno
TransactionInformation: información del estado de la transacción.
TransactionInformation
TransactionInformation: estructura con la respuesta a una solicitud de información de transacción.
Propiedades
Nombre | Tipo | Descripción |
transactionID | int | Identificador único de la transacción en Place to Pay |
sessionID | string[32] | Identificador único de la sesión en Place to Pay |
reference | string[32] | Referencia única de pago |
requestDate | string | Fecha de solicitud o creación de la transacción acorde a ISO 8601 |
bankProcessDate | string | Fecha de procesamiento de la transacción acorde a ISO 8601 |
onTest | boolean | Indicador de si la transacción es en modo de pruebas o no |
returnCode | string[30] | Código de respuesta de la transacción, uno de los siguientes:
SUCCESS FAIL_INVALIDTRAZABILITYCODE FAIL_ACCESSDENIED FAIL_INVALIDSTATE FAIL_INVALIDBANKPROCESSINGDATE FAIL_INVALIDAUTHORIZEDAMOUNT FAIL_INCONSISTENTDATA FAIL_TIMEOUT FAIL_INVALIDVATVALUE FAIL_INVALIDTICKETID FAIL_INVALIDSOLICITEDATE FAIL_INVALIDAUTHORIZATIONID FAIL_TRANSACTIONNOTALLOWED FAIL_ERRORINCREDITS FAIL_EXCEEDEDLIMIT |
trazabilityCode | string[40] | Código único de seguimiento para la operación dado por la red ACH |
transactionCycle | int | Ciclo de compensación de la red |
transactionState | string[20] | Información del estado de la transacción [ OK, NOT_AUTHORIZED, PENDING, FAILED ] |
responseCode | int | Estado de la operación en PlacetoPay |
responseReasonCode | string[3] | Código interno de respuesta de la operación en Place to Pay |
responseReasonText | string[255] | Motivo de respuesta de la operación en Place to Pay |
Tipos de datos o estructuras
Aquí se describen cada una de las estructuras de datos usadas por los métodos del Webservice.
Attribute
Estructura para almacenar información extendida.
Propiedades
Nombre | Tipo | Descripción |
name | string[30] | Código para referenciar el atributo |
value | string[128] | Valor que asume el atributo |
Authentication
Estructura para autenticarse con el webservice.
El login y el tranKey son dados por Place to Pay para poder realizar transacciones en nombre de un sitio de recaudo.
La semilla usada en el consumo debe ser una fecha en formato ISO 8601 (AAAA-MM-DDTHH:NN:SSZZZ, ej: 2013-04-11T08:47:21-05:00), el sistema verificará que la petición no haya expirado, por ello es fundamental una sincronización del reloj del servidor. Más adelante hay un apartado de la obtención de la semilla en el formato solicitado y la generación del Hash.
El tranKey enviado en el consumo corresponde a un hash generado con SHA1 de la concatenación de la semilla y del tranKey originalmente enviado por PlacetoPay.
Propiedades
Nombre | Tipo | Descripción |
login | string[32] | Identificador habilitado para el consumo del API, entregado por Place to Pay. |
tranKey | string[40] | Llave transaccional para el consumo del API SHA1(seed + tranKey) |
seed | string | Semilla usada para el consumo del API en el proceso del hash por SHA1 del tranKey, ISO 8601. |
additional | Attribute[] | Datos adicionales a la estructura de autenticación |
Person
Estructura para reflejar la información de una persona involucrada en una transacción
Propiedades
Nombre | Tipo | Descripción |
document | string[12] | Número de identificación de la persona |
documentType | string[3] | Tipo de documento de identificación de la persona:
CC: Cédula de ciudadanía colombiana CE: Cédula de extranjería TI: Tarjeta de identidad PPN: Pasaporte NIT: Número de identificación tributaria SSN: Social Security Number |
firstName | string[60] | Nombres |
lastName | string[60] | Apellidos |
company | string[60] | Nombre de la compañía en la cual labora o representa |
emailAddress | string[80] | Correo electrónico |
address | string[100] | Dirección postal completa |
city | string[50] | Nombre de la ciudad coincidente con la dirección |
province | string[50] | Nombre de la provincia o departamento coincidente con la dirección |
country | string[2] | Código internacional del país que aplica a la dirección física acorde a ISO 3166-1, mayúscula sostenida. |
phone | string[30] | Número de telefonía fija |
mobile | string[30] | Número de telefonía móvil o celular |
Bank
Estructura para reflejar la información de una entidad bancaria
Propiedades
Nombre | Tipo | Descripción |
bankCode | string[4] | Código de la entidad financiera |
bankName | string[60] | Nombre de la entidad financiera |
CreditConcept
Estructura que representa el concepto del crédito a favor de un tercero.
Propiedades
Nombre | Tipo | Descripción |
entityCode | string[12] | Código de la entidad del tercero para dispersión |
serviceCode | string[12] | Código del servicio del tercero |
amountValue | double | Valor total a recaudar a favor de la entidad |
taxValue | double | Discriminación del impuesto aplicado a favor de la entidad |
description | string[60] | Descripción el concepto cobrado |
Ejemplos
A continuación se muestran algunos ejemplos de generación de una fecha en formato ISO 8601 y de la generación del hash en SHA1.
Ejemplo de generación de fecha ISO 8601
A continuación se muestra como se da formato a la fecha actual para generar una cadena en ISO 8601.
$seed = date('c');
using System;
using System.Globalization;
String seed = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
import java.util.Date;
import java.text.SimpleDateFormat;
Date now = new Date();
SimpleDateFormat isoDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String seed = isoDate.format(now);
Ejemplo de generación del Hash
A continuación se presenta como se puede generar el Hash en diferentes lenguajes de programación. Este Hash es el que se remite como tranKey en la estructura de autenticación.
$hashString = sha1($seed . $tranKey, false);
using System.Text;
using System.Security.Cryptography;
private string GetSHA1(string text)
{
ASCIIEncoding UE = new ASCIIEncoding();
byte[] hashValue;
byte[] message = UE.GetBytes(text);
SHA1 hashString = new SHA1CryptoServiceProvider();
string hex = "";
hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue) {
hex += String.Format("{0:x2}", x);
}
return hex;
}
string hashString = GetSHA1(seed + tranKey);
import java.security.MessageDigest;
import java.util.Formatter;
private static String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private static String GetSHA1(String password)
{
String sha1 = "";
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(password.getBytes("UTF-8"));
sha1 = byteToHex(crypt.digest());
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
}
return sha1;
}
string hashString = GetSHA1(seed
+ tranKey);