n1coePayDocs Referencia del API

Referencia de n1co.js

El loader, el cliente, el card element, la captura de tarjetas, el cobro y los errores de n1co.js.

  1. Carga n1co.js desde el host de n1co, en una página https.
  2. Crea el cliente: n1co('pk_…').
  3. Monta el card element y llama a capture() o confirmPayment().
Página mínima
<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>n1co.js</title>
  </head>
  <body>
    <div id="card"></div>
    <script src="https://elements.n1co.dev/v1/n1co.js"></script>
    <script>
      const card = n1co('pk_3x4mpl3pUbl1shabl3k3yAAAAAAAAAAA').elements().create('card');
      card.on('ready', () => console.log('card element listo'));
      card.on('error', (error) => console.error(error.code, error.message));
      card.mount('#card');
    </script>
  </body>
</html>

Cargar n1co.js#

Forma Ruta Cuándo usarla
Flotante /v1/n1co.js Siempre la última versión. Se cachea 5 minutos.
Fijada /v1/n1co-<hash>.js Una versión inmutable, con integrity y crossorigin.
Versión fijada con SRI
<script src="https://elements.n1co.dev/v1/n1co-<hash>.js" integrity="sha384-…" crossorigin="anonymous"></script>

Cada versión fijada se publicará en el Changelog. En desarrollo, el host es https://elements.n1co.dev.

Tu página usa https:// (o localhost para desarrollar) y otro origen que n1co.js. Su Content Security Policy permite ese host en script-src y frame-src.

n1co(publishableKey)#

Crea el cliente con tu llave pública. No acepta opciones.

El card element#

n1co('pk_…').elements().create('card', options?) crea el elemento. 'card' es el único tipo.

Opciones#

Todas son opcionales; un valor inválido lanza invalid_options.

Opción Valores Por omisión
locale 'es', 'en' 'es'
fields.name 'required', 'optional', 'hidden' 'required'
brands Subconjunto no vacío de ['visa', 'mastercard', 'amex'] Las tres
layout 'stacked', o 'inline' con vencimiento y código en fila 'stacked'
appearance { theme?: 'light' | 'dark', variables?: { …tokens } } { theme: 'light', variables: {} }

Un número de una marca fuera de brands se informa como unsupported_brand.

Apariencia#

No se acepta CSS libre, solo estos tokens:

Token Valores
fontFamily 'system', 'sans-serif', 'serif', 'monospace'
fontSizeBase De 12 a 20 px (16 o '16px')
colorText, colorTextPlaceholder, colorBackground, colorBorder, colorBorderFocus, colorDanger '#rgb' o '#rrggbb'
borderRadius De 0 a 16 px
spacingUnit De 2 a 12 px

colorText y colorDanger necesitan un contraste de 3:1 con colorBackground, y colorTextPlaceholder de 2:1. Con un fondo oscuro, usa theme: 'dark'.

const card = n1co('pk_3x4mpl3pUbl1shabl3k3yAAAAAAAAAAA')
  .elements()
  .create('card', {
    layout: 'inline',
    brands: ['visa', 'mastercard'],
    appearance: { theme: 'light', variables: { fontFamily: 'system', colorBorderFocus: '#7b3eff', borderRadius: 8 } },
  });

Métodos#

Todos menos capture() devuelven el elemento y se pueden encadenar.

Método Efecto
mount(selectorOrElement) Inserta el iframe; su alto sigue al formulario (de 40 a 600 px).
unmount() Retira el iframe y descarta lo escrito.
on(event, handler) Agrega un manejador.
off(event, handler) Quita un manejador.
focus(field?) Enfoca 'number' (por omisión), 'expiry', 'cvc' o 'name'.
clear() Vacía los campos. Se ignora durante una captura.
update({ appearance?, locale? }) Cambia idioma o apariencia. El tema se reemplaza; las variables se combinan.
capture({ client_secret }) Guarda la tarjeta. Devuelve una promesa.

mount() lanza un N1coError si la página no cumple los requisitos. Llama a focus() y clear() después de ready.

Eventos#

Evento Datos
ready Ninguno. El frame está listo.
change { complete, empty, brand, error }; error es null o { field, code, message }.
focus, blur { field }.
error { code, message }: frame_timeout (10 s) o frame_config_unavailable. Puedes volver a montarlo.
capture { ok: true, card } o { ok: false, error } por cada capture().

change se emite cuando cambia el estado, no con cada tecla.

capture()#

const result = await card.capture({ client_secret: 'cs_…_secret_…' });
// { ok: true, card: { id: 'card_…', brand: 'visa', last4: '4242', exp_month: 12, exp_year: 2030 } }

client_secret es el de una sesión de tarjeta. Durante la captura los campos se deshabilitan; si tiene éxito se vacían, y otra captura responde already_captured hasta clear(). Si falla, la promesa se rechaza con N1coCaptureError.

Códigos de capture()#

Código Qué pasó Qué hacer
incomplete_number, invalid_number, unsupported_brand, incomplete_expiry y otros de campo Un campo está incompleto o es inválido; field dice cuál. El comprador lo corrige.
card_rejected La tarjeta fue rechazada. Pide otra tarjeta.
invalid_request n1co rechazó un valor; field lo indica cuando puede. El comprador corrige el campo.
duplicate_field La solicitud repitió un campo. Reintenta.
card_session_not_found, card_session_expired, card_session_completed, card_session_canceled La sesión ya no sirve. Los campos se vacían. Crea una sesión nueva.
capture_outcome_unknown n1co no pudo confirmar la captura y canceló la sesión. Crea una sesión nueva.
card_session_in_progress Otra captura de la sesión sigue en curso. Espera y reintenta.
rate_limited Demasiados intentos. Espera antes de reintentar.
n1co_api_unavailable, capture_not_tokenized, invalid_proxy_key n1co no está disponible o hay un problema de su lado. Reintenta más tarde.
platform_access_pending Tu tienda aún no está habilitada. Revisa tu configuración.
origin_not_allowed Un problema de configuración de n1co. Contacta a n1co.
page_origin_not_allowed Tu página no está en los page_origins de la sesión. Revisa page_origins.
not_visible El formulario estaba tapado o fuera de la pantalla. Muestra el formulario y reintenta.
network_error n1co no respondió en 30 s. Lee la sesión en tu servidor antes de reintentar.
unexpected_response n1co respondió algo que n1co.js no entiende. Reintenta más tarde.
invalid_client_secret Falta el client_secret o está mal formado. Revisa lo que entrega tu servidor.
not_ready El elemento no está montado o listo. Espera ready.
capture_in_progress Otra capture() o confirmPayment() con este elemento no terminó. Espera a que termine.
already_captured Este elemento ya capturó una tarjeta. Llama a clear().
capture_timeout El frame no respondió en 45 s. Lee la sesión en tu servidor antes de reintentar.
element_unmounted Se llamó a unmount() durante la captura. Vuelve a montar el elemento.

Tras capture_timeout o network_error, la tarjeta pudo guardarse: lee la sesión antes de crear otra.

confirmPayment()#

Paga un payment intent con el card element o con la tarjeta que adjuntó tu servidor, y muestra 3D Secure si el banco lo pide.

const n1 = n1co('pk_3x4mpl3pUbl1shabl3k3yAAAAAAAAAAA');
const intent = await n1.confirmPayment({ client_secret, card }); // tarjeta nueva
const paid = await n1.confirmPayment({ client_secret }); // tarjeta adjunta
Opción Requerida Descripción
client_secret Sí El del payment intent: pi_…_secret_….
card No Un card element de este mismo n1co(), montado y listo. Sin él, se cobra la tarjeta adjunta.
billing No { country, state?, postal_code? } para este intento. Lo piden tarjetas de EE. UU. y Canadá.

Se resuelve con el intent en succeeded, processing, requires_payment_method o canceled; ver Cobrar. Si n1co tarda, lee el intent hasta 60 segundos antes de resolver con processing.

Corre una confirmación a la vez por cliente.

Rechazos de confirmPayment()#

Se rechaza con N1coPaymentError cuando el intento no pudo hacerse.

Código Qué pasó
incomplete_number, invalid_number y otros de campo Un campo es inválido; field dice cuál. No se envió nada.
invalid_client_secret Falta el client_secret o está mal formado.
invalid_options Opción desconocida, billing inválido, o card no es de este cliente.
not_ready El card element no está montado o listo.
confirm_in_progress Otra confirmación de este cliente no terminó.
already_paid Este card element ya pagó; llama a clear().
payment_method_required Sin card y sin tarjeta adjunta al intent.
card_unavailable La tarjeta adjunta ya no se puede usar; confirma con el card element.
invalid_request n1co rechazó un valor; field es un campo de la tarjeta o 'billing'.
payment_intent_not_found El client_secret no existe.
payment_intent_unexpected_state Ya está pagado, cancelado, vencido o en 3D Secure. Léelo.
payment_intent_in_progress Otra confirmación de este intent está en curso.
payment_intent_requires_reconciliation El resultado no se pudo conocer dos veces; n1co lo concilia. No reintentes.
page_origin_not_allowed Tu página no está en los page_origins del intent.
rate_limited Más de 10 por minuto para este intent, o demasiadas en total.
n1co_api_unavailable, platform_access_pending, capture_not_tokenized, invalid_proxy_key, origin_not_allowed n1co no está disponible; el intento no se consumió. Reintenta más tarde.
not_visible El card element estaba tapado o fuera de la pantalla.
network_error n1co no respondió a tiempo (150 s al confirmar, 30 s al leer).
unexpected_response n1co respondió algo que n1co.js no entiende.
payment_timeout El frame de pago no respondió. Lee el intent en tu servidor antes de reintentar.
element_unmounted Se desmontó el card element durante el pago.
frame_timeout, frame_config_unavailable El frame de pago no pudo arrancar.
unsupported_page_origin, insecure_page, invalid_frames_origin La página no puede cargar los frames (las reglas de mount()).

retrievePaymentIntent()#

const intent = await n1.retrievePaymentIntent(client_secret);

Lee el intent para mostrar el monto o la tarjeta adjunta antes de confirmar. Tu página ve una versión reducida:

Campo Valor
id, object pi_…; 'payment_intent'.
status Uno de los cinco estados del intent.
amount, currency Unidades menores y código ISO 4217.
description Tu descripción, o null.
payment_method { brand, last4, exp_month, exp_year, saved }, o null.
next_action Siempre null: n1co.js se encarga de 3D Secure.
last_error { code, decline_code, message }, con message traducido, o null.
attempts_remaining Confirmaciones que quedan.
expires_at Cuándo se cancela si no se paga.

Nunca incluye metadata, referencia, facturación, ids de tarjetas, order_id ni authorization_code.

Errores#

Tipo Cuándo Campos
N1coError Se lanza con argumentos inválidos o en una página no válida. code, message
Evento error El frame no arrancó. code, message
N1coCaptureError Rechazo de capture(). code, message, field?
N1coPaymentError Rechazo de confirmPayment() y retrievePaymentIntent(). code, message, field?

Decide con code, que es estable; message viene traducido y se puede mostrar.

Código de N1coError Cuándo
invalid_publishable_key La llave no es pk_ y 32 caracteres base64url.
invalid_options Opciones desconocidas o inválidas.
unsupported_element_type Un tipo de elemento distinto de 'card'.
invalid_frames_origin La página comparte origen con el host de n1co.js.
insecure_page La página es http:// y no es localhost ni 127.0.0.1.
unsupported_page_origin La página no tiene origen http(s)://, por ejemplo file:.

Las versiones actuales de Chrome, Edge, Firefox y Safari. not_visible solo actúa con IntersectionObserver v2.