RPApos Gateway — External RPApos API
HTTP integration with tenant-hosted RPApos (*.2rpa.com). FlowPOS backend calls these URLs from RpaposHttpAdapter; the PWA never talks to RPApos directly (except public logo images).
Document version: 1.0 · Last updated: 2026-05
Base URLs
| Purpose | URL pattern |
|---|---|
| Tenant app | https://{subdomain}.2rpa.com |
| Tenant REST API | https://{subdomain}.2rpa.com/api/{path} |
| Public logo API | https://ys.2rpa.com/api/logo?subDominio={subdomain} |
Configure logo origin:
- Backend:
RPAPOS_LOGO_API_ORIGIN - PWA:
VITE_RPAPOS_LOGO_API_ORIGIN
Authentication
RPApos uses ASP.NET WebForms login, not OAuth.
-
GET https://{subdomain}.2rpa.com/Login
Parse hidden fields:__VIEWSTATE,__VIEWSTATEGENERATOR,__EVENTVALIDATION, and initial session cookies. -
POST https://{subdomain}.2rpa.com/Login
Content-Type: application/x-www-form-urlencoded
Fields:TextBoxUsername,TextBoxPassword,ButtonLogin=Login, plus viewstate fields. -
Success detection: Response HTML contains
localStorage.token = '<jwt>';
(HTTP status may still be 200 on failure.) -
Subsequent API calls send
Cookie:header from the session.
Invalid credentials → 401 UnauthorizedException from FlowPOS (not retried as infrastructure failure).
Subdomain reachability
ping(subdomain) — GET /Login with 5s timeout, any HTTP status accepted. Used by POST /rpapos/connections/probe-subdomain. Does not increment the circuit breaker.
Catalog entity endpoints
Relative to https://{subdomain}.2rpa.com/api/:
| Entity key | HTTP path | Notes |
|---|---|---|
moneda | Moneda | |
unidad_medida | UnidadMedida | |
plu_grupo | PLU/Grupo | |
sku_grupo | Producto/Grupo | |
produccion_grupo | Produccion/Grupo | |
bodega | Bodega | |
proveedor | Proveedor | |
area | area | lowercase path |
persona | Persona | |
sku | SKU | |
plu | PLU/Maestro | |
usuario | Usuario | |
batch_maestro | BatchMaestro | |
precio | PLU/Precio | Defined in adapter; not in planner catalog |
mesa | (special) | See below |
Mesa (tables)
There is no GET /api/Mesa list endpoint.
GET /api/area→ list of areas withId- For each area:
GET /api/Mesa/{areaId} - Results are concatenated into one array
Failures for a single area are logged and skipped; other areas still import.
Response shape
Adapter normalizes:
- Raw JSON array, or
{ "data": [ ... ] }wrapper
Empty or unknown shapes → [].
Rate limiting and reliability
| Control | Value |
|---|---|
| Rate limit | 5 requests/second per subdomain (in-memory token bucket) |
| Retries | 3 attempts, exponential backoff from 2s |
| Circuit breaker | Open after 5 consecutive failures → 503 until successes reset counter |
Distinction from RPAfelApi
| RPApos tenant API | RPAfelApi | |
|---|---|---|
| Host | {tenant}.2rpa.com | fel.rpapos.com |
| Purpose | POS catalog, login, operations | Guatemala electronic invoicing (FEL) |
| FlowPOS module | apps/backend/src/rpapos/ | FEL module + docs under dev/fel/rpafelapi/ |
Do not confuse the two when configuring URLs or writing support docs.
SAT credentials vs tenant web login
Tenant web ({sub}.2rpa.com) | SAT (satellite.rpapos.com / sat.2rpa.com) | |
|---|---|---|
| Used for | Catalog REST import (/api/*) | Product images via SOAP (Objeto_Archivo_1, Catalogo_4) |
| Validate | POST /rpapos/connections/probe | POST /rpapos/connections/probe-sat |
| Credentials | usuario + password on connection | sat_usuario + sat_password (optional columns; preferred for images) |
The mobile/SAT account is often not the same email/password as the tenant admin web login.
SOAP endpoints (product images)
| Host | URL | SOAPAction / body xmlns |
|---|---|---|
| db4 (shared gateway) | https://db4.2rpa.com/service.asmx | http://tempuri.org/{Method} |
| SAT (device registration) | https://sat.2rpa.com/service.asmx | http://localhost/{Method} |
FlowPOS registers a device with Dispositivo_Registra_2 on SAT (namespace http://localhost/, not tempuri.org). The returned token is stored encrypted and passed as pToken on db4 SOAP calls.
pUDID must be a UUID string (Guid.Parse on the SAT server).
Env overrides: RPAPOS_DB4_SOAP_URL, RPAPOS_SAT_SOAP_URL, RPAPOS_SAT_REST_URL.
Image import flow (FlowPOS)
- Register —
Dispositivo_Registra_2on SAT (pUDIDmust be a UUID string). Persistssoap_token_encryptedandestacion_trabajoonrpapos_connection. - Catalog links —
Objeto_Archivo_1lists image objects;Catalogo_4is called with threepTablavalues (Producto_U_M,viw_Producto_1,Producto) and the result with the most rows having bothCodigo_PLUpopulated andObjeto_Archivo > 0is used —Codigo_PLUis the key matched againstrpapos_id_map. - Download —
imgGrabHTTP endpoint per object id (session cookies from tenant login). InlinearchivoBase64fromObjeto_Archivo_1is used when available. - Upload — Matched FlowPOS products receive GCS-backed
imageUrl.
If step 2 returns no rows, the probe may classify the tenant as rest_only_unsupported (REST has image URLs but SOAP catalog is empty). FlowPOS does not import REST-only image URLs today.
Operator steps: Operator guide (Review → Import product images). Backend detail: Architecture (Product image import section).
SOAP catalog tables — modifier import
Three Catalogo_4 pTabla values are used to import product modifiers. All three require a registered SOAP token (soap_token_encrypted on rpapos_connection).
FlowPOS table index: Menus & Modifier Groups — All related tables.
Producto_Grupo — modifier group master
| RPApos field | Sample value | FlowPOS target (product_modifier_group) |
|---|---|---|
Producto_Grupo | "12" | id via rpapos_id_map(plu_option_group, …) |
Id | "12" | legacy/alternate PK column name |
Descripcion | "Extras" | name |
Minimo | "0" | min_selection |
Maximo | "3" | max_selection (null if absent) |
IdTipoGrupo | "1" | captured in raw blob only; not mapped to column |
auto_prompt is always set to false on import.
Producto_Grupo_Detalle — modifier items
Typical RPApos wire shape (confirmed from tenant DB / Catalogo_4):
| RPApos field | Sample value | FlowPOS target (product_modifier) |
|---|---|---|
Producto_Grupo_Detalle | "44" | id via rpapos_id_map(plu_option_item, …) |
Producto_Grupo | "1" | modifier_group_id (via id_map plu_option_group) |
Codigo_PLU | "PLU127" | linked_product_id (via id_map plu; unresolved → NULL) |
Orden | "4" | sort_order |
Producto_Atributo | "108" | not mapped today |
Producto | "130" | not mapped today |
Precio_Adicional | "5.0000" | price_adjustment when present; else 0 |
There is often no Descripcion on detail rows — name falls back to the linked product’s name when Codigo_PLU resolves.
Legacy/alternate names still accepted: Id, Id_Grupo, Id_PLU, Descripcion.
When linked_product_id is set, quantity_per_modifier is automatically set to 1 to satisfy the check constraint chk_modifier_inventory_link_consistency.
Producto_Grupo_Relacion — PLU↔group attachments
| RPApos field | Sample value | FlowPOS target (product_modifier_group_assignment) |
|---|---|---|
Codigo_PLU | "PLU88" | product_id (resolved via id_map plu) |
Id_PLU | "88" | legacy/alternate PLU reference |
Producto_Grupo | "12" | modifier_group_id (resolved via id_map plu_option_group) |
Id_Grupo | "12" | legacy/alternate group FK |
Unique constraint on assignment table: (product_id, modifier_group_id). There is no REST equivalent for this table — SOAP is the only source.
Note: This pTabla is only available via SOAP (
Catalogo_4). There is no REST equivalent (/api/Producto/Grupo/Relaciondoes not exist).