> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elata.bio/llms.txt
> Use this file to discover all available pages before exploring further.

# Compras dentro de la aplicación

> Vende artículos únicos en tu aplicación con @elata-biosciences/app-payments.

<a id="overview" />

## Información general

`@elata-biosciences/app-payments` permite que su aplicación abra la caja de Elata y verifique lo que posee el usuario. Elata realiza el pago, recibe el pago en USDCy registra la propiedad. Su aplicación nunca toca billeteras ni detalles de pago.

```bash theme={null}
npm install @elata-biosciences/app-payments
```

| Función | Devuelve | Úselo para |
| - | - | - |
| `getCatalog(opts?)` | `Promise<CatalogItem[]>` | Enumere los elementos de su aplicación con precio, título y descripción |
| `getOwnedItems(opts?)` | `Promise<number[]>` | Enumere cada `contentId` que posee el usuario |
| `hasItem(contentId, opts?)` | `Promise<boolean>` | Marque un artículo |
| `requestPurchase(input)` | `Promise<PurchaseResult>` | Abrir caja para un artículo |

<a id="create-your-catalog" />

## Crea tu catálogo

Abra **Mis aplicaciones → su aplicación → Editar → Comercio → Productos**. Los propietarios y los miembros autorizados del equipo pueden crear y administrar el catálogo ellos mismos.

| Campo | que entrar |
| - | - |
| Título | Un nombre de elemento claro, hasta 100 caracteres |
| Descripción | Lo que recibe el comprador, hasta 500 caracteres |
| URL de la imagen | URL de imagen HTTP o HTTPS opcional |
| Precio | Una cantidad positiva legible por humanos USDC en el formulario del panel |
| Activo | Si el artículo está disponible en el catálogo activo |

Guarde el producto y luego copie el `contentId` asignado en su integración. El identificador es estable y no se puede editar. Los productos se pueden editar o desactivar en lugar de eliminarlos. La desactivación detiene nuevas ventas; siga aplicando los beneficios para propietarios existentes, incluso cuando el artículo ya no aparezca en el catálogo activo.

El tablero acepta cantidades ordinarias como `1.00`. Las API de productos y las respuestas del catálogo utilizan unidades base enteras USDC : `"1000000"` significa 1 USDC. La creación de una entrada de catálogo no implementa su beneficio en su aplicación.

<Info>
  El pago debe configurarse para la implementación. El pago de la aplicación que se describe aquí paga USDC en Base a través del divisor. Consulte [Qué hay en vivo](/es/overview/status) antes de probar los pagos.
</Info>

***

<a id="the-correct-flow" />

## El flujo correcto

Primero controle su interfaz de usuario cuando sea propietario, luego compre y luego aplique el beneficio.

```ts theme={null}
import {
  getCatalog,
  getOwnedItems,
  requestPurchase,
  AppPaymentsError,
} from '@elata-biosciences/app-payments';

const formatUsdc = (base: string) => `$${(Number(base) / 1e6).toFixed(2)}`;

// 1. Read the catalog and what the user already owns.
const [items, owned] = await Promise.all([getCatalog(), getOwnedItems()]);
const ownedSet = new Set(owned);

// 2. Re-apply benefits on startup. Elata is the source of truth,
//    so this survives reloads and device changes.
for (const id of owned) applyBenefit(id);

// 3. Buy, then branch on status.
async function buy(item) {
  try {
    const result = await requestPurchase({
      contentId: item.contentId,
      priceUsdc: formatUsdc(item.priceUsdc), // display hint only
      title: item.title,
    });
    if (result.status === 'success') {
      ownedSet.add(item.contentId);
      applyBenefit(item.contentId);
    } else if (result.status === 'error') {
      showError(result.error);
    }
    // 'cancelled': the user backed out. Do nothing.
  } catch (err) {
    // Only thrown for local problems: no parent frame, bad input, timeout.
    showError(err instanceof AppPaymentsError ? err.code : String(err));
  }
}
```

`requestPurchase` registra *que* el usuario posee un artículo. Tu aplicación decide lo que *hace* poseerla.

***

<a id="things-to-know" />

## Cosas que debes saber

<AccordionGroup>
  <Accordion title="Rama en estado, nunca en txHash">
    Si el usuario ya posee el artículo, Elata omite el pago y devuelve `{ status: "success", txHash: "" }`. El código que verifica `if (result.txHash)` manejará esto mal.
  </Accordion>

  <Accordion title="Dos formatos de precios">
    `CatalogItem.priceUsdc` está en USDC **unidades base** (6 decimales): `"50000"` es \$0,05. `RequestPurchaseInput.priceUsdc` es una sugerencia de visualización de formato libre que Elata ignora. Elata siempre cobra el precio del catálogo.
  </Accordion>

  <Accordion title="Los artículos se desbloquean una sola vez.">
    Cada artículo se compra una vez. Los consumibles (saldos de gasto por uso) y la facturación recurrente no se admiten a través de artículos. Para obtener ingresos recurrentes, utilice un plan de suscripción [Suscripciones](/es/apps/platform/subscriptions).
  </Accordion>

  <Accordion title="Tiempos de espera">
    `requestPurchase` espera hasta 5 minutos para que el usuario finalice el pago. `getCatalog`, `getOwnedItems`y `hasItem` tienen un valor predeterminado de 10 segundos. Fuera de Elata, utilice un host simulado para las pruebas locales. Trate un error en la consulta de propiedad como propiedad desconocida: ofrezca un reintento o una acción de inicio de sesión, y nunca otorgue un beneficio pagado simplemente porque se agotó el tiempo de espera de la consulta.
  </Accordion>
</AccordionGroup>

***

<a id="errors" />

## Errores

Llamadas rechazadas solo con `AppPaymentsError`, que tiene un `code`:

| Código | Significado |
| - | - |
| `invalid_input` | `contentId` no es un número entero no negativo o una opción tiene el tipo incorrecto |
| `no_window` | No se ejecuta en un navegador |
| `no_parent` | No correr dentro del marco de Elata |
| `no_crypto` | `crypto.randomUUID` no está disponible |
| `timeout` | No hay respuesta a tiempo |
| `not_authenticated` | El usuario no ha iniciado sesión (consultas de propiedad) |
| `fetch_failed` | Elata no pudo buscar la propiedad |

Se resuelve un resultado de compra normal `cancelled` o `error` ; no rechaza.

***

<a id="security-model" />

## Modelo de seguridad

* Los registros de compra de Elata se crean después de la verificación de pago del lado del servidor. Su interfaz de usuario debe utilizar consultas de propiedad del host como fuente de verdad.
* Su aplicación **nunca ve** detalles de pago, claves de billetera o tokens de sesión.
* Reproducir una solicitud de grabación con el mismo `requestId` es idempotente. Esto no hace que enviar un segundo pago en cadena sea seguro.
* El divisor deduce la tarifa de la plataforma configurada y envía la parte del creador a la billetera de pagos. Consulte [Ingresos y pagos](/es/apps/operate/revenue-and-payouts).

***

<a id="try-it" />

## Pruébalo

* [`examples/iap-demo`](https://github.com/Elata-Biosciences/elata-bio-sdk/tree/main/examples/iap-demo): un archivo HTML autónomo con un almacén simulado incorporado, para que pueda ejecutar el flujo completo localmente.
* [Paquete README en npm](https://www.npmjs.com/package/@elata-biosciences/app-payments)

<a id="payment-and-ui-states" />

## Estados de pago y UI

Maneje el éxito, la cancelación y los errores por separado. Evite la superposición de intentos de compra. Un pago exitoso y un derecho registrado son pasos separados; desbloquear sólo después de que Elata informe de éxito.

Si se liquida un pago pero falla el registro, conserve los detalles de la transacción y dirija al usuario a [ayuda de facturación](/es/users/billing-and-purchases#payment-problems-and-history). No envíe automáticamente otro pago. El proceso de pago vuelve a intentar retrasos temporales en la indexación, pero no se garantiza la recuperación de cada error de grabación.

Las consultas de propiedad pueden requerir autenticación. En `not_authenticated`, solicite al usuario que inicie sesión; en caso de error de búsqueda, muestra un estado de reintento. No trate silenciosamente a un propietario desconocido como si fuera un no propietario confirmado.

La aplicación no conecta billeteras por sí misma. Elata checkout gestiona la conexión de la billetera y la confirmación del pago, incluida la interfaz de la billetera integrada cuando se utiliza. Los créditos por funciones medidas no son un saldo de pago alternativo para estos artículos.

<a id="test-your-integration" />

## Prueba tu integración

* Vuelva a abrir la aplicación y restaure los beneficios que ya posee de la propiedad del host.
* Mostrar **Utilice** o **Propiedad** para artículos comprados y **Comprar** para artículos disponibles sin propietario.
* Maneje una respuesta exitosa que ya sea de propiedad con un hash de transacción vacío.
* Maneje los estados de cierre de sesión, cancelación, fondos insuficientes, pago no disponible y error de búsqueda.
* Desactive un artículo y verifique que los propietarios existentes aún puedan utilizar su beneficio.

Para acceder a la suscripción, utilice [Suscripciones](/es/apps/platform/subscriptions), en lugar de simular facturación recurrente con compras repetidas de artículos.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.