---
updatedAt: 2026-07-15T00:54:13.000Z
agentTools:
  projectIndex: https://docs.orkestapay.com/llms.txt
---

# PayPal

<Image src="https://files.readme.io/4878b06cf4fa144c3cefd22f32dc76b3785de82e56fabcd68ec04b128b7a26f9-paypal_bnr2x.png" align="center" width="100% " />

## PayPal

PayPal es una plataforma que actúa como intermediario en transacciones de pago en línea, permitiendo a los usuarios realizar y recibir pagos de manera segura y rápida.

En esencia, PayPal simplifica el proceso de pago digital proporcionando una experiencia segura, global y conveniente para compradores y vendedores.

<br />

## Operaciones soportadas

| Operación                         | Descripción                                      |
| --------------------------------- | ------------------------------------------------ |
| ✅ **Autorización de pago**        | Bloquea fondos en la tarjeta del cliente.        |
| ✅ **Captura de pago**             | Completa la transacción y transfiere los fondos. |
| ✅ **Pago directo**                | Combina autorización y captura en un solo paso.  |
| ✅ **Reembolso**                   | Devuelve el monto completo de una transacción.   |
| ✅ **Reembolso parcial**           | Devuelve parte del monto capturado.              |
| ✅ **Cancelación de autorización** | Revierte una autorización que no fue capturada.  |

<br />

## Integración

### 1. Configurar PayPal como método de pago

Para realizar la integración de **PayPal**, primero deberás de realizar una serie de configuraciones desde el portal de OrkestaPay. Visita nuestra guía de configuración de [Proveedores](/developer-center/docs/proveedores#google-pay) y busca el método de pago **PayPal**.

<br />

### 2. Implementar botón de pago

Para realizar la tokenización de los datos de pago hay que seguir los siguientes pasos:

1. **Incluir scripts de OrkestaPay**: Utilizar los scripts de OrkestaPay en tu aplicación web.
2. **Inicializar parámetros**: Aquí se definen las credenciales de OrkestaPay, así como datos referentes al pago a procesar.
3. **Renderizar el botón de pago**: Colocar el botón de PayPal en tu frontend.

<br />

#### Recursos necesarios:

**CSS**

```html
<link rel="stylesheet" href="https://resources.orkestapay.com/payment-methods/styles.css" integrity="sha384-5/NLomvLQk75JVAmEdaNkdkgLavuAlRS256szA++bmuw6Zph/wFYlWFHz9Fss7JF" crossorigin="anonymous">
```

**JS**

```html
<script src="https://resources.orkestapay.com/js/orkestapay.js" integrity="sha384-lQoLMYDY2Cz/Y+8BLiNbhfLVHWawqsA/gE/8WRTpF6ZS3EABNKXhrq/0bBu4M1aI" crossorigin="anonymous"></script>

<script src="https://resources.orkestapay.com/payment-methods/main.js" integrity="sha384-hvoIO7IyazX+Cc2LqBdHXx7Z3tq766248YzywLTN+D6f41Lub/VHUh2Pe5Q7WKfA" crossorigin="anonymous"></script>
```

<br />

#### Ejemplo de código

En el siguiente snippet de código hay ciertos parámetros que son necesarios de reemplazar con los datos de tu comercio:

* `public_key` : Llave pública, estas credenciales las puedes obtener en el portal de OrkestaPay.
* `merchant_id:` ID del comercio, estas credenciales las puedes obtener en el portal de OrkestaPay.
* `is_sandbox:` Define si las credenciales que estás por operar son de pruebas o productivas.

En este ejemplo se capturan credenciales sensibles en un formulario, **estas credenciales deberán de ser manejadas desde el backend.**

* `client_id` : Esta llave en conjunto con la llave secreta, permitirá la autenticación para poder comunicarse con el API de OrkestaPay. **Es utilizada en el servidor.**
* `client_secret:` Esta llave en conjunto con la llave de acceso, permitirá la autenticación para poder comunicarse con el API de OrkestaPay. **Es utilizada en el servidor.**

<Callout icon="📘" theme="info">
  ### INFORMACIÓN

  Para consultar las credenciales de OrkestaPay, puedes visitar nuestra guía [Obtener llaves de API](https://orkestapay.readme.io/docs/obtener-llaves-del-api).
</Callout>

<br />

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <base href="/" />
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="apple-touch-icon" type="image/x-icon" href="favicon.ico" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <title>PayPal web component</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
      integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
      crossorigin="anonymous"
    />
    <link rel="stylesheet" href="https://resources.orkestapay.com/payment-methods/styles.css" />
    <style>
      .code {
        color: inherit;
        overflow-wrap: break-word;
        white-space: pre-wrap;
      }
    </style>
  </head>
  <body>
    <main class="container">
      <section class="row mt-5">
        <h1 id="card-title" class="col-12 text-center">
          OrkestaPay payment method PayPal web component
        </h1>
      </section>

      <section class="row">
        <article class="col-12 col-md-6 offset-md-3">
          <div class="row">
            <section class="pt-3 col-12 col-md-6">
              <label for="client-id" class="form-label">
                OrkestaPay client ID&nbsp;<span class="text-danger">*</span>
              </label>
              <input type="text" id="client-id" class="form-control" />
              <small id="client-id-error" class="text-danger">&nbsp;</small>
            </section>

            <section class="pt-3 col-12 col-md-6">
              <label for="client-secret" class="form-label">
                OrkestaPay client secret&nbsp;<span class="text-danger">*</span>
              </label>
              <input type="password" id="client-secret" class="form-control" />
              <small id="client-secret-error" class="text-danger">&nbsp;</small>
            </section>
          </div>
        </article>
        <article
          id="button-container"
          class="col-12 col-md-6 offset-md-3"
        ></article>
        <article class="pt-3 col-12">
          <div id="payment-details" class="w-100 alert" role="alert"></div>
        </article>
      </section>
    </main>

    <noscript>
      Please enable JavaScript to continue using this application.
    </noscript>

    <script type="text/javascript" src="https://resources.orkestapay.com/js/orkestapay.js"></script>
    <script
      type="text/javascript"
      src="https://resources.orkestapay.com/payment-methods/main.js"
    ></script>
    <script type="text/javascript">
      //#region FRONTEND

      let orkestaPay;
      let paymentId = null;

      const clientId = document.getElementById('client-id');
      const clientSecret = document.getElementById('client-secret');      

      const {
        public_key,
        merchant_id,
        is_sandbox,
        country_code,
        currency,
        amount,
      } = initValues();

      (async function main() {        
        orkestaPay = initOrkestaPay({ is_sandbox, merchant_id, public_key });

        const payPalButton = document.createElement('orkestapay-paypal-button');
        await customElements.whenDefined('orkestapay-paypal-button');

        payPalButton.params = {
          payment_details: { currency, createPayment, confirmPayment },
          theme: {
            color: 'gold',
            height: 48,
            shape: 'rect',
          },
        };

        const container = document.getElementById('button-container');
        container.appendChild(payPalButton);
      })();

      function handlePaymentCreated(payment) {
        const code = document.createElement('code');
        code.innerHTML = JSON.stringify(payment, null, 2);
        code.classList.add('code');

        const paymentDetails = document.getElementById('payment-details');
        paymentDetails.classList.add('alert-success');
        paymentDetails.replaceChildren(code);

        paymentId = payment.payment_id;
        return paymentId ?? null;
      }

      function initValues() {
        const url = new URL(window.location.href);
        return {
          public_key: "<REPLACE_WITH_YOUR_PUBLIC_KEY>",
          merchant_id: "<REPLACE_WITH_YOUR_MERCHANT_ID>",
          is_sandbox: true,
          country_code: "MX",
          currency: "MXN",
          amount: "100.00",
        };
      }      

      //#endregion FRONTEND

      //#region BACKEND

      async function createPayment(paymentMethod) {
        if (!paymentMethod) return null;
        const { payment_method_id } = paymentMethod;

        const order = await createOrder();
        if (!order) return null;
        const { order_id } = order;

        const deviceInfo = await orkestaPay.getDeviceInfo();
        if (!deviceInfo) return;
        const { device_session_id } = deviceInfo;

        const url = `${orkestaPay.getApiUrl()}/v1/payments`;
        const Authorization = await authenticate();
        const body = JSON.stringify({
          payment_source: { type: 'PAYPAL', payment_method_id },
          device_session_id,
          order_id,
        });

        return fetch(url, {
          method: 'POST',
          headers: {
            Authorization,
            'Content-Type': 'application/json',
            'Idempotency-Key': crypto.randomUUID(),
          },
          body,
        })
          .then(handleFetchResponse)
          .then(handlePaymentCreated)
          .catch(handleFetchError);
      }

      async function confirmPayment() {
        if (!paymentId) return;

        const url = `${orkestaPay.getApiUrl()}/v1/payments/${paymentId}/confirm`;
        const Authorization = await authenticate();
        const body = JSON.stringify({});

        return fetch(url, {
          method: 'POST',
          headers: {
            Authorization,
            'Content-Type': 'application/json',
            'Idempotency-Key': crypto.randomUUID(),
          },
          body,
        })
          .then(handleFetchResponse)
          .then(handlePaymentCreated)
          .catch(handleFetchError);
      }

      async function createOrder() {
        const url = `${orkestaPay.getApiUrl()}/v1/orders`;
        const Authorization = await authenticate();
        const body = JSON.stringify({
          merchant_order_id: crypto.randomUUID(),
          subtotal_amount: amount,
          total_amount: amount,
          country_code,
          customer: {
            email: "john@yopmail.com",
          },
          currency,
          products: [
            {
              product_id: crypto.randomUUID(),
              quantity: 1,
              unit_price: amount,
              name: 'A random product',
            },
          ],
        });

        return fetch(url, {
          method: 'POST',
          headers: { Authorization, 'Content-Type': 'application/json' },
          body,
        })
          .then(handleFetchResponse)
          .catch(handleFetchError);
      }

      async function authenticate() {
        const url = `${orkestaPay.getApiUrl()}/v1/oauth/tokens`;
        const body = JSON.stringify({
          client_id: clientId.value.trim(),
          client_secret: clientSecret.value.trim(),
          grant_type: 'client_credentials',
        });

        const response = await fetch(url, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body,
        })
          .then(handleFetchResponse)
          .catch(handleFetchError);
        if (!response) return null;

        const { token_type, access_token } = response;
        return `${token_type} ${access_token}`;
      }

      function handleFetchResponse(response) {
        return response.ok ? response.json() : Promise.reject(body);
      }

      function handleFetchError(error) {
        console.error(error);
        return null;
      }

      //#endregion BACKEND
    </script>
  </body>
</html>
```

<Callout icon="📘" theme="info">
  ### NOTA

  Este código es solo con fines demostrativos, que integra código de frontend y código que debería de ejecutarse desde un backend, por lo tanto es tú responsabilidad realizar una implementación con buenas prácticas.
</Callout>

<br />

### Explicación del código

#### Variables y Funciones Iniciales

* `orkestaPay`: Objeto principal para interactuar con la API de OrkestaPay.
* `paymentId`: Almacena el ID del pago actual.
* `initValues()`: Configuración inicial, como claves y detalles de transacción (monto, moneda, etc.).

<br />

#### Función `main`

* Función autoejecutable que:
  1. Inicializa **OrkestaPay** con valores iniciales.
  2. Crea un botón de PayPal como un **Web Component** (`<orkestapay-paypal-button>`).
  3. Configura parámetros del botón:
     * `payment_details`: Define las funciones para crear y confirmar pagos.
     * `theme`: Personalización visual (color, forma, altura).
  4. Agrega el botón al contenedor (`button-container`).

<br />

#### Operaciones de backend

##### Autenticación (`authenticate`)

* Genera un token de acceso:
  * Envía las credenciales del cliente (`client_id` y `client_secret`) a la API.
  * Devuelve un token que se usa para autorizar las solicitudes.

<br />

##### Registro de Pedidos (`createOrder`)

* Crea un nuevo pedido:
  * Incluye información básica como el monto total, moneda, y productos (ficticios en este caso).

<br />

##### Creación de Pago (`createPayment`)

* Recibe un método de pago (`paymentMethod`).
* Pasos:
  1. Registra un pedido (`createOrder`).
  2. Obtiene información del dispositivo.
  3. Envía una solicitud `POST` a la API para crear un pago.
  4. Maneja la respuesta y actualiza los detalles del pago (`handlePaymentCreated`).

<br />

##### Confirmación de Pagos (`confirmPayment`)

* Confirma el pago previamente creado mediante su `paymentId`.

<br />

#### **Manejo de respuestas y errores**

* `handleFetchResponse(response)`: Devuelve el cuerpo de la respuesta si es exitosa; en caso contrario, rechaza la promesa.
* `handleFetchError(error)`: Muestra errores en la consola.

<br />

### Pruebas

Para finalizar una prueba de integración deberás de contar con una cuenta de sandbox de PayPal de tipo personal.

<Callout icon="📘" theme="info">
  ### NOTA

  Para más información sobre pruebas con PayPal dirígete a su documentación oficial: [https://developer.paypal.com/tools/sandbox/](https://developer.paypal.com/tools/sandbox/)
</Callout>

<br />