Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.payana.la/llms.txt

Use this file to discover all available pages before exploring further.

Guía paso a paso para que los administradores de cuenta NetSuite configuren y obtengan todas las credenciales y permisos necesarios para la integración con Payana.

1. Obtener el Account ID

  1. Ve a Setup > Company > Company Information.
  2. Localiza el campo Account ID (ej. 1234567 o 1234567_SB1 en sandboxes).
  3. Copia y guarda este valor.
Si el Account ID contiene un guion bajo (ej. _SB1, _RP), indica un entorno Sandbox o Release Preview. Confirma el tipo de entorno al compartir.

2. Habilitar Token-Based Authentication (TBA)

  1. Ve a Setup > Company > Enable Features.
  2. Abre la subpestaña SuiteCloud.
  3. En Manage Authentication, marca Token-Based Authentication.
  4. Haz clic en Save.

3. Crear el Integration Record (Consumer Key y Secret)

  1. Ve a Setup > Integration > Manage Integrations > New.
  2. Completa los campos:
    • Name: Payana Integration (u otro nombre descriptivo).
    • State: Enabled.
  3. En la subpestaña Authentication:
    • Marca Token-Based Authentication.
    • Desmarca Authorization Code Grant (no es necesario para servidor a servidor).
  4. Haz clic en Save.
  5. Copia de inmediato los valores mostrados:
    • Consumer Key
    • Consumer Secret
El Consumer Secret solo se muestra una vez al crear el registro. Si se pierde, debes crear un nuevo Integration Record.

4. Crear el rol “Conexión Payana”

4.1 Crear el rol

  1. Ve a Setup > Users/Roles > Manage Roles > New.
  2. Configura:
    • Name: Conexión Payana.
    • Centre Type: Classic Centre (es crítico; ver nota abajo).
  3. En la subpestaña Authentication:
    • Marca Web Services Only Role.
  4. Haz clic en Save (agregarás permisos en los siguientes pasos).
¿Por qué Classic Centre?
Los roles de NetSuite usan el Centre Type para determinar qué módulos y tipos de registro puede ver un usuario. Centros funcionales como Accounting Centre o Employee Centre restringen el acceso a ciertos registros y endpoints REST aunque el permiso figure como “Full”. Classic Centre es el único Centre Type que da acceso sin restricciones a todos los módulos vía REST/SOAP, necesario para una integración servidor a servidor. Usar otro centro es una causa frecuente de 401 Invalid login o respuestas API vacías difíciles de diagnosticar.

4.2 Permisos de Setup

En la subpestaña Permissions > Setup agrega:
PermisoNivelMotivo
Log in using Access TokensFullRequerido para TBA: permite autenticación con access tokens.
REST Web ServicesFullDa acceso a los endpoints REST usados por Payana.
User Access TokensFullPermite crear y gestionar tokens asociados a este rol.
Accounting ListsFullPermite leer la tabla PaymentMethod (nombre del método de pago en pagos).
SuiteAnalytics WorkbookFull

4.2 Permisos de Reportes

En la subpestaña Permissions > Reports agrega:
PermisoNivelMotivo
SuiteAnalytics WorkbookFullPermite ejecutar consultas en la base de datos

4.4 Permisos de transacciones

En la subpestaña Permissions > Transactions agrega:

Nivel 1 — Mínimo requerido (operaciones AP básicas)

PermisoNivelMotivo
Bills (Vendor Bill)FullPayana crea y actualiza facturas de proveedor (AP) en NetSuite.
Purchase Orders (Purchase Order)FullNecesario para leer y referenciar POs al vincularlos a bills.
Find TransactionFullNecesario para buscar transacciones existentes (bills, POs) y evitar duplicados.

Nivel 2 — Requerido para flujo AP completo

PermisoNivelMotivo
Bill Purchase OrdersFullNecesario para vincular una factura de proveedor a su orden de compra.
Enter Vendor CreditsFullPermite crear notas de crédito cuando el proveedor emite reembolso total o parcial.
Pay BillsFullNecesario si Payana gestiona o registra pagos contra facturas de proveedor.

4.5 Permisos de listas

En la subpestaña Permissions > Lists agrega:

Nivel 1 — Mínimo requerido

PermisoNivelMotivo
VendorsFullPayana debe leer y resolver proveedores al crear bills.
SubsidiariesFullNecesario para asignar bills y POs a la subsidiaria correcta en cuentas multi-entidad.
AccountsFullNecesario para asignar cuentas contables (gastos, AP) en líneas de bills.
Perform SearchFullHabilita SuiteQL y saved searches para el endpoint REST de consultas.

Nivel 2 — Requerido para flujo AP completo

PermisoNivelMotivo
ItemsFullNecesario para resolver ítems en líneas de bills (inventario y no inventario).
CompaniesFullNecesario para consultar entidades (los vendors son un subtipo de company) al crear bills.
CurrencyFullNecesario para bills multi-moneda (tasas y códigos de moneda).
DepartmentsFullCentros de costo (cuentas analíticas). La integración consulta la tabla Department vía SuiteQL.
LocationsFullBodegas/almacenes. La integración consulta la tabla Location vía SuiteQL.

4.6 Permisos por tabla (SuiteQL)

La integración usa SuiteQL para leer datos. Cada tabla requiere el permiso indicado en NetSuite. La siguiente lista coincide con las entidades a las que accede el procesador (equivalente funcional a la integración con Odoo).
Tabla SuiteQLUso en la integración PayanaPermiso NetSuite que la habilita
VendorProveedores (sincronización de suppliers, datos de beneficiarios en payables y pagos).Lists – Vendors
ItemProductos e ítems (inventario y no inventario).Lists – Items
AccountCuentas contables (libros, métodos de pago, cuentas de gasto en líneas de PO y bills).Lists – Accounts
DepartmentCentros de costo (cost centers).Lists – Departments
LocationBodegas/almacenes (warehouses).Lists – Locations
TransactionFacturas de proveedor (VendBill), órdenes de compra (PurchOrd), pagos (VendPymt, VendCred).Transactions – Find Transaction + Bills, Purchase Orders, Pay Bills, Enter Vendor Credits
TransactionLineLíneas de PO, líneas de pago aplicadas a bills.Transactions – Find Transaction
PaymentMethodNombre del método de pago en pagos (opcional; si falta, se usa valor por defecto).Setup – Accounting Lists
SubsidiaryMulti-entidad (OneWorld).Lists – Subsidiaries
Perform Search (Lists) debe estar en Full para que las consultas SuiteQL funcionen. Find Transaction (Transactions) permite consultar la tabla Transaction y TransactionLine para los tipos de transacción permitidos (Bills, Purchase Orders, etc.).

4.6 Acceso a subsidiarias

  1. En el mismo rol, ve a la subpestaña Subsidiaries (solo si la cuenta usa OneWorld).
  2. Elige All o las subsidiarias que gestionará la integración.
  3. Haz clic en Save.

5. Asignar el rol a un usuario

  1. Ve a Setup > Users/Roles > Manage Users y selecciona el usuario que tendrá el token (puede ser un usuario dedicado a la integración).
  2. En la subpestaña Access > Roles, agrega el rol Conexión Payana.
  3. Haz clic en Save.
Es buena práctica usar un usuario dedicado (ej. [email protected]) en lugar de una cuenta personal, para evitar invalidar el token si alguien deja la empresa.

6. Generar Access Tokens (Token ID y Token Secret)

  1. Ve a Setup > Users/Roles > Access Tokens > New.
  2. Completa:
    • Application Name: Selecciona Payana Integration (el Integration Record del paso 3).
    • User: Selecciona el usuario del paso 5.
    • Role: Selecciona Conexión Payana.
  3. Haz clic en Save.
  4. Copia de inmediato los valores mostrados:
    • Token ID
    • Token Secret
El Token Secret solo se muestra una vez al crear el token. Si se pierde, debes revocar el token y crear uno nuevo.

7. Resumen de valores para compartir con Payana

CampoDónde obtenerlo
Account IDSetup > Company > Company Information
Environment TypeProduction / Sandbox / Release Preview
Consumer KeySe muestra una vez al guardar el Integration Record
Consumer SecretSe muestra una vez al guardar el Integration Record
Token IDSe muestra una vez al guardar el Access Token
Token SecretSe muestra una vez al guardar el Access Token
Comparte estos seis valores por un canal seguro

8. Lista de verificación

  • Token-Based Authentication está habilitado en SuiteCloud.
  • Existe un Integration Record con TBA habilitado.
  • El rol “Conexión Payana” usa Classic Centre como Centre Type.
  • El rol tiene Web Services Only marcado en la subpestaña Authentication.
  • Permisos de Setup: Log in using Access Tokens, REST Web Services, User Access Tokens, SuiteAnalytics Workbook, y Accounting Lists en Full.
  • Permisos de transacciones (Nivel 1): Bills, Purchase Orders y Find Transaction en Full.
  • Permisos de transacciones (Nivel 2): Bill Purchase Orders, Enter Vendor Credits y Pay Bills en Full.
  • Permisos de listas (Nivel 1): Vendors, Subsidiaries, Accounts y Perform Search en Full.
  • Permisos de listas (Nivel 2): Items, Companies, Currency, Departments y Locations en Full.
  • Permisos por tabla SuiteQL (sección 4.5): acceso a Vendor, Item, Account, Department, Location, Transaction, TransactionLine y, si aplica, PaymentMethod.
  • El rol tiene configurado el acceso a subsidiarias (All o lista específica).
  • Un usuario de integración dedicado tiene asignado el rol.
  • Se ha creado el Access Token y se han copiado Token ID y Token Secret.
  • Las seis credenciales se han compartido con Payana de forma segura.
  • Se verificó el acceso con una solicitud de prueba (sección 9).

9. Validar la conexión (Opcional)

Una vez configuradas las credenciales, verifica que la integración tiene acceso correcto a NetSuite.

Con Postman (recomendado)

Postman maneja la firma OAuth 1.0 automáticamente, lo que lo hace la forma más sencilla de probar.
1

Crear una solicitud POST

Usa la siguiente URL, reemplazando ACCOUNT_ID por tu Account ID en minúsculas (usa guiones en lugar de guiones bajos para sandboxes):
https://ACCOUNT_ID.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql
Ejemplo producción: https://1234567.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql Ejemplo sandbox: https://1234567-sb1.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql
2

Configurar autenticación OAuth 1.0

En la pestaña Authorization:
CampoValor
TypeOAuth 1.0
Signature MethodHMAC-SHA256
Consumer KeyTu Consumer Key
Consumer SecretTu Consumer Secret
Access TokenTu Token ID
Token SecretTu Token Secret
RealmTu Account ID original (ej. 1234567 o 1234567_SB1)
Marca la opción Add params to header.
3

Agregar headers

En la pestaña Headers:
HeaderValor
Content-Typeapplication/json
Prefertransient
4

Enviar la consulta de prueba

En Body selecciona raw > JSON y pega:
{ "q": "SELECT id, companyName FROM entity WHERE ROWNUM <= 1" }
Haz clic en Send.

Respuesta esperada

Una respuesta 200 OK confirma que las credenciales y permisos están correctos:
{
  "count": 1,
  "hasMore": false,
  "items": [
    {
      "id": "123",
      "companyname": "Example Vendor"
    }
  ],
  "offset": 0,
  "totalResults": 1
}

Errores comunes

CódigoSignificadoQué revisar
401Credenciales inválidasVerifica que Consumer Key, Consumer Secret, Token ID y Token Secret sean correctos y no estén expirados.
403Permisos insuficientesEl rol no tiene los permisos necesarios. Revisa las secciones 4.2 a 4.5.
404Account ID o URL incorrectosConfirma el Account ID y que el formato de URL corresponda al entorno.
Copia el siguiente script, reemplaza los valores de credenciales al inicio, y pégalo directamente en una terminal (macOS, Linux o Windows con WSL/Git Bash).Requiere curl, openssl, python3 y base64.
# ── Credenciales (reemplaza estos valores) ──
ACCOUNT_ID_ORIG="YOUR_ACCOUNT_ID"       # ej. 1234567 o 1234567_SB1
CONSUMER_KEY="YOUR_CONSUMER_KEY"
CONSUMER_SECRET="YOUR_CONSUMER_SECRET"
TOKEN_ID="YOUR_TOKEN_ID"
TOKEN_SECRET="YOUR_TOKEN_SECRET"
        
# ── Derived values ──
ACCOUNT_ID_URL=$(echo "$ACCOUNT_ID_ORIG" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
REALM="$ACCOUNT_ID_ORIG"
URL="https://${ACCOUNT_ID_URL}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql"

# ── Query ──
# Test de conexión:
# QUERY="SELECT 1+1 AS result FROM DUAL"
# Test de vendors:
QUERY="SELECT id, entityid, companyname, email FROM vendor WHERE ROWNUM <= 10"

# ── OAuth 1.0 signature ──
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)

ENCODED_URL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${URL}', safe=''))")
PARAMS="oauth_consumer_key=${CONSUMER_KEY}&oauth_nonce=${NONCE}&oauth_signature_method=HMAC-SHA256&oauth_timestamp=${TIMESTAMP}&oauth_token=${TOKEN_ID}&oauth_version=1.0"
ENCODED_PARAMS=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${PARAMS}', safe=''))")

SIGNATURE_BASE="POST&${ENCODED_URL}&${ENCODED_PARAMS}"
SIGNING_KEY="${CONSUMER_SECRET}&${TOKEN_SECRET}"

SIGNATURE=$(printf '%s' "$SIGNATURE_BASE" | openssl dgst -sha256 -hmac "$SIGNING_KEY" -binary | base64 | tr -d '\n')
ENCODED_SIGNATURE=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${SIGNATURE}', safe=''))")

AUTH_HEADER="OAuth oauth_consumer_key=\"${CONSUMER_KEY}\",oauth_token=\"${TOKEN_ID}\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"${TIMESTAMP}\",oauth_nonce=\"${NONCE}\",oauth_version=\"1.0\",oauth_signature=\"${ENCODED_SIGNATURE}\",realm=\"${REALM}\""

# ── Execute request ──
curl -s -X POST "$URL" \
  -H "Authorization: ${AUTH_HEADER}" \
  -H "Content-Type: application/json" \
  -H "Prefer: transient" \
  -H "accept-language: en" \
  -d "{\"q\":\"${QUERY}\"}" \
  | python3 -m json.tool

Una vez que la consulta básica funcione, verifica acceso a los tipos de registro específicos que usa la integración:
-- Facturas de proveedor
SELECT id, tranId, entity FROM transaction WHERE type = 'VendBill' AND ROWNUM <= 1

-- Órdenes de compra
SELECT id, tranId, entity FROM transaction WHERE type = 'PurchOrd' AND ROWNUM <= 1

-- Proveedores
SELECT id, companyName FROM vendor WHERE ROWNUM <= 1

-- Subsidiarias (solo OneWorld)
SELECT id, name FROM subsidiary WHERE ROWNUM <= 1

-- Centros de costo (Departments)
SELECT id, fullname FROM department WHERE ROWNUM <= 1

-- Bodegas (Locations)
SELECT id, fullname FROM location WHERE ROWNUM <= 1
Si todas las consultas retornan resultados (o un array items vacío con status 200), las credenciales y permisos están correctamente configurados.