---
title: "Enlaces de instalación y deep links | Tajo"
description: "Genera URLs de instalación para distribuir tu app y deep links para llevar a los usuarios a vistas concretas de la app"
url: https://tajo.io/es/docs/stripe-apps/install-links/
markdown: https://tajo.io/es/docs/stripe-apps/install-links.md
lang: es-ES
author: "Set Noa"
author_url: https://tajo.io/es/set-noa/
robots: noindex
---

Solicita acceso anticipado

Escribe tu nombre y dirección de correo de trabajo. Te enviaremos un enlace para confirmar tu solicitud de acceso a Tajo.

# Enlaces de instalación y deep links

[Set Noa](https://tajo.io/es/set-noa/)

Los enlaces de instalación te permiten distribuir tu Stripe App fuera del marketplace, mientras que los deep links llevan a los usuarios directamente a vistas concretas dentro de tu app ya instalada. Ambos son imprescindibles para que el onboarding y los flujos de integración sean fluidos.

Caution

**Estado: planificada, no construida.** Tajo no tiene ninguna Stripe App, así que hoy no se puede instalar nada de esta sección. Los identificadores de app, las URLs y las credenciales de esta página son marcadores de posición ilustrativos, no endpoints reales.

## Enlaces de instalación

Un enlace de instalación es una URL directa que los comercios pueden usar para instalar tu app. Cuando alguien hace clic en un enlace de instalación, Stripe se encarga del flujo de instalación y después redirige de vuelta a la URI que hayas indicado.

### Requisitos previos

Antes de usar enlaces de instalación, configura `allowed_redirect_uris` en el manifiesto de tu app:

```json
{
  "id": "com.tajo.brevo-integration",
  "allowed_redirect_uris": [
    "https://tajo.io/stripe/callback",
    "https://tajo.io/stripe/oauth/complete"
  ]
}
```

### Formato del enlace de instalación

```
https://marketplace.stripe.com/oauth/v2/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&state=STATE_VALUE
```

| Parámetro | Obligatorio | Descripción |
| --- | --- | --- |
| `client_id` | Sí | El ID de tu app (por ejemplo, `com.tajo.brevo-integration`) |
| `redirect_uri` | Sí | Debe coincidir con alguna de tus `allowed_redirect_uris` |
| `state` | Recomendado | Cadena aleatoria para protegerte del CSRF |

### Parámetros de la redirección

Tras una instalación correcta, Stripe redirige al usuario a tu `redirect_uri` con estos parámetros de consulta:

| Parámetro | Descripción |
| --- | --- |
| `user_id` | El ID de usuario de Stripe de la cuenta que instala la app |
| `account_id` | El ID de cuenta de Stripe (por ejemplo, `acct_xxxxx`) |
| `state` | El valor de `state` que enviaste (para verificar el CSRF) |
| `install_signature` | Firma HMAC que permite verificar que la instalación es legítima |

Ejemplo de URL de redirección:

```
https://tajo.io/stripe/callback
  ?user_id=usr_xxxxx
  &account_id=acct_xxxxx
  &state=abc123random
  &install_signature=sig_xxxxx
```

### Protección contra CSRF

Usa siempre el parámetro `state` para evitar ataques de falsificación de peticiones entre sitios:

```javascript
import crypto from 'crypto';

// Generate a random state value and store it in the session
const generateInstallLink = (req, res) => {
  const state = crypto.randomBytes(32).toString('hex');

  // Store state in session for later verification
  req.session.stripeInstallState = state;

  const installUrl = new URL('https://marketplace.stripe.com/oauth/v2/authorize');
  installUrl.searchParams.set('client_id', 'com.tajo.brevo-integration');
  installUrl.searchParams.set('redirect_uri', 'https://tajo.io/stripe/callback');
  installUrl.searchParams.set('state', state);

  res.redirect(installUrl.toString());
};

// Handle the redirect callback
const handleInstallCallback = async (req, res) => {
  const { state, user_id, account_id, install_signature } = req.query;

  // Verify state matches what we stored
  if (state !== req.session.stripeInstallState) {
    return res.status(403).json({ error: 'Invalid state parameter' });
  }

  // Clear the stored state
  delete req.session.stripeInstallState;

  // Verify the install signature
  if (!verifyInstallSignature(install_signature, account_id)) {
    return res.status(403).json({ error: 'Invalid install signature' });
  }

  // Process the successful installation
  await processInstallation(user_id, account_id);

  res.redirect('/dashboard/stripe-connected');
};
```

### Verificación de la firma

Verifica el `install_signature` con el secreto de firma de tu app:

```javascript
import crypto from 'crypto';

const verifyInstallSignature = (signature, accountId) => {
  const signingSecret = process.env.STRIPE_APP_SIGNING_SECRET;

  const expectedSignature = crypto
    .createHmac('sha256', signingSecret)
    .update(accountId)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
};
```

Caution

Usa siempre `crypto.timingSafeEqual` al comparar firmas, así evitas los ataques de temporización. Nunca uses una simple igualdad de cadenas (`===`).

### Secreto de firma

El secreto de firma de tu app está disponible en el Stripe Dashboard, dentro de los ajustes de la app. Te sirve para:

- Verificar las firmas de instalación de las redirecciones de vuelta
- Validar las cargas útiles de los webhooks de Stripe
- Autenticar las peticiones entre tu backend y Stripe

Guarda el secreto de firma de forma segura:

```bash
# Set as environment variable
export STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"
```

Nunca incrustes secretos de firma en tu código fuente ni los subas al control de versiones.

## Deep links

Los deep links llevan a los usuarios directamente a una vista concreta dentro de tu Stripe App instalada. Úsalos para dirigir a la gente desde comunicaciones externas (emails, notificaciones, páginas de soporte) al contexto adecuado de la app.

### Formato de la URL de un deep link

```
https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID
```

| Componente | Descripción | Ejemplo |
| --- | --- | --- |
| `MODE` | `live` o `test` | `live` |
| `acct_ID` | ID de la cuenta de Stripe de destino | `acct_1234567890` |
| `PAGE` | Ruta de la página del Dashboard | `customers/cus_xxxxx` |
| `APP_ID` | El ID de tu app | `com.tajo.brevo-integration` |
| `TARGET` | `drawer` o `modal` | `drawer` |
| `VIEWPORT_ID` | El viewport que se abre | `stripe.dashboard.customer.detail` |

### Destinos drawer y modal

| Destino | Comportamiento | Caso de uso |
| --- | --- | --- |
| `drawer` | Abre la app en el panel lateral (drawer) | Interacción predeterminada con la app, contexto junto a la página |
| `modal` | Abre la app en una ventana modal a pantalla completa | Flujos que requieren concentración, onboarding, formularios complejos |

### Ejemplos de deep links

#### Abrir la vista de detalle de un cliente en el drawer

```
https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx
  ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail
```

#### Abrir los ajustes en una modal

```
https://dashboard.stripe.com/live/acct_xxxxx/settings
  ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.settings
```

#### Abrir el flujo de onboarding

```
https://dashboard.stripe.com/live/acct_xxxxx/dashboard
  ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboarding
```

#### Abrir la vista de detalle de un pago en modo test

```
https://dashboard.stripe.com/test/acct_xxxxx/payments/pi_xxxxx
  ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.payment.detail
```

### Generar deep links por programación

```javascript
const generateDeepLink = ({
  accountId,
  mode = 'live',
  page,
  appId = 'com.tajo.brevo-integration',
  target = 'drawer',
  viewport,
}) => {
  const baseUrl = `https://dashboard.stripe.com/${mode}/${accountId}/${page}`;
  const params = new URLSearchParams();
  params.set(`apps[${appId}][${target}]`, viewport);

  return `${baseUrl}?${params.toString()}`;
};

// Generate a link to view a customer's Brevo profile
const customerLink = generateDeepLink({
  accountId: 'acct_xxxxx',
  page: 'customers/cus_xxxxx',
  viewport: 'stripe.dashboard.customer.detail',
});

// Generate a link to app settings
const settingsLink = generateDeepLink({
  accountId: 'acct_xxxxx',
  page: 'settings',
  viewport: 'stripe.dashboard.settings',
  target: 'modal',
});
```

### Usar deep links en tus comunicaciones

Los deep links resultan especialmente útiles en:

- **Notificaciones por email**: “Consulta el estado de sincronización con Brevo de este cliente”
- **Respuestas de soporte**: “Haz clic aquí para revisar los ajustes de tu integración”
- **Emails de onboarding**: “Termina de configurar Brevo”
- **Alertas de error**: “Revisa el problema de sincronización del cliente X”

```html
<!-- Example in an email template -->
<a href="https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail">
  View Brevo Profile in Stripe
</a>
```

## Combinar enlaces de instalación y deep links

Para lograr la mejor experiencia de onboarding, combina los enlaces de instalación con deep links posteriores a la instalación:

1. La persona hace clic en un **enlace de instalación** desde tu web o desde un email
2. Instala la app y se le redirige a tu URL de callback
3. Tu callback procesa la instalación y la redirige a un **deep link** que abre el viewport de onboarding

```javascript
const handleInstallCallback = async (req, res) => {
  const { account_id, install_signature, state } = req.query;

  // Verify state and signature
  // ... (verification code)

  // Process installation
  await processInstallation(account_id);

  // Redirect to the app's onboarding view via deep link
  const onboardingLink = generateDeepLink({
    accountId: account_id,
    page: 'dashboard',
    viewport: 'stripe.dashboard.onboarding',
    target: 'modal',
  });

  res.redirect(onboardingLink);
};
```

Tip

Prueba siempre los enlaces de instalación y los deep links tanto en modo live como en modo test, así te aseguras de que funcionan bien en todos los entornos.
