🔧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
(Token de autenticación de la aplicación, precedido por la palabra "Bearer". Este token es el mismo que utilizaste al preparar la transacción inicialmente).Content-type: application/json
(Formato de los datos: 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 monto total (amount
)
El campo amount
debe ser la suma de todos los valores monetarios
amount = amountWithoutTax + amountWithTax + tax + service + tip
Aunque los campos individuales son opcionales, debe haber al menos uno presente que respalde el valor total amount
💵 Valores monetarios en centavos:
Todos los montos deben expresarse como enteros. Multiplica el valor en dólares por 100:
💵 Valor en USD |
🪙 Valor en centavos |
$ 1.00 |
100 |
$ 1.50 |
150 |
$ 10.00 |
1000 |
$ 12.68 |
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 de Tokenizacion 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.
📋 Desglose del campo order
El campo order se divide en dos arreglos: BillTo, LineItems
🧾BillTo (Datos de facturación):
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 (Detalle del pedido):
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
date_default_timezone_set('America/Guayaquil');
//Funcion q ejecuta una solicitud http POST
function curlPost($urlAPI, $headers,$body) {
//Iniciar solicitud curl: POST
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $urlAPI);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$curl_response = curl_exec($curl);
//Finaliza solicitud curl: POST
curl_close($curl);
//Respuesta en formato JSON
return json_decode($curl_response);
}
// funcion de encriptacion en AES 256 CBC sin vector de inicializacion
function encrypt($objet) {
error_reporting(E_ERROR | E_PARSE | E_NOTICE);
$encrypted = base64_encode(openssl_encrypt($objet,'AES-256-CBC',"your_codingPassword",OPENSSL_RAW_DATA,""));
error_reporting(E_ALL);
return $encrypted;
}
/*## Preparar credenciales como variables para la solicitud ##*/
$token="your_token";
$storeId = "your_storeID";
//INFORMACION DE TARJETA Y DATOS DE USUARIO
//token de tarjeta "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);
/*## Preparar informacion para la solicitud POST ##*/
//URL del servicio payphone
$url="https://pay.payphonetodoesposible.com/api/transaction/web";
//Preparar cabecera para la solicitud
$headers[] = 'Authorization: Bearer '.$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"=> $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"
)
)
)
);
$bodyJSON = json_encode($data);
//realizar solicitud http POST
$result=curlPost($url, $headers,$bodyJSON);
//Mostrar Resultado en Pantalla
echo "<h1>🧩 Prueba de Transaccion con tokenizacion</h1> <br>";
echo "🔗 POST: <pre>".$url."</pre>";
echo "📦 Cuerpo Solicitud : <pre>".json_encode($data,JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT )."</pre>";
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.