Skip to main content

Integración Payments

Prueba peticiones firmadas en el navegador en el Sandbox de la API — pega tu API key y secret, y el playground firma las peticiones automáticamente.
Los ejemplos siguientes muestran el header en formato wire Authorization: P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE. Para calcular la firma en tu código, usa el helper signedRequest en Autenticación.
La integración Payments es una API REST agnóstica de proveedor para las operaciones financieras esenciales que todo backoffice necesita:
  1. Emitir Invoice (cobro)POST /payments/invoices. Una Invoice aquí es una solicitud de pago — un cobro recolectado vía PIX, boleto, tarjeta, ACH o SEPA según la región.
  2. Cancelar InvoicePOST /payments/invoices/{id}/cancel (anula cobros no pagados).
  3. Emitir documento fiscal (NFS-e/NF-e/PEPPOL)POST /payments/invoices/{id}/tax-documents. Opcional, específico por región (Brasil hoy, Europa después). También puede ser auto-emitido al crear la Invoice.
  4. Pagar a beneficiario (premio o cualquier payout)POST /payments/payouts.
  5. Leer un extracto bancarioGET /payments/balance-transactions.
Toda transacción lleva campos de control de primer nivel usados por tu equipo financiero para conciliación: cost_center (centro de costos) y contractor_reference (referencia del contratante) los envías en el request; our_number (nuestro número) lo genera SalesOS y se devuelve en el response (y en cada movimiento del extracto). Por debajo, SalesOS rutea la solicitud al proveedor correcto — no necesitas elegir el proveedor a menos que quieras.
Cobro ≠ documento fiscal. Una Invoice es la solicitud de pago (boleto, PIX, tarjeta). El documento fiscal (NFS-e en BR, PEPPOL en UE) es un recurso separado y opcional adjunto a la Invoice. Esta separación mantiene la API portable entre BR / US / UE.
La API sigue convenciones de mercado: modelo REST por recurso, montos en unidades menores enteras, timestamps ISO-8601, RFC 9457 Problem Details para errores, header Idempotency-Key para reintentos seguros, paginación por cursor y webhooks firmados. Si ya integraste con cualquier API moderna de pagos, te sentirás como en casa.

Ruteo por Región

SalesOS elige el backend correcto automáticamente a partir de customer.country y currency. No necesitas escoger. Los payouts rutean por destino: BRL → PIX cashout; otras monedas → transferencia internacional.

Cómo Funciona

  1. Obtienes una API Key en el Dashboard de SalesOS (Admin > Integraciones > API Keys) con los scopes correctos (payments:write, payments:read).
  2. Emites Invoices (cobros). SalesOS crea la solicitud de pago en la región del cliente (BR activo; US/UE próximamente). Recibes un artefacto pagable: QR-code/copia-pega PIX, código de barras de boleto, URL de checkout de tarjeta.
  3. (Opcional) Se adjunta un documento fiscal. Cuando currency = BRL y configuras tax_document.auto_issue: true, SalesOS emite una NFS-e automáticamente tras la confirmación del pago. También puedes llamar a POST /invoices/{id}/tax-documents después para emitir o reintentar.
  4. Pagas a beneficiarios (empleados, partners, ganadores de premios). SalesOS rutea pagos BRL via PIX y otras monedas via transferencia internacional.
  5. Lees un extracto unificado — toda factura, payout, comisión y fee de documento fiscal en un único libro mayor, filtrable por cost_center, our_number, contractor_reference, período y proveedor.
  6. Escuchas webhooks para eventos terminales (invoice.paid, invoice.canceled, tax_document.issued, payout.paid, …) en lugar de hacer polling.

Inicio Rápido

1

Obtener tu API Key

Ve a Admin > Integraciones > API Keys en el Dashboard de SalesOS. Crea una nueva clave con los scopes payments:write y payments:read. Copia la clave — solo se mostrará una vez.Tu clave luce así: sk_live_a1b2c3d4e5f6g7h8i9j0...
2

Emite tu primera Invoice (BR — cobro PIX con NFS-e automática)

Crea un cobro PIX para un cliente brasileño. El bloque opcional tax_document indica a SalesOS que emita la NFS-e automáticamente tras el pago.
Respuesta (201 Created):
El status pasa por openpaid (en la confirmación PIX, ~segundos) → tax_document.status: issued (emisión de NFS-e, segundos a minutos). Escucha los webhooks invoice.paid y tax_document.issued en vez de hacer polling.
3

(Opcional) Emite una Invoice para cliente US (próximamente)

Para clientes US/UE SalesOS rutea el cobro hacia el backend internacional. Esta ruta queda en cola tras el onboarding de Play2Sell LLC — las llamadas hoy devuelven 501 provider_not_configured.
Sin bloque tax_document — US no tiene documento fiscal nacional. Sales tax va en metadata o futuros line_items. El SSN del cliente no se recoge en este endpoint: los cobros B2C/B2B regulares en EE.UU. no lo requieren. El manejo de SSN/EIN para reporting 1099 (cuando pagas a contractors US) es un flujo separado en Payouts, no en Invoices.
4

Pagar a un beneficiario

Paga a un ganador de premio via PIX (BRL — ruteo automático):
Respuesta (201 Created):
Recibirás un webhook payout.paid en segundos en sandbox o en menos de un minuto en producción (PIX).
5

Leer tu extracto

Lista cada movimiento etiquetado con cost_center=CC-AWARDS del mes:
Respuesta (200 OK):

Autenticación

Todas las solicitudes requieren una API Key en el header Authorization:
Consulta la página de Autenticación para detalles sobre cómo crear y administrar API Keys.

Entornos

URL Base: https://api.play2sell.comDashboard: https://dashboard.play2sell.com

Referencia de Endpoints

Path base: /functions/v1/payments. Todos los endpoints aceptan y devuelven JSON.

Invoices (Cobros)

Una Invoice es un cobro — una solicitud de pago que se recolectará de tu cliente vía PIX, boleto, tarjeta u otro método según la región. La Invoice no incluye un documento fiscal por defecto; ver Tax Documents abajo.

POST /functions/v1/payments/invoices — crear un cobro

object
requerido
Cliente que será cobrado.
string
requerido
ISO-3166-1 alpha-2 (BR, US, DE, …). Decide el ruteo de proveedor.
string
CPF (11 dígitos) o CNPJ (14 dígitos) para BR (obligatorio cuando tax_document está presente). Para cobros US/UE este campo no es obligatorio — déjalo fuera salvo que tu flujo contable lo necesite. SSN/EIN no se recolectan aquí en cobros normales.
string
requerido
Razón social o nombre completo (max 255 caracteres).
string
requerido
Email válido — se usa para recibos y (cuando aplique) la entrega del documento fiscal.
string
Teléfono opcional (max 20 caracteres). Formato E.164 recomendado (p. ej. +5511999000111). Algunos proveedores lo usan para emparejamiento AML/KYC y notificaciones transaccionales.
integer
requerido
Monto total en unidades menores (ej: 12345 = R$ 123,45). Debe ser positivo.
string
requerido
Código ISO-4217. Decide el ruteo de proveedor junto con customer.country.
string
requerido
Descripción que aparece en el artefacto de pago y (cuando se emite) en la discriminación del documento fiscal (max 1000 caracteres).
El campo description se muestra al pagador. En cobros PIX aparece en la app bancaria/billetera del pagador junto al código QR; en boleto se imprime en el comprobante; en NFS-e va en la discriminación del servicio. Elige un valor que tenga sentido en los tres contextos (ej: "Consultoría — Abril/2026", no "INV-2026-000123 fila-billing-interna").
object
requerido
Cómo se recolectará el cobro.
string
requerido
Uno de pix, boleto, bolepix, card (BR); card, ach_debit, bank_transfer (US — próximamente); card, sepa_debit, bank_transfer (UE — próximamente).
integer
Para pix / boleto / bolepix: tiempo de validez del artefacto. Por defecto 3600 (PIX) / 3 días (boleto).
string
Para card: a dónde redirigir al cliente tras el checkout.
object
Opcional. Cuando está presente, SalesOS emitirá un documento fiscal automáticamente tras el pago. Hoy solo BR.
boolean
Cuando true, el documento fiscal se emite al transitar a paid. Cuando false (u omitido), usa POST /v1/invoices/{id}/tax-documents después.
string
"nfse" (servicios BR — activo), "nfe" (productos BR — próximamente), "peppol" (UE — próximamente).
string
Código municipal de servicio, obligatorio cuando type="nfse" (ej: "01.05" para consultoría en SP).
string
Código de centro de costos interno (max 64 caracteres). Opcional — cuando se omite, el cobro se clasifica en el centro de costos por defecto del tenant. Enviar un código no registrado retorna 422 unknown_cost_center. Ver Campos de Control Comunes.
string
Referencia del contratante — referencia externa del cliente/contrato (max 64 caracteres).
object
Pares clave-valor libres (max 50 claves, valor max 500 caracteres).
our_number (nuestro número) no va en el request — SalesOS lo genera al emitir y lo devuelve en el response (formato: INV-<AAAA>-<secuencia>). Almacénalo para conciliación.

GET /functions/v1/payments/invoices/{id} — consultar

La respuesta siempre incluye el artefacto actual de payment_method (QR PIX, código de barras de boleto, URL de checkout) y el resumen inline de tax_document cuando existe.

GET /functions/v1/payments/invoices — listar

Filtros: status (open|paid|canceled|failed), payment_method.type, cost_center, our_number, contractor_reference, created[gte], created[lte]. Paginación por cursor mediante limit (≤ 100), starting_after, ending_before.

POST /functions/v1/payments/invoices/{id}/cancel — anular cobro no pagado

Si la Invoice tiene un tax_document adjunto en estado issued, el cancelamiento se cascada al documento fiscal cuando el municipio aún está dentro de la ventana de cancelación. De lo contrario devuelve cancellation_window_expired.
El reembolso de cobros pagados no está expuesto en la v1. Si necesitas revertir un pago ya liquidado, contacta al soporte — el equipo puede procesarlo manualmente. Una versión futura de la API podría exponer un flujo de reembolso programático conforme los casos de uso maduren.

Tax Documents (Documentos Fiscales)

Un TaxDocument es el artefacto fiscal adjunto a una Invoice — hoy NFS-e (servicios BR). Tiene su propio ciclo de vida y puede emitirse, consultarse o cancelarse independientemente del cobro subyacente. Usa este recurso cuando optaste por no usar auto_issue al crear la Invoice, cuando un intento de auto-emisión falló y quieres reintentar, o cuando necesitas cancelar solo el documento fiscal.

POST /functions/v1/payments/invoices/{id}/tax-documents — emitir/reintentar

string
requerido
"nfse" hoy. Futuro: "nfe", "peppol".
string
Obligatorio cuando type="nfse".
object
Metadata libre opcional, persistida en el documento.
Respuesta (202 Accepted):
La emisión es asíncrona. Escucha los webhooks tax_document.issued (o tax_document.failed). En éxito el documento trae document_number, xml_url, pdf_url e issued_at.

GET /functions/v1/payments/invoices/{id}/tax-documents/{doc_id} — consultar

POST /functions/v1/payments/invoices/{id}/tax-documents/{doc_id}/cancel — cancelar

Sujeto a la ventana de cancelación del municipio (típicamente el día de la emisión para NFS-e). cancellation_window_expired se devuelve fuera de la ventana.

Payouts (Pagos a Beneficiarios)

POST /functions/v1/payments/payouts — pagar a un beneficiario

Ruteo automático: currency = "BRL" → PIX cashout; otras monedas → transferencia internacional.
object
requerido
Destinatario del payout.
string
requerido
Nombre completo o razón social (max 255 caracteres).
string
requerido
Documento de identificación fiscal del beneficiario. CPF (11 dígitos) o CNPJ (14 dígitos) para BR; pasaporte o ID fiscal local para internacional. Obligatorio.
string
requerido
Teléfono en formato E.164 (ej: "+5511999000111"). Obligatorio — usado para AML/KYC y notificaciones de estado del payout.
string
Email opcional. Cuando se provee, los recibos del payout se envían a esta dirección.
object
requerido
Cuenta destino. Para PIX usa type: "pix" con key_type (cpf|cnpj|email|phone|evp) y key. Para internacional usa type: "bank_transfer" con country, iban o account_number + routing_number según los requisitos bancarios del país de destino.
integer
requerido
Monto en unidades menores. Debe ser positivo.
string
requerido
ISO-4217. Determina el ruteo de proveedor.
string
requerido
Uno de "prize", "commission", "vendor_payment", "other".
string
Código de centro de costos (max 64 caracteres). Opcional — cuando se omite, el payout se clasifica en el centro de costos por defecto del tenant. Enviar un código no registrado retorna 422 unknown_cost_center.
string
Referencia del contratante — referencia externa (max 64 caracteres).
object
Pares clave-valor libres (max 50 claves, valor max 500 caracteres).
our_number (nuestro número) no va en el request — SalesOS lo genera al emitir y lo devuelve en el response (formato: PO-<AAAA>-<secuencia>). Almacénalo para conciliación.

GET /functions/v1/payments/payouts/{id} — consultar

GET /functions/v1/payments/payouts — listar

Filtros: status, provider, cost_center, our_number, contractor_reference, created[gte], created[lte]. Paginación por cursor.

POST /functions/v1/payments/payouts/{id}/cancel — cancelar

Disponible solo para transferencias internacionales en estado created / incoming_payment_waiting. PIX es síncrono y final — una vez aceptado no se cancela; emite un payout en sentido opuesto como reverso.

Balance Transactions (Extracto Bancario)

Libro mayor unificado entre proveedores. Solo lectura.

GET /functions/v1/payments/balance-transactions — listar

Filtros:

GET /functions/v1/payments/balance-transactions/{id} — consultar

Cada movimiento expone:
string
ID estable del movimiento (btxn_...).
string
charge | payout | fee | adjustment.
integer
Monto en unidades menores con signo. Negativo = salida, positivo = entrada.
string
ISO-4217.
integer
amount - fee para salidas; amount para entradas.
integer
Comisión del proveedor en unidades menores, siempre positiva.
string
Fecha ISO-8601 de liquidación de los fondos.
string
Timestamp ISO-8601 del movimiento.
object
{ resource, id } — apunta a la factura/payout origen.
string
Heredado del recurso de origen.
string
Heredado del recurso de origen.
string
Heredado del recurso de origen.

Campos de Control Comunes

Toda Invoice, Payout y Balance Transaction lleva los mismos campos de control. Hacen round-trip en GET y son filtrables en LIST.
Por qué our_number lo genera el servidor. En el banking brasileño el cedente asigna el “nuestro número” — pero en esta API SalesOS es el gateway de emisión, así que SalesOS asigna el valor y lo devuelve. Si necesitas llevar tu identificador interno, usa contractor_reference (top-level, indexado) o metadata.* (libre).

Idempotencia

Todos los endpoints POST requieren el header Idempotency-Key — una cadena única a tu elección (max 255 caracteres; recomendamos UUIDv4 o una clave determinística derivada de tu dominio).
  • La primera llamada con la clave procesa normalmente y la respuesta se almacena por 24 h.
  • Reintentos con la misma clave y el mismo body devuelven la misma respuesta, con el header Idempotent-Replay: true.
  • Reintentos con la misma clave pero body distinto devuelven 409 idempotency_key_reused.

Montos y Moneda

Los montos son enteros en unidades menores para evitar errores de punto flotante: Las monedas siguen ISO-4217 (3 letras mayúsculas). Siempre acompaña amount con currency. Rechaza en el servidor cualquier payload que mezcle escalas (ej: enviar decimales).

Manejo de Errores

Todos los errores siguen RFC 9457 Problem Details:
JSON malformado o headers obligatorios ausentes. Corrige la solicitud y reenvía.
API key faltante, inválida o expirada. Verifica el header Authorization. Genera una clave nueva si expiró.
Clave válida pero sin el scope requerido (payments:write o payments:read). Edita la clave en el Dashboard.
El ID del recurso no existe o pertenece a otro tenant.
Misma Idempotency-Key usada con body distinto. Usa una clave nueva o reenvía el body original.
La solicitud fue entendida pero no puede procesarse. Inspecciona el campo code para desambiguar:
  • validation_error — la validación del body falló; el array errors[] lista los problemas a nivel de campo. Corrige los datos y reenvía con Idempotency-Key nueva.
  • unsupported_region — la combinación country / currency del cliente aún no está habilitada (hoy solo BR / BRL está activo). Espera a que la región esté disponible, o cobra a un cliente en una región soportada.
  • unknown_cost_center — el código cost_center enviado no está registrado para tu tenant. Créalo en Admin > Integraciones > Centros de Costo antes de reenviar, u omite el campo para usar el centro de costo por defecto del tenant.
  • merchant_not_provisioned — tu tenant no tiene un merchant de pago activo para el centro de costo resuelto. Contacta al soporte para finalizar el provisionamiento antes de reintentar.
Demasiadas solicitudes. El header Retry-After indica los segundos a esperar.
El backend downstream devolvió error. El campo detail contiene un mensaje sanitizado. Reenvía con la misma Idempotency-Key.
Error interno. Reenvía con backoff exponencial (2s, 4s, 8s). Contacta al soporte si persiste.

Webhooks

Configura un endpoint de webhook por entorno en Admin > Integraciones > Webhooks. SalesOS hará POST con JSON firmado para cada evento terminal: Cada solicitud incluye:
  • X-Pay-Event — tipo del evento (ej: payout.paid).
  • X-Pay-Signaturet=<unix>,v1=<hex-hmac-sha256>. Verifica con el secreto configurado en el Dashboard.
  • X-Pay-Delivery — ID único de entrega, útil para deduplicación.
Verificación de firma (Node.js):
Payload de ejemplo:

Ejemplos Completos de Código


Mejores Prácticas

Higiene de centros de costos

Elige un conjunto pequeño y estable de códigos (≤ 50). Documéntalos en el wiki de finanzas. Rechaza en el servidor llamadas que referencien códigos desconocidos — fallar ruidosamente es mejor que clasificar mal en silencio.

Usa ambas claves juntas para conciliación

  • our_number (generado por el servidor) es tu clave bancaria — impreso en el boleto / enviado al proveedor, presente en tu archivo de extracto bancario.
  • contractor_reference (lo proporcionas) es tu clave de contrato — el PO, ID de contrato con vendor o ID del evento referente; presente en tu ERP.
Cruzar ambas en el cierre mensual te da una conciliación de un clic entre el banco, la API Payments de SalesOS y tu ERP.

Ruteo por región

SalesOS rutea automáticamente por customer.country y currency. No necesitas escoger backend; confía en el ruteo.

Confiabilidad de webhooks

Trata los webhooks como fuente de verdad para estados terminales. El polling funciona pero consume rate limit. Verifica siempre X-Pay-Signature y deduplica por X-Pay-Delivery.

Manejo de fallos

  • 422: corrige los datos y reenvía con Idempotency-Key nueva.
  • 429: espera según Retry-After.
  • 502 (provider_error): reenvía con la misma Idempotency-Key — la solicitud original no hizo commit, así que reintentar es seguro.
  • 5xx: backoff exponencial (2s, 4s, 8s). Contacta al soporte si persiste.

Límites de Solicitudes

Cada API key tiene un límite configurable (por defecto: 1000 solicitudes por hora). El contador se reinicia cada hora. Las respuestas con rate limit incluyen el header Retry-After (segundos).

Seguridad

  • Las API keys se hashean con bcrypt — nunca se almacenan en texto plano.
  • Cada clave está limitada a un único tenant — sin acceso entre tenants.
  • Se pueden configurar listas de IPs permitidas por clave.
  • Todas las solicitudes se registran con fines de auditoría (inmutable, retención de 7 años).
  • Las claves pueden revocarse instantáneamente desde el Dashboard.
Nunca expongas tu API key en código del lado del cliente (JavaScript en el navegador, apps móviles o repositorios públicos). La API Payments solo debe ser llamada desde tu servidor backend.

Próximos Pasos

Autenticación

Aprende a crear y administrar API Keys

Integración Activities

Envía actividades de CRM a SalesOS

Soporte

¿Necesitas ayuda? Contacta a nuestro equipo de soporte