Payment Vault
Store and tokenize payment credentials for single or future use
On this page
Tokenize payment credentials for secure reuse.
Choose a DEUNA-hosted Vault experience or a PCI-compliant API flow, receive a reusable card ID, and process future payments safely.
- Interface
- DEUNA-hosted credential entry or merchant-owned PCI-compliant capture
- Delivery model
- SDK component or customer-authorized Cards API
- Best for
- Saved cards, one-click checkout, and repeat payments
Understand the credential boundary#
The card_id returned by a supported tokenization flow is a DEUNA payment-credential reference. Its availability for a later payment depends on the customer consent, token type, merchant account, provider connection, environment, country, and operation enabled for that flow.
- Do not assume that every stored credential can move between processors or payment methods.
- Confirm network-token, account-updater, portability, recurring-use, and deletion behavior for the target account before production.
- Keep the underlying PAN, CVV, provider token, and private credentials out of your application logs and metadata.
- Store the customer, consent purpose, tokenization time, credential status, and permitted future use in your system of record.
- Support credential revocation, expiry, replacement, and customer deletion without treating a deleted token as a canceled subscription automatically.
Use the Provider capabilities catalog for published connection support and confirm account-specific credential behavior with your DEUNA Technical Account Manager.
Choose an integration method#
Payment Vault supports both DEUNA SDKs and the customer-authorized Cards API. Both methods return a DEUNA card_id; choose the method according to who owns the credential-entry experience and its Payment Card Industry Data Security Standard (PCI DSS) scope.
Integrate with the Cards API#
Use the Cards API when your application owns the card-entry experience and is prepared for the corresponding PCI DSS responsibilities. This is a customer-authorized flow: authenticate the customer, then call POST /v2/users/{user_id}/cards with that customer's Bearer token and the merchant context required by the Store a card endpoint.
:::info Supported public route
For new integrations, use only POST /v2/users/{user_id}/cards. The unversioned /users/{user_id}/cards route preserves a legacy single-card contract, while /users/{user_id}/cards/{card_id}/tokens adds a processor-specific token to an existing card and is not a card-creation endpoint. Neither route is part of the current external API catalog. See Card POST route differences.
:::
The /v2 request body is a JSON array, even when you store one card:
curl --request POST \
--url 'https://api.sandbox.deuna.io/v2/users/USER_ID/cards' \
--header 'Authorization: Bearer USER_ACCESS_TOKEN' \
--header 'X-Merchant-ID: MERCHANT_ID' \
--header 'Content-Type: application/json' \
--data '[
{
"card_holder": "Jane Doe",
"card_number": "CARD_NUMBER",
"card_cvv": "CARD_CVV",
"expiry_month": "12",
"expiry_year": "2029",
"is_default": true
}
]'const response = await fetch("https://api.sandbox.deuna.io/v2/users/USER_ID/cards", {
method: "POST",
headers: {
"Authorization": "Bearer USER_ACCESS_TOKEN",
"X-Merchant-ID": "MERCHANT_ID",
"Content-Type": "application/json"
},
body: JSON.stringify([
{
"card_holder": "Jane Doe",
"card_number": "CARD_NUMBER",
"card_cvv": "CARD_CVV",
"expiry_month": "12",
"expiry_year": "2029",
"is_default": true
}
])
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"POST",
"https://api.sandbox.deuna.io/v2/users/USER_ID/cards",
headers={
"Authorization": "Bearer USER_ACCESS_TOKEN",
"X-Merchant-ID": "MERCHANT_ID",
"Content-Type": "application/json"
},
json=[
{
"card_holder": "Jane Doe",
"card_number": "CARD_NUMBER",
"card_cvv": "CARD_CVV",
"expiry_month": "12",
"expiry_year": "2029",
"is_default": True
}
],
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/v2/users/USER_ID/cards",
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer USER_ACCESS_TOKEN",
"X-Merchant-ID: MERCHANT_ID",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
[
"card_holder" => "Jane Doe",
"card_number" => "CARD_NUMBER",
"card_cvv" => "CARD_CVV",
"expiry_month" => "12",
"expiry_year" => "2029",
"is_default" => true
]
])
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/v2/users/USER_ID/cards"))
.header("Authorization", "Bearer USER_ACCESS_TOKEN")
.header("X-Merchant-ID", "MERCHANT_ID")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("[\n {\n \"card_holder\": \"Jane Doe\",\n \"card_number\": \"CARD_NUMBER\",\n \"card_cvv\": \"CARD_CVV\",\n \"expiry_month\": \"12\",\n \"expiry_year\": \"2029\",\n \"is_default\": true\n }\n ]"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("POST", "https://api.sandbox.deuna.io/v2/users/USER_ID/cards", strings.NewReader("[\n {\n \"card_holder\": \"Jane Doe\",\n \"card_number\": \"CARD_NUMBER\",\n \"card_cvv\": \"CARD_CVV\",\n \"expiry_month\": \"12\",\n \"expiry_year\": \"2029\",\n \"is_default\": true\n }\n ]"))
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer USER_ACCESS_TOKEN")
request.Header.Set("X-Merchant-ID", "MERCHANT_ID")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}A successful request returns HTTP 201 Created. Store the returned data[].id as the card_id; never store the submitted PAN or CVV.
{
"data": [
{
"id": "8b5d0b45-e34f-4fd3-8cb5-79a7041f86ec",
"company": "visa",
"last_four": "4242",
"expiration_date": "12/29"
}
]
}After a timeout or an ambiguous response, check List stored cards before resubmitting the card. The Gateway contract does not advertise an idempotency header for this operation, so clients must not assume that a retry is idempotent. Verification metadata can be absent until DEUNA verifies the credential; see Card verification metadata.
Integrate with a DEUNA SDK#
The integration of the Payment Vault is through DEUNA's SDKs.
In web environments, the widget can be opened in a target HTML element or displayed as a modal.
Choose your SDK platform:
Features
- The SDK exposes several callbacks that allow the merchant to react dynamically to important events within the payment flow, such as:
- When the user closes the widget.
- When a card or payment credential is successfully tokenized.
- When a tokenization attempt fails.
- The Payment Vault can be rendered embedded or as a modal.
Additional information
Learn more about Payment Vault integration:
- Verifying event type and card brand: The Vault recognizes card brands from event metadata.
- Discount applied if the card is Mastercard by the merchant: If the card is Mastercard, a 20% discount is applied to the current shopping cart. This action is performed entirely by your app.
- Order Update: After applying a discount, your application is responsible for updating the order using the DEUNA Update Order endpoint.
- Notification to the widget to update the order and installments: Changes in the status of an order are communicated using the SDK callbacks.
- Display a promotional tag: In addition to updating the order and payment amounts, you can apply custom CSS styling to the active widget using
setCustomStyles(...). See the Web SDK guide.
Process a payment with the returned card_id
To process a payment in DEUNA with given card_id use the Purchase API.
Example curl request
const requestBody = {
payer_info: {
email: "eposada@deuna.com"
},
payment_source: {
method_type: "credit_card",
card_info: {
card_id: "8d369b6e-113a-4640-9e63-dc29957fc86a",
installment: {
plan_option_id: "<uuid que se retorna en el postMessage 'onInstallmentSelected'>"
}
}
},
// ... Remaining of the request 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": "foo@bar.com"
},
"payment_source": {
"method_type": "credit_card",
"card_info": {
"card_id": "8d369b6e-113a-4640-9e63-dc29957fc86a"
}
},
"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": "foo@bar.com",
"first_name": "efren",
"identity_document": "162915134",
"is_default": true,
"last_name": "garcia",
"phone": "+525222222222",
"state_code": "MX",
"state_name": "miguel hidalgo",
"zipcode": "11500"
}
}
}'const response = await 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({
"payer_info": {
"email": "foo@bar.com"
},
"payment_source": {
"method_type": "credit_card",
"card_info": {
"card_id": "8d369b6e-113a-4640-9e63-dc29957fc86a"
}
},
"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": "foo@bar.com",
"first_name": "efren",
"identity_document": "162915134",
"is_default": true,
"last_name": "garcia",
"phone": "+525222222222",
"state_code": "MX",
"state_name": "miguel hidalgo",
"zipcode": "11500"
}
}
})
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"POST",
"https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
headers={
"x-api-key": "YOUR_PRIVATE_API_KEY",
"Content-Type": "application/json"
},
json={
"payer_info": {
"email": "foo@bar.com"
},
"payment_source": {
"method_type": "credit_card",
"card_info": {
"card_id": "8d369b6e-113a-4640-9e63-dc29957fc86a"
}
},
"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": "foo@bar.com",
"first_name": "efren",
"identity_document": "162915134",
"is_default": True,
"last_name": "garcia",
"phone": "+525222222222",
"state_code": "MX",
"state_name": "miguel hidalgo",
"zipcode": "11500"
}
}
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/v2/merchants/orders/purchase",
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_PRIVATE_API_KEY",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"payer_info" => [
"email" => "foo@bar.com"
],
"payment_source" => [
"method_type" => "credit_card",
"card_info" => [
"card_id" => "8d369b6e-113a-4640-9e63-dc29957fc86a"
]
],
"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" => "foo@bar.com",
"first_name" => "efren",
"identity_document" => "162915134",
"is_default" => true,
"last_name" => "garcia",
"phone" => "+525222222222",
"state_code" => "MX",
"state_name" => "miguel hidalgo",
"zipcode" => "11500"
]
]
])
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/v2/merchants/orders/purchase"))
.header("x-api-key", "YOUR_PRIVATE_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\n \"payer_info\": {\n \"email\": \"foo@bar.com\"\n },\n \"payment_source\": {\n \"method_type\": \"credit_card\",\n \"card_info\": {\n \"card_id\": \"8d369b6e-113a-4640-9e63-dc29957fc86a\"\n }\n },\n \"order\": {\n \"order_id\": \"testapi-0003\",\n \"currency\": \"MXN\",\n \"items\": [\n {\n \"id\": \"216\",\n \"name\": \"10 Cellphones\",\n \"description\": \"\",\n \"options\": \"string option\",\n \"total_amount\": {\n \"original_amount\": 2000,\n \"amount\": 2000,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"unit_price\": {\n \"amount\": 200,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"tax_amount\": {\n \"amount\": 0,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"quantity\": 1,\n \"uom\": \"string\",\n \"upc\": \"string\",\n \"sku\": \"\",\n \"isbn\": \"\",\n \"brand\": \"\",\n \"manufacturer\": \"\",\n \"category\": \"\",\n \"color\": \"\",\n \"size\": \"\",\n \"weight\": {\n \"amount\": 0,\n \"unit\": \"kg\"\n },\n \"image_url\": \"https://images-staging.getduna.com/95463fb5-6279-4ec3-8ff9-fe07aacd2142/db5b698c57654116_domicilio_216_750x750_1662162887.png?d=200x200&format=webp\",\n \"details_url\": \"\",\n \"type\": \"physcal\",\n \"taxable\": true\n }\n ],\n \"sub_total\": 2000,\n \"total_amount\": 2000,\n \"store_code\": \"all\",\n \"billing_address\": {\n \"address1\": \"presa angostura 36PH\",\n \"address2\": \"\",\n \"address_type\": \"home\",\n \"city\": \"CDMX\",\n \"country_code\": \"MX\",\n \"email\": \"foo@bar.com\",\n \"first_name\": \"efren\",\n \"identity_document\": \"162915134\",\n \"is_default\": true,\n \"last_name\": \"garcia\",\n \"phone\": \"+525222222222\",\n \"state_code\": \"MX\",\n \"state_name\": \"miguel hidalgo\",\n \"zipcode\": \"11500\"\n }\n }\n}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("POST", "https://api.sandbox.deuna.io/v2/merchants/orders/purchase", strings.NewReader("{\n \"payer_info\": {\n \"email\": \"foo@bar.com\"\n },\n \"payment_source\": {\n \"method_type\": \"credit_card\",\n \"card_info\": {\n \"card_id\": \"8d369b6e-113a-4640-9e63-dc29957fc86a\"\n }\n },\n \"order\": {\n \"order_id\": \"testapi-0003\",\n \"currency\": \"MXN\",\n \"items\": [\n {\n \"id\": \"216\",\n \"name\": \"10 Cellphones\",\n \"description\": \"\",\n \"options\": \"string option\",\n \"total_amount\": {\n \"original_amount\": 2000,\n \"amount\": 2000,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"unit_price\": {\n \"amount\": 200,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"tax_amount\": {\n \"amount\": 0,\n \"currency\": \"MXN\",\n \"currency_symbol\": \"$\"\n },\n \"quantity\": 1,\n \"uom\": \"string\",\n \"upc\": \"string\",\n \"sku\": \"\",\n \"isbn\": \"\",\n \"brand\": \"\",\n \"manufacturer\": \"\",\n \"category\": \"\",\n \"color\": \"\",\n \"size\": \"\",\n \"weight\": {\n \"amount\": 0,\n \"unit\": \"kg\"\n },\n \"image_url\": \"https://images-staging.getduna.com/95463fb5-6279-4ec3-8ff9-fe07aacd2142/db5b698c57654116_domicilio_216_750x750_1662162887.png?d=200x200&format=webp\",\n \"details_url\": \"\",\n \"type\": \"physcal\",\n \"taxable\": true\n }\n ],\n \"sub_total\": 2000,\n \"total_amount\": 2000,\n \"store_code\": \"all\",\n \"billing_address\": {\n \"address1\": \"presa angostura 36PH\",\n \"address2\": \"\",\n \"address_type\": \"home\",\n \"city\": \"CDMX\",\n \"country_code\": \"MX\",\n \"email\": \"foo@bar.com\",\n \"first_name\": \"efren\",\n \"identity_document\": \"162915134\",\n \"is_default\": true,\n \"last_name\": \"garcia\",\n \"phone\": \"+525222222222\",\n \"state_code\": \"MX\",\n \"state_name\": \"miguel hidalgo\",\n \"zipcode\": \"11500\"\n }\n }\n}"))
if err != nil { panic(err) }
request.Header.Set("x-api-key", "YOUR_PRIVATE_API_KEY")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}$curl = curl_init();
$requestBody = json_encode(array(
"payer_info" => array(
"email" => "foo@bar.com"
),
"payment_source" => array(
"method_type" => "credit_card",
"card_info" => array(
"card_id" => "8d369b6e-113a-4640-9e63-dc29957fc86a"
)
),
// 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: "foo@bar.com"
},
payment_source: {
method_type: "credit_card",
card_info: {
card_id: "8d369b6e-113a-4640-9e63-dc29957fc86a"
}
}
# ... 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_bodyimport 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", "foo@bar.com"))
.put("payment_source", new JSONObject()
.put("method_type", "credit_card")
.put("card_info", new JSONObject().put("card_id", "8d369b6e-113a-4640-9e63-dc29957fc86a")))
// ... 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();
}
}Demo
After integrating the Payment Vault, the experience is similar to the following demo: