Payment Vault
Esta página documenta detalles para integrar las el Payment Vault DEUNA en tu aplicación.
Elige tu integración
Almacena y tokeniza credenciales de pago con el Vault DEUNA.
Integra el Vault a tu solución de pagos mediante las sigientes opciones:
Vault via SDK (recomendado)
Recomendamos integrar el Payment Vault mediante nuestros SDKs, ya que ofrecen una experiencia más optimizada y simplifican la comunicación entre las aplicaciones y las páginas web. A continuación, se listan los SDKs disponibles:
En entornos web, el widget puede abrirse en un elemento HTML objetivo o mostrarse como un modal.
En aplicaciones móviles (iOS y Android), el widget se abre dentro de un WebView.
Funcionalidades
El SDK expone varios callbacks
que permiten al comercio reaccionar de forma dinámica ante eventos importantes dentro del flujo de pago, como:
- Cuando el usuario cierra el widget.
- Cuando se tokeniza exitosamente una tarjeta o credencial de pago.
- Cuando falla un intento de tokenización.
Estas funcionalidades permiten al comercio personalizar la experiencia del usuario y adaptarla según las necesidades de cada transacción.
Vault via URL / iFrame
Puedes renderizar el Payment Widget dentro de un Iframe o en un tab completo como redirect, en caso de que no puedas usar los SDKs.
Para integrar el Payment Vaultpor URL o iFrame, ve a Vault via URL / iFrame.
Información adicional
Conoce más acerca de la integración del Payment Vault:
- Verificación del tipo de evento y marca de la tarjeta: El Vault reconoce la marca de tarjetas a partir de metadata de eventos.
- Aplicación de descuento si la tarjeta es Mastercard por el comercio: Si la marca de la tarjeta es 'mastercard', se aplica un descuento del 20% al carrito de compras actual. Esta acción es realizada 100% por tu aplicación.
- Actualización de la orden: Después de aplicar un descuento, tu aplicación es responsable de actualizar la orden utilizando el endpoint Actualizar Orden de DEUNA.
- Notificación al widget para actualizar la orden e installments: Los cambios de estatus de una orden se comunican mediante el método
postMessage
.- El método
postMessage
envía un mensaje al widget indicando que pasos a seguir dependiendo de la lógica de negocio. - Se debe incluir un objeto con el tipo '
refetchOrder
' y con un valor dedata
igual anull
.
- El método
- Mostrar un tag promocional: Además de actualizar la orden y las cuotas de pago, es posible aplicar un estilo CSS personalizado mediante la función getCustomCSS(cardBrand) al widget.
Procesar un pago con un card_id
o credential de pago
card_id
o credential de pagoCuando un proceso de pago se inicia en el backend de tu aplicación, debes configurar el pago con un card_id
para finalizar la compra.
Debes integrar los endpoints de Pagos para obtener los
card_id
.
Este proceso requiere solicitudes específicas al endpoint de la API de Pagos para concluir la transacción.
Ejemplo de solicitud curl
const requestBody = {
payer_info: {
email: "[email protected]"
},
payment_source: {
method_type: "credit_card",
card_info: {
card_id: "8d369b6e-113a-4640-9e63-dc29957fc86aza",
installment: {
plan_option_id: "<uuid que se retorna en el postMessage 'onInstallmentSelected'>"
}
}
},
// ... Resto del body
};
fetch('https://api.sandbox.deuna.io/v2/merchants/orders/purchase', {
method: 'POST',
headers: {
'x-api-key': '<YOUR_PRIVATE_API_KEY>',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl --location 'https://api.sandbox.deuna.io/v2/merchants/orders/purchase' \
--header 'x-api-key: YOUR_PRIVATE_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"payer_info": {
"email": "[email protected]"
},
"payment_source": {
"method_type": "credit_card",
"card_info": {
"card_id": "8d369b6e-113a-4640-9e63-dc29957fc86aza"
}
},
"order": {
"order_id": "testapi-0003",
"currency": "MXN",
"items": [
{
"id": "216",
"name": "10 Cellphones",
"description": "",
"options": "string option",
"total_amount": {
"original_amount": 2000,
"amount": 2000,
"currency": "MXN",
"currency_symbol": "$"
},
"unit_price": {
"amount": 200,
"currency": "MXN",
"currency_symbol": "$"
},
"tax_amount": {
"amount": 0,
"currency": "MXN",
"currency_symbol": "$"
},
"quantity": 1,
"uom": "string",
"upc": "string",
"sku": "",
"isbn": "",
"brand": "",
"manufacturer": "",
"category": "",
"color": "",
"size": "",
"weight": {
"amount": 0,
"unit": "kg"
},
"image_url": "https://images-staging.getduna.com/95463fb5-6279-4ec3-8ff9-fe07aacd2142/db5b698c57654116_domicilio_216_750x750_1662162887.png?d=200x200&format=webp",
"details_url": "",
"type": "physcal",
"taxable": true
}
],
"sub_total": 2000,
"total_amount": 2000,
"store_code": "all",
"billing_address": {
"address1": "presa angostura 36PH",
"address2": "",
"address_type": "home",
"city": "CDMX",
"country_code": "MX",
"email": "[email protected]",
"first_name": "efren",
"identity_document": "162915134",
"is_default": true,
"last_name": "garcia",
"phone": "+525222222222",
"state_code": "MX",
"state_name": "miguel hidalgo",
"zipcode": "11500"
}
}
}'
$curl = curl_init();
$requestBody = json_encode(array(
"payer_info" => array(
"email" => "[email protected]"
),
"payment_source" => array(
"method_type" => "credit_card",
"card_info" => array(
"card_id" => "8d369b6e-113a-4640-9e63-dc29957fc86aza"
)
),
// Aquí puedes continuar añadiendo el resto del cuerpo de la solicitud
"order" => array(
"order_id" => "testapi-0003",
"currency" => "MXN",
"items" => array(
// Aquí van los detalles de los items
),
// Continúa con el resto de los detalles del pedido
)
));
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $requestBody, // Aquí se utiliza la variable
CURLOPT_HTTPHEADER => array(
"x-api-key: YOUR_PRIVATE_API_KEY", // Asegúrate de reemplazar con tu API key real
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
require 'uri'
require 'net/http'
require 'json'
url = URI("https://api.sandbox.deuna.io/v2/merchants/orders/purchase")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request_body = {
payer_info: {
email: "[email protected]"
},
payment_source: {
method_type: "credit_card",
card_info: {
card_id: "8d369b6e-113a-4640-9e63-dc29957fc86aza"
}
}
# ... Agrega aquí el resto del cuerpo de la solicitud
}.to_json
request = Net::HTTP::Post.new(url)
request["x-api-key"] = "YOUR_PRIVATE_API_KEY" # Reemplaza con tu API key
request["Content-Type"] = "application/json"
request.body = request_body
response = http.request(request)
puts response.read_body
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import org.json.JSONObject;
public class Main {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
JSONObject requestBody = new JSONObject()
.put("payer_info", new JSONObject().put("email", "[email protected]"))
.put("payment_source", new JSONObject()
.put("method_type", "credit_card")
.put("card_info", new JSONObject().put("card_id", "8d369b6e-113a-4640-9e63-dc29957fc86aza")))
// ... Agrega aquí el resto del cuerpo de la solicitud
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/v2/merchants/orders/purchase"))
.header("x-api-key", "YOUR_PRIVATE_API_KEY") // Reemplaza con tu API key
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody.toString()))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
Ver el API reference
Para revisar en detalle el endpoint te recomendamos ir a realizar pago de orden
Demo de experiencia
Después de integrar el Payment Vault la experiencia es similar al siguiente demo:

Updated 9 days ago