Generación de nuevas transacciones con cardToken:
Para generar nuevas transacciones utilizando los datos guardados como el cardToken, se debe realizar una solicitud HTTP POST:
API transaction/web
URL de la solicitud POST
https://pay.payphonetodoesposible.com/api/transaction/web
Cabeceras Requeridas:
Authorization: bearer TU_TOKEN
(Esta cabecera debe contener el token de autenticación de tu aplicación, precedido por la palabra “Bearer”. Este token es el mismo que utilizaste al preparar la transacción inicialmente).Content-type: application/json
(Indica que el formato de los datos enviados en el cuerpo de la solicitud es JSON).
Estructura del Cuerpo de la Solicitud:
El cuerpo de la solicitud debe ser un objeto JSON que incluya los datos del titular de la tarjeta (cardToken,
cardHolder, email, documentId, phoneNumber
), montos y demás información para la nueva transacción
{
"cardHolder": "{{cardHolder}}",
"cardToken": "{{ctoken_user}}",
"documentId": "1234567890",
"phoneNumber": "593999999999",
"email": "aloy@mail.com",
"amount": 315,
"amountWithoutTax": 315,
"amountWithTax": 0,
"tax": 0,
"service": null,
"tip": null,
"clientTransactionId": "ID_UNICO_X_TRX-101",
"currency": "USD",
"storeId": "your_storeId",
"optionalParameter": "Concepto o motivo de cobro",
"order": {
"billTo": {
"billToId": 12,
"address1": "Colorado Springs",
"address2": "Denver",
"country": "EC",
"state": "Azuay",
"locality": "Cuenca",
"firstName": "Elisabeth",
"lastName": "Sobeck",
"phoneNumber": "+593999999999",
"email": "aloy@mail.com",
"postalCode": "010202",
"ipAddress": "127.0.0.1"
},
"lineItems": [
{
"productName": "Producto Vendido",
"unitPrice": 100,
"quantity": 1,
"totalAmount": 115,
"taxAmount": 15,
"productSKU": "SKU-4242.0001",
"productDescription": "DETALLE PRODUCTO"
},
{
"productName": "Servicio Entregado",
"unitPrice": 100,
"quantity": 2,
"totalAmount": 200,
"taxAmount": 0,
"productSKU": "SKU-4242.0001",
"productDescription": "DETALLE SERVICIO"
}
]
}
}
Importante:
*Cálculo del amount
:
Recuerda que el campo amount
(valor a cobrar) debe ser la suma de los campos amountWithTax
, amountWithoutTax
, tax
, service
y tip
.
amount = amountWithoutTax + amountWithTax + tax + service + tip
Aunque los montos individuales son opcionales, al menos uno debe estar presente para respaldar el campo amount
*Valores Monetarios:
Todos los valores monetarios deben expresarse en enteros. Es decir, se multiplica el valor en dólares por 100. Por ejemplo:
$1 dólar = 100
$1.50 dólares = 150
$10 dólares = 1000
$12.68 dólares = 1268
Descripción de parámetros en la petición
A continuación se detallan todos los parámetros que se pueden usar para una transacción como montos a cobra, moneda, datos del cliente y otros campos que puedes enviar.
Nombre y apellido del titular de la tarjeta codificado en AES 256 CBC sin vector de inicialización
cToken de tarjeta obtenido del pago aprobado desde botón de pago.
Valor total a cobrar.
Debe ser igual a la suma de todos los montos individuales ( amountWithoutTax, amountWithTax, Tax, service y tip ).
Monto que no está sujeto a impuestos.
Monto que incluye el valor sujeto a impuestos, excluyendo el propio impuesto.
Monto del impuesto aplicado a la transacción.
Monto asociado al servicio proporcionado.
Monto de la propina otorgada por el cliente.
Código de moneda ISO 4217. (ej:USD)
Identificador único asignado a la transacción para su seguimiento.
Identificador de la sucursal que efectúa el cobro (se obtiene en Payphone Developer).
Motivo o referencia específica del pago.
Número de teléfono del titular. Obtenido en la confirmación de transacción.
Formato: Código País + numero telefónico.
Ej. 593984111222
Correo electrónico del cliente; se solicitará si no se proporciona.
Número de identificación del cliente; se solicitará si no se proporciona.
Arreglos con datos de facturación y detalle de artículos o servicios.
Advertencia:
Al utilizar los campos phoneNumber
, email
y documentId
, en las solicitudes a los servicios de Payphone, es crucial que se ingresen los datos del titular de la tarjeta que se obtuvo de la confirmación para cada transacción individual. No se permite el uso de datos "quemados" o estáticos, ya que esto puede resultar en el rechazo de sus transacciones y el bloqueo de sus usuarios. El uso de datos falsos o repetitivos puede generar sospechas de fraude.
El campo Order
es obligatorio en las solicitudes a los servicios de Payphone.
Payphone se compromete a proteger la seguridad y privacidad de los datos, por lo que es fundamental cumplir con esta política para garantizar un proceso de pago seguro y confiable.
Descripción de campo ORDER
El campo order se divide en dos arreglos: BillTo, LineItems
BillTo:
El campo billTo es un arreglo que contiene información de facturación
Identificador para los datos de facturación (Opcional)
Dirección de facturación 1
Dirección de facturación 2
El código de país según la norma ISO 3166-1 alfa-2.
(EJ: EC)
Número de teléfono del titular.
Formato: Símbolo(+) + Código País + numero telefónico.
Ej. +593984111222
Correo electrónico del titular.
Código Postal: dirección numérica de un lugar específico.
Identificador del cliente otorgada por el comercio
Dirección IP del dispositivo
LineItems:
El campo lineItems es un conjunto de arreglos que contiene la información de los servicios o productos entregados
Nombre del producto o servicio
Total a pagar por este servicio
Identificador del producto o servicio
Descripcion corta del producto
Respuesta de solicitud
El resultado de una transacción exitosa incluirá el token de la tarjeta, el código de autorización, y otros detalles relevantes de la transacción
{
"cardToken": "ctoken_user",
"authorizationCode": "W46191086",
"messageCode": 0,
"status": "Approved",
"statusCode": 3,
"transactionId": 46191086,
"clientTransactionId": "TOK2025-02-07T22:33:50.471Z",
"currencyCode": "USD"
}
Descripción de parámetros de respuesta
Una vez la llamada es satisfactoria obtendrás un JSON con los siguientes parámetros:
Código de estado de la transacción.
2 = Cancelado
3 = Aprobada
Estado de la transacción (Approved o Canceled).
Identificador de transacción que enviaste en la petición.
Código de autorización bancario.
Identificador de transacción asignado por Payphone.
Mensaje de error, si corresponde
cToken de tarjeta obtenido del pago aprobado desde botón de pago.
Moneda utilizada para el pago.
Ejemplos de solicitudes POST al api transaction/web
A continuación, se presenta varios ejemplos de cómo realizar solicitudes POST:
<?php
//token de tarjeta obtenido de url de respuesta "ctoken"
$cardToken = "ctoken_user";
//datos del titular obtenidos de la confirmacion de la transaccion
$documentId = "1234567890";
$phoneNumber = "593999999999";
$email = "aloy@mail.com";
//Nombre del titular
$userName="Elisabeth Sobeck";
//ejecutar funcion de encriptacion para obtener cardHolder
$cardHolder=encrypt($userName);
//separar nombre en un arreglo
$arrayName = explode(" ", $userName);
//Genera Dato Unico por transaccion
$clientTransactionID = substr((date("ymd-Hi-s").gettimeofday()["usec"]),0, 16);
//funcion de encriptacion en AES 256 CBC sin vector de inicializacion
function encrypt($optionalParameter4) {
error_reporting(E_ERROR | E_PARSE | E_NOTICE);
$encrypted = base64_encode(openssl_encrypt($optionalParameter4,'AES-256-CBC',"your_coding_password",OPENSSL_RAW_DATA,""));
error_reporting(E_ALL);
return $encrypted;
}
//Preparar cabecera para la solicitud
$headers[] = 'Authorization: Bearer your_token' ;//CREDENCIALES DE CONFIGURACION
$headers[] = 'Content-Type: application/json' ;//TIPO DE APLICACION
//Preparar objeto JSON para solicitud
$data = array(
"cardHolder"=> $cardHolder,
"cardToken"=> $cardToken,
"documentId"=> $documentId,
"phoneNumber"=> $phoneNumber,
"email"=> $email,
"amount"=> 315,
"amountWithoutTax"=> 315,
"clientTransactionId"=> $clientTransactionID,
"currency"=> "USD",
"storeId"=> "your_storeId",
"optionalParameter"=> "Concepto o motivo de cobro",
"order"=> array(
"billTo"=> array(
"billToId"=> 12,
"address1"=> "Colorado Springs",
"address2"=> "Denver",
"country"=> "EC",
"state"=> "Azuay",
"locality"=> "Cuenca",
"firstName"=> $arrayName[0],
"lastName"=> $arrayName[1],
"phoneNumber"=> "+".$phoneNumber,
"email"=> $email,
"postalCode"=> "010202",
"ipAddress"=> "127.0.0.1"
),
"lineItems"=> array(
array(
"productName"=> "Producto o Servicio entregado",
"unitPrice"=> 315,
"quantity"=> 1,
"totalAmount"=> 115,
"taxAmount"=> 0,
"productSKU"=> "SKU-4242.0001",
"productDescription"=> "DETALLE PRODUCTO"
)
)
)
);
$objetoJSON = json_encode($data);
//Iniciar solicitud curl: POST
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://pay.payphonetodoesposible.com/api/transaction/web");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $objetoJSON);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//Respuesta en formato JSON
$curl_response = curl_exec($curl);
//Finaliza solicitud curl: POST
curl_close($curl);
//Mostrar Resultado en Pantalla
echo "<h1>Prueba de Transaccion con tokenizacion</h1> <br>";
echo "Cuerpo Solicitud : <pre>".json_encode($data,JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT )."</pre>";
$result= json_decode($curl_response);
echo "Respuesta : <pre>".json_encode($result,JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT )."</pre>";
?>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Confirmacion con jQuery</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
</head>
<body>
<h1>Prueba de Transaccion con tokenizacion</h1>
<div><a>Respuesta : <strong id="result"></strong></a></div>
<script>
//funcion que encripta en AES 256 CBC sin vector de inicializacion
function encrypted_aes(optionalParameter4) {
var key = CryptoJS.enc.Utf8.parse('your_coding_password');
var iv = CryptoJS.enc.Utf8.parse('');
var encrypted = CryptoJS.AES.encrypt(optionalParameter4, key,{ iv: iv });
var result_aes = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
return result_aes;
}
//token de tarjeta obtenido de url de respuesta "ctoken"
const cardToken = "ctoken_user";
//datos del titular obtenidos de la confirmacion de la transaccion
const documentId = "1234567890";
const phoneNumber = "593999999999";
const email = "aloy@mail.com";
//Nombre del titular
const userName="Elisabeth Sobeck";
//ejecutar funcion de encriptacion para obtener cardHolder
const cardHolder=encrypted_aes(userName) ;
//separar nombre en un arreglo
const arrayName = userName.split(" ");
//Genera Dato Unico por transaccion
const clientTransactionID = Date.now();
$(document).ready(function() {
$.ajax({
url: "https://pay.payphonetodoesposible.com/api/transaction/web",
type: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer your_token"
},
data: JSON.stringify({
"cardHolder": cardHolder,
"cardToken": cardToken,
"documentId": documentId,
"phoneNumber": phoneNumber,
"email": email,
"amount": 200,
"amountWithoutTax": 200,
"clientTransactionId": clientTransactionID,
"currency": "USD",
"storeId": "your_storeId",
"optionalParameter": "Concepto o motivo de cobro",
"order": {
"billTo": {
"address1": "Colorado Springs",
"address2": "Denver",
"country": "EC",
"state": "Azuay",
"locality": "Cuenca",
"firstName": arrayName[0],
"lastName": arrayName[1],
"phoneNumber": "+"+phoneNumber,
"email": email,
"postalCode": "010202",
"ipAddress": "127.0.0.1"
},
"lineItems": [
{
"productName": "Producto o Servicio entregado",
"unitPrice": 200,
"quantity": 1,
"totalAmount": 200,
"taxAmount": 0,
"productSKU": "SKU-4242.0001",
"productDescription": "DETALLE PRODUCTO"
}
]
}
}),
success: function(response) {
$("#result").html(
"<pre>" + JSON.stringify(response, null, 2) + "</pre>"
);
},
error: function(error) {
$("#result").html(
"Error en la solicitud : <pre>" + JSON.stringify(error, null, 2) + "</pre>"
);
}
});
});
</script>
</body>
</html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Tokenizacion con Fetch</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
</head>
<body>
<h1>Transaccion con Tokenizacion con Fetch</h1>
<div><a>Cuerpo : <pre id="data"></pre></a></div>
<div><a>Respuesta : </a></div>
<script>
//funcion que encripta en AES 256 CBC sin vector de inicializacion
function encrypted_aes(optionalParameter4) {
var key = CryptoJS.enc.Utf8.parse('your_coding_password');
var iv = CryptoJS.enc.Utf8.parse('');
var encrypted = CryptoJS.AES.encrypt(optionalParameter4, key,{ iv: iv });
var result_aes = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
return result_aes;
}
//token de tarjeta obtenido de url de respuesta "ctoken"
const cardToken = "ctoken_user";
//datos del titular obtenidos de la confirmacion de la transaccion
const documentId = "1234567890";
const phoneNumber = "593999999999";
const email = "aloy@mail.com";
//Nombre del titular
const userName="Elisabeth Sobeck";
//ejecutar funcion de encriptacion para obtener cardHolder
const cardHolder=encrypted_aes(userName) ;
//separar nombre en un arreglo
const arrayName = userName.split(" ");
//Genera Dato Unico por transaccion
const clientTransactionID = Date.now();
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer your_token",
"Referer": document.referrer
};
const bodyJSON = {
"cardHolder": cardHolder,
"cardToken": cardToken,
"documentId": documentId,
"phoneNumber": phoneNumber,
"email": email,
"amount": 200,
"amountWithoutTax": 200,
"clientTransactionId": clientTransactionID,
"currency": "USD",
"storeId": "your_storeId",
"optionalParameter": "Concepto o motivo de cobro",
"order": {
"billTo": {
"address1": "Colorado Springs",
"address2": "Denver",
"country": "EC",
"state": "Azuay",
"locality": "Cuenca",
"firstName": arrayName[0],
"lastName": arrayName[1],
"phoneNumber": "+"+phoneNumber,
"email": email,
"postalCode": "010202",
"ipAddress": "127.0.0.1"
},
"lineItems": [
{
"productName": "Producto o Servicio entregado",
"unitPrice": 200,
"quantity": 1,
"totalAmount": 200,
"taxAmount": 0,
"productSKU": "SKU-4242.0001",
"productDescription": "DETALLE PRODUCTO"
}
]
}
};
document.getElementById("data").innerHTML=JSON.stringify(bodyJSON, null, 2);
const url = "https://pay.payphonetodoesposible.com/api/transaction/web";
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(bodyJSON)
})
.then((res) => res.json())
.catch((error) => {
// Creamos las etiquetas <a>
const jsonResult = document.createElement("pre");
jsonResult.textContent = JSON.stringify(error, null, 2);
// Mostrar los enlaces en el documento con un salto de línea entre ellos
const container = document.createElement("div");
container.appendChild(jsonResult);
// Agregar los enlaces al body del documento o a un contenedor específico
document.body.appendChild(container);
})
.then((data) => {
// Creamos las etiquetas <a>
const jsonResult = document.createElement("pre");
jsonResult.textContent = JSON.stringify(data, null, 2);
// Mostrar los enlaces en el documento con un salto de línea entre ellos
const container = document.createElement("div");
container.appendChild(jsonResult);
// Agregar los enlaces al body del documento o a un contenedor específico
document.body.appendChild(container);
});
</script>
</body>
</html>
¡Y eso es todo! Si has llegado a este punto, ¡felicidades! Tu integración está completada. En la siguiente sección, te explicaremos cómo realizar pruebas y pasar a producción.