Click to Pay

Get started with Click to Pay

This page offers a comprehensive guide to successfully integrating the Click to Pay Widget with DEUNA.

The Click to Pay Widget focuses on efficient payment processing and card management.

This tool uses advanced payment technology and intelligent security, based on EMVCo's secure remote commerce framework.

📘

For more information about Click to Pay, refer to the dedicated Master Card Checkout Services Page

Requirements

The following content lists all the requirements for a successful integration with Master Card's Click to Pay:

Integration steps

Now that the technical requirements are set, you can start the step-by-step integration.

1. Choose your integration

You have two choices for Click to Pay in DEUNA.

Vault widget

The vault widget allows you to add or select an existing card in Click to Pay.

This option obtains the selected card and returns it to generate a payment via the DEUNA API, but processing the payment is not its responsibility.

  • Integration methods:
  1. iOS SDK
  2. Android SDK
  3. Integration via URL

🚧

The vault web sdk is coming soon.

Payment widget

The payment widget allows a user to add or select an existing card in Click to Pay.

This option obtains the selected card and returns it to generate a payment, and it also processes the payment.

  • Integration methods
  1. Web SDK
  2. iOS SDK
  3. Android SDK

📘

For the Payment Widget, use HTTPS to embed the widget to the parent website. This is a security requirement from Click to Pay.

2. Configure the Click to Pay component

Activate the Click to Pay component from the DEUNA Admin.

  1. Add the Click to Pay to your DEUNA Admin Connections.
  2. Search for "Click to Pay" and enter your Master Card business account credentials.
  3. If you chose the URL integration: In your app, start an iFrame with the DEUNA URL (provided by DEUNA).

URL para integración

https://elements.sandbox.deuna.io/click_to_pay?publicApiKey=${apiKey}&firstName=${encodeURIComponent(firstname)}&lastName=${encodeURIComponent(lastname)}&email=${encodeURIComponent(email)}
https://elements.deuna.com/click_to_pay?publicApiKey=${apiKey}&firstName=${encodeURIComponent(firstname)}&lastName=${encodeURIComponent(lastname)}&email=${encodeURIComponent(email)}

📘

Integrate this component inside of an iframe in your website or app webView.

Query params attributes

AtributoDescripción
publicApiKey (required)Your DEUNA public API key.
firstName (required)User first name.
lastName (required)User last name.
email (optional)User email. En caso no sea enviada a la integración,se mostrará una pantalla para recopilar el correo electrónico, ya que es un requisito de Click to Pay para iniciar su flujo."
cssFile (optional)DEUNA provided UUID. This applies only for customized css files.
userToken(optional)El bearer token del usuario de DEUNA. Cuando este es enviado, todas las acciones dentro del widget van a hacer sobre este usuario de DEUNA. Adicionalmente, cuando se envía este userToken, no es necesario mandar ni el email, firstName, lastName. Solo será requerido el userTokeny el publicApiKey
int (optional)Allows you to send embedded or modal as a value to specify the type of integration to be performed and thus enable certain functionalities depending on the integration, such as the indicator arrow to go back or close the modal.

👍

Be sure that all query params are coded to have special caracters, this can avoid any future issues with requests.

3. Get a card_id

After integrating the component in your application, you must get a card_id to process the payment.

Here is an example of how to integrate the URL using HTML, CSS, and JavaScript:

  1. The DEUNA component handles the communication with Click to Pay, including saving the card.
  2. After success, DEUNA sends the postMessage with a valid card_id.
  3. The card_id is sent in the purchase request from your backend to process the payment.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Click to Pay Integration</title>
    <style>
      /* Estilos básicos para el iframe */
      #click-to-pay-iframe {
          width: 100%;
          height: 500px; /* Ajusta la altura según tus necesidades */
          border: none;
      }
    </style>
  </head>
  <body>
    <iframe
      id="click-to-pay-iframe"
      src="https://elements.sandbox.deuna.io/click_to_pay?publicApiKey=${apiKey}&firstName=${encodeURIComponent(firstname)}&lastName=${encodeURIComponent(lastname)}&email=${encodeURIComponent(email)}"
      allow="payment"
    >
    </iframe>

    <script>
      // Escucha los mensajes de postMessage para recibir el card_id (a.k.a card token)
      window.addEventListener('message', function(event) {
          if (event.origin !== "https://elements.sandbox.deuna.io") {
              return;
          }
          let firstParsedData;
          if (typeof event.data === 'string') {
              firstParsedData = JSON.parse(event.data);
          } else {
              firstParsedData = event.data;
          }

          const parsedData = JSON.parse(firstParsedData);
          console.log('postMessage:', parsedData);

          if (
            parsedData &&
            parsedData.type === "vaultSaveSuccess"
        ) {
          // obtener el card_id (a.k.a card token)
          const cardId = parsedData.data.metadata.createdCard.id;

          // crear pago con el card_id
        }
      });
    </script>
  </body>
</html>

4. Process a card

When a card is successfully processed in DEUNA, you get a postMessage event with a card_id in the response.

Use the card_id to process the payment in your backend.

📘

Head to Handling events with postMessage for more information.

Example events

window.addEventListener("message", (event) => {
  if (event.origin !== "URL_DE_CONFIANZA") { // Reemplaza con tu URL de confianza
    return;
  }

  switch (event.data.type) {
    case 'VaultStarted':
      // Click to Pay ready
      break;

    case 'VaultSaveSuccess':
      // Card saved, get the card_id
      const cardId = event.data.metadata.createdCard.id;
      // Use this card_id to process payments
      break;

    case 'VaultSaveError':
    case 'VaultFailed':
      // Error management
      const errorCode = event.data.metadata.errorCode;
      const errorMessage = event.data.metadata.errorMessage;
      break;

    case 'VaultProcessing':
      // Pago en proceso
      break;

    //Add more cases as needed
  }
});

5. Process a payment

After the payment is initiated through your backend, you need to process the payment through a V2 purchase.

This endpoint is in charge of creating an order and processing the payment in DEUNA if an order token is not passed to it and anorder object is sent to it with all the required information.

Here is a list of required fields for Click to Pay: [NEED TO DEFINE THE REQUIRED FIELDS FOR CLICK TO PAY (IF THEY EXIST)]

FieldDescriptionValue
order.callback_urls.on_successRedirect URL after authorizing the purchase with your PayPal Wallet account.https://example.com/
payment_source.method_typeDEUNA payment method type.wallet
payment_source.processorPayPal Wallet payment method identifier.paypal_wallet

Example Request

📘

The value of card_id is the same as the value DEUNA sends through the postMessage event during \VaultSavedSuccess

const requestBody = {
    payer_info: {
        email: "[email protected]"
    },
    payment_source: {
        method_type: "credit_card",
        card_info: {
            card_id: "8d369b6e-113a-4640-9e63-dc29957fc86aza"
        }
    },
    // ... 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-sandbox.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();
    }
}

👍

Refer to V2 Purchase to see the endpoint details.

Example purchase

This is an example of Click to Pay purchase in DEUNA::

CSS component customization

You can edit the appearance of the widget through CSS.

📘

Head to CSS Customization for more information.

6. Try the integration

Use the Click to Pay trial cards to test your integration with DEUNA.