Nuestra API es la solución que te permite integrar tu solución de comercio digital a través de un canal seguro y se adapta a las necesidades del comercio para realizar operaciones bancarias como pagos, cancelaciones, preautorizaciones y postautorizaciones; así como consultar el estatus de las transacciones, generación de Payment URL y completa personalización de la experiencia al comprador.
¡Listo, has decidido que API REST es la solución para tu comercio! A continuación, los pasos a seguir:
La integración con REST API sugiere utilizar una arquitectura MVC (Modelo-Vista-Controlador). Es importante construir las peticiones HTTP utilizando un lenguaje de servidor como PHP en el controlador de la vista y no hacerlas desde el frontend, ya que esto se considera como una práctica insegura.
El proceso general para realizar una petición HTTP siguiendo MVC dentro de un sitio web consiste en:
Para realizar cualquier transacción deberemos incluir los siguientes Headers en nuestra petición HTTP de la siguiente forma:
Nombre del parámetro | Definición | Valor/Ejemplo |
---|---|---|
Content-Type |
| application/json |
Request-Id | Identificador de la petición, se sugiere usar el formato UUID V4, universally unique identifier (UUID) de 128 bits hay diferentes librerías dependiendo el lenguaje de programación que utilicemos que nos podrían ayudar con esta tarea. | 11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000 |
Api-Key | Valor de tu API KEY | tOqWgOZAFq6aAYpqyQtAGVkjfo2Qp3 |
Timestamp | Valor del tiempo EPOCH en el que se construye la petición. | 1650590066714 |
Client- Nombre del parámetro | Definición | Valor/Ejemplo |
MessageSignature | Valor de la firma obtenida para el cuerpo de cada petición. Consulta el procedimiento para generarla. | GJOCzEMi2p0fW8s0xEK+tM/vsgAG/O/P+gwAXdXGa8Q= |
Headers HTTP |
Para cada una de las solicitudes HTTP que enviemos es necesario generar un Hash (Message-Signature) que utiliza nuestro servidor para validar la autenticidad e integridad del mensaje. Este hash es enviado en el header dentro de la petición HTTP como Message-Signature. Detalles
Algoritmo: HMAC SHA256
Encoding: Base64
Firmado con: "API SECRET" provista al comercio por parte de fiserv
Paso 1 - Generar una cadena de texto con la siguiente estructura msgSignatureString = API_KEY + CLIENT_REQUEST_ID + TIMESTAMP + PAYLOAD.
En donde:
Payload original | Payload a enviar (serializado) |
---|---|
{ “name”: ”Fiserv”, “Jaime Balmes 11D” } | {“name”:”Fiserv”,“location”:“Jaime Balmes 11D”} “location”: |
Paso 2 - Firmar la cadena resultante usando el algoritmo HMAC SHA256 y utilizando como llave tu API SECRET.
strHash = HmacSHA256( msgSignatureString, API SECRET )
Paso 3 - Obtener la representación en base64 de la cadena resultante del paso anterior. El resultado de esto es lo que incluiremos como valor en el header Message-Signature de nuestra petición.
b64Hash = strToBase64 (strHash)
3D Secure es la nueva forma de autenticar pagos desarrollada por las marcas que posibilita la realización de compras seguras en Internet y autentifica al comprador como legítimo titular de la tarjeta que se está utilizando.
De esta manera se garantiza la total seguridad en las transacciones.
Existen algunas peticiones que no necesitan pasar por este flujo, como lo son: las transacciones recurrentes MIT (Merchant Initiated Transactions), generación de tokens, generación de paymentURL y postautorizaciones.
Sin embargo, la MAYORÍA de las transacciones que realicemos por default necesitan pasar por el flujo de 3DSecure en nuestras tiendas, por ejemplo: ventas directas, ventas a MSI, ventas con token, recurrencias programadas, preautorizaciones, etc. Es decir, todas las transacciones con los siguientes requestType, pasan por 3DS.
Por ello es importante que comprendamos el flujo de las transacciones con 3Dsecure. A continuación, el diagrama de un flujo de autenticación 3DS. Para mayor información, ver la narrativa de cada uno de los procesos según el número informado sobre la figura.
1. Primary Transaction se refiere a la transacción inicial donde, dentro del payload podremos encontrar el tipo de operativa que se quiere realizar (venta directa, venta msi, etc.) y la información del tarjetahabiente. Esta petición inicial siempre deberá incluir el objeto authenticationRequest y deberá contener los siguientes parámetros:
Parámetros | Descripción |
---|---|
authenticationType | Protocolo solicitado para la autenticación. Deberá ser establecido con el valor Secure3DAuthenticationRequest |
termURL | Es la url de callback en donde se reciben los resultados del proceso de autenticación desde el servidor ACS (Access Control Server) quien se encarga de ejecutar la autenticación del tarjetahabiente. |
methodNotificationURL | Se utiliza para recibir una notificación cuando el formulario 3DSMethod sea completado, por medio de un POST http a una url definida. La URL deberá ser única y capaz de identificar la transacción a la que pertenece. Adicionalmente es posible enviar la referencia de la transacción dentro de la URL como un parámetro GET (queryString). Ejemplo: https://www.mywebshop.com/process3dSecureMethod?reference=12345612352 |
challengeIndicator | En caso de tener alguna preferencia sobre el flujo de autenticación a seguir, puedes anexar este parámetro opcional con alguno de los valores enlistados a continuación. En caso de no enviarlo, el valor predeterminado será seteado en “01” – No preference. “01” = No preference (No tienes preferencia sobre el flujo) “02” = No challenge requested (Prefieres no solicitar challenge) “03” = Challenge requested: 3DS Requestor Preference (Prefieres que se solicite challenge) “04” = Challenge requested: Mandate (Existen algunas regiones en donde es obligatorio el uso de challenge) |
challengeWindowSize | Puedes anexar este parámetro si deseas establecer el tamaño de la ventana de autenticación mostrada al tarjetahabiente durante la autenticación. Los valores posibles por enviar son.
|
Es recomendable proporcionar los datos de facturación y envío dentro de la transacción para reducir el riesgo de rechazos por autenticación. Para realizar esto, asegúrate de proporcionar los datos dentro de tu petición de venta.
El siguiente JSON representa una transacción de venta con los requerimientos mínimos:
{
"requestType": "PaymentCardSaleTransaction",
"transactionAmount": {
"total": "122.04",
"currency": "MXN"
},
"paymentMethod": {
"paymentCard": {
"number": "403587XXXXXX4977",
"securityCode": "977",
"expiryDate": {
"month": "12",
"year": "24"
}
}
},
"authenticationRequest": {
"authenticationType": "Secure3DAuthenticationRequest",
"termURL": "https://www.mywebshop.com/process3dSecure",
"methodNotificationURL": "https://www.mywebshop.com/process3dSecureMethodNotification? transactionReferenceNumber=ffffffff-ba0b-539f-8000-016b2343ad7e",
"challengeIndicator": "01", "challengeWindowSize": "01"
}
}
2. En este paso debemos validar si la respuesta del Gateway contiene el elemento ‘3DSMethod’. No todos los emisores soportan la recolección de datos usando el formulario de 3DSMethod. Este elemento contiene un iframe que deberás incrustar en tu sitio; este no presenta ninguna interfaz gráfica y su única funcionalidad es recolectar información del usuario, ayudando a identificar potenciales transacciones fraudulentas. En caso contrario, continuaremos con el flujo con lo que se indica en el paso 6.
A continuación, se muestra un JSON de respuesta con este formato:
{
"clientRequestId": "30dd879c-ee2f-11db-8314-0800200c9a66",
"apiTraceId": "rrt-0c80a3403e2c2def0-d-ea-28805-6810951-2",
"ipgTransactionId": "838916029301",
"transactionType": "SALE",
"transactionTime": 1518811817,
"approvedAmount": {
"total": 122.04,
"currency": "USD"
},
"transactionStatus": "WAITING",
"authenticationResponse": {
"type": "3D_SECURE",
"version": "2.1",
"secure3dMethod": {
"methodForm": "<!DOCTYPE iframe SYSTEM "about:legacy-compat">
<iframe id="tdsMmethodTgtFrame" name="tdsMmethodTgtFrame"
style="width: 1px; height: 1px; display: none;" src="javascript:false;"
xmlns="http://www.w3.org/1999/xhtml">
<!--.--> </iframe><form id="tdsMmethodForm"
name="tdsMmethodForm"
action=https://localhost.modirum.com:8543/dstests/ACSEmu2
method="post"
target="tdsMmethodTgtFrame" xmlns="http://www.w3.org/1999/xhtml">
<input type="hidden" name="3DSMethodData"
value="eyAidGhyZWVEU1NlcnZlclRyYW5zSUQiIDogIjAwMDAwMDAwLTU2NzYtNTY2My
04MDAwLTAwMDAw &#10;MDAwNDFhOSIsICJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9
uVVJMIiA6ICJodHRwczovL2xvY2Fs&#10;aG9zdC5tb2RpcnVtLmNvbTo4NTQzL21kcGF5bXBpL
01lcmNoYW50U2VydmVyP21uPVkmdHhpZD0x
&#10;NjgwOSZkaWdlc3Q9aSUyQnhhUEF5NWFOcVJRbllqNmozbWFDZlFJbTdFdjJYTm
kwNnh6YmZNJTJG&#10;R3MlM0QiIH0"/> <input type="hidden"
name="threeDSMethodData"
value="eyAidGhyZWVEU1NlcnZlclRyYW5zSUQiIDogIjAwMDAwMDAwLTU2NzYtNTY2
My04MDAwLTAwMDA
w&#10;MDAwNDFhOSIsICJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIiA
6ICJodHRwczovL2xvY 2Fs&#10;aG9zdC5tb2RpcnVtLmNvbTo4NTQzL21kcGF5bXBpL01lcm
NoYW50U2VydmVyP21uPVkmdHhpZD0x&#10;NjgwOSZkaWdlc3Q9aSUyQnhhUEF5NWFOcV
JRbllqNmozbWFDZlFJbTdFdjJYTmkwNnh6YmZNJTJG&#10;R3MlM0QiIH0"/>
</form><script type="text/javascript"
xmlns="http://www.w3.org/1999/xhtml">
document.getElementById("tdsMmethodForm").submit(); </script>",
"secure3dTransId": "3ac7caa7-aa42-2663-791b-2ac05a542c4a"
}
}
}
2. Una vez hayamos incrustado el iframe y se haya mandado el formulario html indicado en la respuesta anterior, debemos validar si recibimos datos de sesión para 3ds dentro de nuestra methodNotificationURL.
3. Si recibiste la notificación con los datos de sesión de 3DS dentro de los primeros 10 segundos a la url definida en tu methodNotificationURL.
URL: https://cert.api.firstdata.com/gateway/v2/payments/{ipgTransactionId} (donde el ipgTransactionId lo obtendremos de la respuesta previa).
Payload:
{
"authenticationType": "Secure3D21AuthenticationUpdateRequest",
"storeId": "12345500000",
"methodNotificationStatus":"RECEIVED",
"securityCode":"XXX"
}
NOTA: El campo storeId no es mandatorio.
5. Si no se obtiene un iframe de respuesta en un lapso de 10 segundos, en estos escenarios no se enviará ninguna información a methodNotificationURL y el flujo deberá continuar enviando el estatus.
EXPECTED_BUT_NOT_RECEIVED
Esto se realiza enviando una petición PATCH con la siguiente información:
URL: https://cert.api.firstdata.com/gateway/v2/payments/{ipgTransactionId} (donde el ipgTransactionId lo obtendremos de la respuesta previa).
Payload:
{
"authenticationType": "Secure3D21AuthenticationUpdateRequest",
"storeId": "12345500000",
"methodNotificationStatus": "EXPECTED_BUT_NOT_RECEIVED", "securityCode":"XXX"
}
NOTA: El campo storeId no es mandatorio.
6. Una vez se haya concluido este flujo el sistema determinará el flujo de 3DS para la transacción. Cuando una transacción es considerada de bajo riesgo, es aplicado el flujo Frictionless o sin fricción. En este caso, el Gateway procederá a autorizar la transacción sin algún input adicional por parte del tarjetahabiente pasando directamente al paso 10, caso contrario seguiremos al paso 7.
7. Cuando se completa el llamado al API y el sistema detecta que se trata de un flujo con Challenge, la transacción no es autorizada de forma inmediata. En su lugar, obtendrás el estatus WAITING y los parámetros para redirigir al tarjetahabiente con el Directory Server del emisor para poder autenticar la operación:
{
"clientRequestId": "30dd879c-ee2f-11db-8314-0800200c9a66",
"apiTraceId": "rrt-0c80a3403e2c2def0-d-ea-28805-6810951-2",
"ipgTransactionId": "838916029301",
"transactionType": "SALE",
"transactionTime": 1518811817,
"approvedAmount": {
"total": 122.04,
"currency": "USD"
},
"transactionStatus": "WAITING",
"authenticationResponse": {
"type": "3D_SECURE",
"version": "2.1",
"params": {
"acsURL": "https://3ds-acs.test.modirum.com/mdpayacs/pareq",
"termURL": "https://www.mywebshop.com/process3dSecure/",
"cReq": "ewogICAiYWNzVHJhbCIgOiA...wMDAtMDAwMDAwMDA0MWE5Igp9",
"sessiondata": "50F2156E03083CA665BCB4.."
}
}
}
El campo authenticationResponse contendrá la siguiente información:
Parámetro | Descripción |
---|---|
type | 3D_SECURE |
version | 2.1.0 (3DS VERSION) |
acsURL | URL al sitio del emisor para redireccionar al tarjetahabiente y postear cReq y sessionData |
termURL | URL del comercio en donde se recibirán los resultados de autenticación |
cReq | Challenge Request: Mensaje codificado devuelto desde el ACS |
sessionData | Parámetros de sesión usados para la autenticación. Este campo no siempre es retornado |
Deberás implementar un formulario html que se envíe automáticamente dentro de tu sitio web con la información provista.
<form name="frm" method="POST" action="{value obtained on acsURL}">
<input type=”hidden” name=”creq” value=”ewogICAiYWNzVHJhbCIgOiA...wMDAtMDAwMDAwMDA0MWE5Igp9”>
<input type=”hidden” name=”threeDSSessionData” value=”50F2156E03083CA665BCB4..”>
</form>
8. Una vez enviado el POST, el comprador será redirigido a la pantalla de autenticación 3DS en donde, dependiendo de las reglas de su emisor, se autenticará mediante el mecanismo que el banco utilice, por ejemplo: ingresar token o clave.
9. Cuando se ingresa la clave correcta, el comprador será redirigido a la URL que definimos como "termURL" en el paso 1, junto con las siguientes parámetros POST
Llave | Valor |
---|---|
cRes | Cadena que contiene información cifrada, resultado de la autenticación |
Completar la transacción: deberás construir una petición PATCH para confirmar los resultados de la autenticación al Gateway. Los componentes para enviar dentro de la petición son los siguientes:
URL: https://cert.api.firstdata.com/gateway/v2/payments/{ipgTransactionId}. Donde el ipgTransactionId lo obtendremos de la respuesta previa.
{
"authenticationType": "Secure3D21AuthenticationUpdateRequest",
"storeId": "12345500000",
"billingAddress": {
"company": "Test Company", "address1": "5565 Glenridge Conn",
"address2": "Suite 123",
"city": "Atlanta",
"region": "Georgia",
"postalCode": "30342",
"country": "USA"
},
"securityCode": "123",
"acsResponse": {
"cRes": "ewogICAiYWNzUmVmZX…Fuc1N0YXR…IKfQ=="
}
}
La respuesta a esta petición deberá contener el resultado final de la autenticación:
{
"clientRequestId": "30dd879c-ee2f-11db-8314-0800200c9a66", "apiTraceId": "rrt-0c80a3403e2c2def0-d-ea-28805-6810951-2",
"ipgTransactionId": "838916029301",
"transactionType": "SALE",
"transactionTime": 1518811817,
"approvedAmount": { "total": 122.04, "currency": "USD"
},
"transactionStatus": "APPROVED",
"schemeTransactionId": "019078743804756",
"processor": {
"responseCode": "00",
"responseMessage": "APPROVED", "authorizationCode": "OK7118"
},
"secure3dResponse": {
"responseCode3dSecure": "1"
}
}
10. Mapeamos de manera correcta nuestra respuesta según la sección de Manejo de Respuestas informada en este manual.
En el caso de una venta directa utilizaremos el siguiente formato de Payload/Body en nuestra request.
{
"requestType": "PaymentCardSaleTransaction",
"transactionAmount": {
"total": "122.04",
"currency": "MXN"
},
"paymentMethod": {
"paymentCard": {
"number": "403587XXXXXX4977",
"securityCode": "977",
"expiryDate": {
"month": "12",
"year": "24"
}
}
},
"authenticationRequest": {
"authenticationType": "Secure3D21AuthenticationRequest",
"termURL": "https://www.mywebshop.com/process3dSecure",
"methodNotificationURL": "https://www.mywebshop.com/process3dSecureMethodNotification?transactionReferenceNumber=ffffffffba0b-539f-8000-016b2343ad7e",
"challengeIndicator": "01", "challengeWindowSize": "01"
}
}
Esta petición consta de cuatro objetos necesarios estos se detallan a continuación:
requestType | [string] indica el tipo de transacción a realizar "PaymentCardSaleTransasction" |
---|---|
transactionAmount | Indica el total a cobrar y el tipo de moneda
|
paymentMethod | Indica la información del método de pago
|
authenticationRequest | Indica el comportamiento que tendrá nuestra aplicación a la hora de autenticar a nuestro cliente usando 3DSecure |
Petición Venta Directa
Para una venta a meses sin intereses, será igual a una Venta Directa, solo agregaremos el objeto “order” al Payload.
{
"transactionAmount": {
"total": "100.00", "currency": "MXN"
},
"requestType": "PaymentCardSaleTransaction",
"paymentMethod": {
"paymentCard": {
"number": "5579xxxxxxxxxx12",
"securityCode": "123",
"expiryDate": {
"month": "12", "year": "22"
}
}
},
"order": {
"installmentOptions": {
"numberOfInstallments": 6
}
}
"authenticationRequest": {
"authenticationType": "Secure3D21AuthenticationRequest",
"termURL": "https://www.mywebshop.com/process3dSecure",
"methodNotificationURL": "https://www.mywebshop.com/process3dSecureMethodNotification?transactionReferenceNumber=ffffffffba0b-539f-8000-016b2343ad7e", "challengeIndicator": "01", "challengeWindowSize": "01" }
}
Para una venta pre-auth será igual a una Venta Directa solo, que en esta ocasión, el requestType será “PaymentCardPreAuthTransaction”.
{
"requestType": "PaymentCardPreAuthTransaction",
"transactionAmount": {
"total": "122.04",
"currency": "MXN"
},
"paymentMethod": {
"paymentCard": {
"number": "403587XXXXXX4977",
"securityCode": "977",
"expiryDate": {
"month": "12",
"year": "24"
}
}
},
"authenticationRequest": {
"authenticationType": "Secure3D21AuthenticationRequest",
"termURL": "https://www.mywebshop.com/process3dSecure",
"methodNotificationURL": "https://www.mywebshop.com/process3dSecureMethodNotification?transactionReferenceNumber=ffffffffba0b-539f-8000-016b2343ad7e",
"challengeIndicator": "01", "challengeWindowSize": "01"
}
}
Para el proceso de post-auth simplemente debemos apuntar a el Endpoint: https://cert.api.firstdata.com/gateway/v2/payments/84533163643
*se debe sustituir 84533163643 por el valor devuelto en ipgTransactionId de la respuesta exitosa de la Pre-Auth que vamos a autorizar.
Payload:
{
"requestType": "PostAuthTransaction",
"transactionAmount": {
"total": "120.00", "currency": "MXN"
}
}
{
"requestType": "PaymentCardPaymentTokenizationRequest",
"paymentCard": {
"number": "5579xxxxxxxxxx12",
"expiryDate": {
"month": "12",
"year": "22"
}
},
"createToken": {
"reusable": true,
"declineDuplicates": false
}
}
Para utilizar el token debemos seguir el siguiente esquema
{
"transactionAmount": {
"total": "12.04", "currency": "MXN"
},
"requestType": "PaymentTokenSaleTransaction",
"paymentMethod": {
"paymentToken": {
"value": "1235325235236",
"function": "DEBIT", "securityCode": "977"
}
},
"storedCredentials": {
"sequence": "FIRST",
"scheduled": true
}
}
{
"transactionAmount": {
"total": "15.00",
"currency": "MXN"
},
"transactionType": "SALE",
"clientLocale": {
"language": "es_MX",
"country": "MX"
}
}
Estos se caracterizan por ser iniciados por el cliente y por tener un número finito de cobros a efectuar. Es decir, los cobros dejarán de aplicarse una vez se termine el tiempo especificado.
En el caso de una venta con pagos recurrentes calendarizados será igual que una venta directa pero modificaremos el requestType:PaymentMethodPaymentSchedulesRequest y agregaremos los objetos startDate, frequency,purchaseOrderNumber ([string] número de contrato) y numberOfPayments.
{
"requestType": "PaymentMethodPaymentSchedulesRequest",
"transactionAmount": {
"total": "122.04",
"currency": "MXN"
},
"paymentMethod": {
"paymentCard": {
"number": "403587XXXXXX4977",
"securityCode": "977",
"expiryDate": {
"month": "12",
"year": "24"
}
}
},
"startDate": "2020-12-30",
"frequency": {
"every": 1,
"unit": "MONTH"
},
"purchaseOrderNumber": "123456789",
"numberOfPayments": 3
"authenticationRequest": {
"authenticationType": "Secure3D21AuthenticationRequest",
"termURL": "https://www.mywebshop.com/process3dSecure",
"methodNotificationURL": "https://www.mywebshop.com/process3dSecureMethodNotification?transactionReferenceNumber=ffffffffba0b-539f-8000-016b2343ad7e",
"challengeIndicator": "01", "challengeWindowSize": "01"
}
}
Estos se caracterizan por ser iniciados por el comercio y funcionan como una suscripción. Es decir, se continuarán efectuando los cobros hasta que el cliente explícitamente cancele el servicio.
Los cargos recurrentes iniciados por el comercio (MIT) son cobros efectuados de forma frecuente al tarjetahabiente y permiten variar el monto de cada cobro. Nuestra API permite este tipo de transacciones especificando el tipo de transacción recurrente "recurringType" FIRST (para la transacción inicial) y REPEAT (para transacciones subsecuentes).
Nota. Todas las transacciones recurrentes requieren "purchaseOrderNumber" para que sean procesadas correctamente.
Payload
{
"transactionAmount": {
"total": "20.00", "currency": "MXN"
},
"requestType": "PaymentCardSaleTransaction",
"paymentMethod": {
"paymentCard": {
"number": "5579xxxxx0012",
"expiryDate": {
"month": "01", "year": "24"
}
}
},
"order": {
"orderId":"REC09072020_1",
"additionalDetails": { "purchaseOrderNumber": "PO01"
},
"installmentOptions":{
"recurringType":"FIRST"
}
}
}
Transacción Subsecuente
{
"transactionAmount": {
"total": "2.00", "currency": "MXN"
},
"paymentMethod": {
"paymentCard": {
"number": "5579xxxxx0012",
"expiryDate": {
"month": "01", "year": "24"
}
}
},
"requestType": "PaymentCardSaleTransaction",
"order": {
"orderId": "REC09072020_2",
"additionalDetails": { "purchaseOrderNumber": "PO01"
},
"installmentOptions": {
"recurringType": "REPEAT"
}
}
}