Referencia de n1co.js
El loader, el cliente, el card element, la captura de tarjetas, el cobro y los errores de n1co.js.
- Carga
n1co.jsdesde el host de n1co, en una páginahttps. - Crea el cliente:
n1co('pk_…'). - Monta el card element y llama a
capture()oconfirmPayment().
<!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. |
<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:. |
Navegadores#
Las versiones actuales de Chrome, Edge, Firefox y Safari. not_visible solo actúa con IntersectionObserver v2.