ROKIConnect
Conectores Empezar API SDK Migrar MCP Portal EN

Migrar desde otra pasarela

La costumbre se viene con el codigo. Estos 70 nombres de campo de Stripe y Mercado Pago estan mapeados a como se llaman en ROKI, o a un honesto "no existe equivalente, hace esto en su lugar".

Importa mas de lo que parece: este API acepta un campo que no existe, responde 201 y lo ignora. Un nombre traido de otra pasarela no falla, funciona a medias. La respuesta trae un arreglo warnings que nombra cada campo descartado - esta ausente cuando el cuerpo va limpio, asi que leerlo es la comprobacion mas barata que hay.

Desde PixelPay

La diferencia grande no es un nombre de campo: es que a ROKI no le llega el numero de tarjeta. El SDK de PixelPay recibe card_number, card_cvv y card_holder y los manda desde tu servidor; en ROKI el numero se escribe en una superficie de ROKI -el checkout alojado o el iframe que incrusta tu tienda- y tu servidor nunca lo ve. Si estas portando el camino que arma esa peticion, ese camino se borra entero, y con el casi todo lo que PCI te exige. Los nombres de abajo salen de su SDK publicado (@pixelpay/sdk-core 2.5.7), que es la fuente que se puede leer y verificar.

EscribisteEn ROKIQue hacer
customer_emailcustomer.emailEn Stripe y en PixelPay esto es "customer_email"; en ROKI es "customer.email". En ROKI vive dentro del objeto opcional de prellenado customer (customer.email, junto a name, phone, identity_number), no crea ningún registro de cliente, sigue siendo editable a menos que también mandés lock_customer_fields: true, y se devuelve como eco...
order_amountamountLos dos van en unidades decimales, asi que el valor no cambia - pero PixelPay lo manda como texto y el campo de ROKI es numerico. ROKI tambien acepta numeros en texto, asi que no va a fallar; es el unico campo de esta migracion que pasa casi intacto.
order_idexternal_referenceROKI no exige que sea unico: la proteccion contra duplicados viene de la cabecera Idempotency-Key, no de este campo. Si dependias de que PixelPay rechazara un order_id repetido, esa comprobacion ya no ocurre y tenes que mandar la cabecera.
order_currencycurrency_codeUn codigo de tres letras lo rechaza el patron. Ademas toma por omision la moneda de la terminal, asi que la mayoria de las integraciones puede no mandarlo.
order_notedescriptionSi te pasas es un 422, no un recorte.
order_callbacksuccess_urlDiferencia importante: llegar a success_url NO significa que el pago ocurrio - significa que el navegador volvio. Lo unico que confirma que el dinero se movio es el webhook firmado. Si tu integracion de PixelPay acreditaba la orden en el callback, esa logica tiene que mudarse al webhook.
order_tax_amountsales_tax_valueMandar el valor sin el tipo es la forma de que el impuesto salga mal en silencio.
order_extrasmetadataLa misma idea: pares clave/valor tuyos, devueltos intactos al consultar y en cada webhook, y nunca visibles para el cliente.
order_shipping_amountno existeSumale el envio vos mismo a "amount": ROKI cobra exactamente el monto que le mandas, y no hay nada que le agregue una linea encima.
order_contentno existeSe cobra solo el total. Guarda el detalle del carrito de tu lado y poné un rotulo legible en "name".
customer_namecustomer.nameEn PixelPay esto es "customer_name"; en ROKI va adentro del objeto "customer", como "customer.name". Es el campo mas peligroso de toda la migracion: ROKI tambien tiene un "name" de primer nivel, pero ese es el ROTULO del pago que el cliente lee en el checkout, no el comprador. Poner ahi el nombre del comprador devuelve 201 y funciona - y cada cliente ve su propio nombre donde deberia ir la descripcion de la orden.
customer_identificationcustomer.identity_numberEn PixelPay esto es "customer_identification"; en ROKI es "customer.identity_number". Ademas es el identificador preferido para listar las tarjetas guardadas de un cliente, asi que conviene mandarlo aunque el checkout no lo necesite.
billing_phonecustomer.phoneEn PixelPay esto es "billing_phone"; lo mas parecido en ROKI es "customer.phone". ROKI no tiene bloque de facturacion: los demas campos billing_* no tienen a donde ir.
billing_addressno existeEl checkout alojado de ROKI tiene su propia seccion de facturacion opcional que el mismo recoge, y el API no acepta ninguno de estos al crear. Sacalos de tu peticion.
card_numberno existeROKI nunca recibe datos de tarjeta por este API - ni en este campo ni en ningun otro. El numero se escribe en una superficie de ROKI: el checkout alojado, o el iframe que tu tienda incrusta. Si estas portando codigo que manda un PAN a tu propio servidor, ese camino entero desaparece, y con el casi todo lo que PCI te exige.
card_tokenno existeROKI soporta tarjetas guardadas, pero Connect no expone cobrar con una desde el API: el cliente elige su tarjeta guardada en el checkout de ROKI. Los cobros recurrentes sin el cliente presente se habilitan por comercio y todavia no son parte de esta superficie.
payment_uuidtransaction_idDos cosas muerden aca. NO es el "id" numerico que te dan al crear: pasarlo a esas rutas devuelve 404 con code "transaction_id_expected". Y aparece cuando se INTENTA el cobro, no cuando sale bien: un pago puede estar pendiente y ya traer transaction_id, asi que "tiene transaction_id" NO quiere decir "se pago". Mira el status. Sobre un pago asi las rutas se niegan con claridad: receipt_unavailable y void_invalid.
void_reasonno existeLa anulacion de ROKI no recibe ninguno de los dos: el transaction_id en la URL es toda la peticion. Si guardas un motivo para tus propios registros, guardalo de tu lado.
installment_typeno existeROKI Connect no expone cuotas. No los mandes: el API devuelve 201 y los nombra en "warnings", asi que un plan que creias vendido nunca se aplico.
points_redeem_amountno existeROKI Connect no tiene equivalente. Restale el descuento que quieras a "amount" antes de mandarlo.
authentication_requestno existeEn ROKI no se pide: 3DS2 corre en el checkout de ROKI cuando la tarjeta y el monto lo ameritan. No hay campo para encenderlo, y no hay nada que portar.
apple_payno existeROKI Connect no expone esas billeteras. Mandarlas da 201 con el campo nombrado en "warnings" - el cobro sale como un pago con tarjeta normal.
tap_to_pay_deviceno existeROKI Connect es un API de pagos en linea y no expone Tap to Pay. No hay nada que mapear: es otro producto, no otro nombre de campo.
customer_fingerprintno existeROKI no tiene campo equivalente: el checkout corre en la pagina de ROKI, asi que las senales que necesita las recoge ahi en vez de confiar en un valor que manda tu servidor.
secure_payloadno existeEn ROKI ese ida y vuelta ocurre adentro del checkout de ROKI, asi que no hay payload que llevar ni paso que reproducir.
sourceno existeROKI no tiene ese campo, pero "metadata" acepta lo que quieras guardar: pone ahi tu canal y vuelve intacto al consultar y en cada webhook.

Desde Stripe

EscribisteEn ROKIQue hacer
amountamountMismo nombre, distinta unidad: el amount de ROKI va en unidades decimales (1500.00 = L 1,500.00, mínimo 0.01), así que dividí el entero de Stripe entre 100 antes de mandarlo, y aplicá tu propio tope porque ROKI no impone máximo y crearía en silencio un...
amount_centsamountROKI no tiene campo de centavos en ningún lado: convertí a unidades decimales y mandá amount; este es uno de los pocos nombres equivocados que falla con ruido en vez de en silencio, devolviendo 422 'El campo amount es obligatorio.' porque amount es obligatorio.
currencycurrency_codePOST /payments quiere el código *numérico* ISO 4217 como string ('340' = HNL), no el alfabético; la forma alfabética ('HNL') se acepta solo en /payments/token-charge, /payment-methods/{id}/charge y /confirm, y la respuesta hace eco de...
payment_method_typesno existeROKI es solo tarjeta y el modo de integración se elige según el endpoint que llamás - POST /payments para el checkout hospedado, POST /confirm para campos de tarjeta embebidos, POST /payment-methods/{id}/charge para una tarjeta guardada - así que eliminá el campo por completo,...
success_urlsuccess_urlNombre idéntico en POST /payments, pero el endpoint de componentes embebidos POST /confirm lo llama success_redirect_url; solo se acepta http/https (los esquemas de app personalizados como myapp:// devuelven 422), y que un cliente caiga ahí nunca es prueba de...
cancel_urlcancel_urlMismo nombre en POST /payments; el equivalente en componentes embebidos es failed_redirect_url en POST /confirm, que significa 'el cargo falló', no 'el cliente se echó para atrás', así que los dos no son intercambiables.
customer_emailcustomer.emailEn Stripe y en PixelPay esto es "customer_email"; en ROKI es "customer.email". En ROKI vive dentro del objeto opcional de prellenado customer (customer.email, junto a name, phone, identity_number), no crea ningún registro de cliente, sigue siendo editable a menos que también mandés lock_customer_fields: true, y se devuelve como eco...
metadatametadataMismo nombre y mismo propósito - se devuelve intacto al consultarlo y en cada webhook, nunca se le muestra al cliente - pero tiene que ser un objeto JSON o te da 422 ('El campo metadata debe ser un array.'), y cuando no mandás ninguno ROKI puede devolver...
client_reference_idexternal_referenceEl external_reference de ROKI es obligatorio (máx 191) y, a pesar del nombre, NO es único - dos creaciones con el mismo valor producen dos links pagaderos por separado - así que la protección contra duplicados tiene que venir de Idempotency-Key; podés filtrar por él...
capture_methodno existeROKI no separa autorización y captura y no tiene endpoint de captura - todo cargo aprobado se captura de inmediato - así que expresá en su lugar la reversión: intentá POST /payments/{transaction_id}/void (solo monto completo, antes de liquidar) y recurrí a POST...
receipt_emailno existeROKI nunca envía un recibo por correo desde el API: consultá GET /payments/{transaction_id}/receipt para obtener el receipt_url público (o /receipt/download para el PDF) y entregalo vos mismo - y tené presente que customer.email solo prellena el formulario del checkout,...
setup_future_usageno existeNo podés pedir el guardado de la tarjeta desde el API de ROKI de ninguna manera - el cliente tiene que marcar 'save my card' en el checkout propio de ROKI, tras lo cual el webhook payment_method.saved entrega un pm_* opaco que después cobrás vía POST...
payment_intenttransaction_idROKI divide esto en dos identificadores: el id numérico para GET /payments/{id}, y el UUID transaction_id - null hasta que el pago realmente se cobra - que es el que requieren void, refund y los recibos; pasar el id numérico a esas rutas...
customerno existeROKI no tiene recurso Customer ni ids de cliente, así que no hay nada que pasar aquí - identificá a las personas por los datos mismos: mandá el objeto inline de prellenado customer (name, email, phone, identity_number) en POST /payments, y buscá lo guardado...
descriptiondescriptionMismo nombre pero limitado a 120 caracteres en ROKI, y no es la etiqueta que el cliente ve en el checkout - esa es name, el campo obligatorio (máx 191) para el que Stripe no tiene equivalente, así que una migración directa deja tu página de checkout sin etiqueta.
statement_descriptorno existeROKI no expone descriptor de estado de cuenta por pago - viene de la configuración de la terminal del comercio - así que quitá el campo en vez de mandarlo, porque se ignoraría en silencio con un 201; name y description solo afectan lo que el...
line_itemsno existeROKI recibe un solo total ya calculado: sumá el carrito en tu propio backend y mandá amount en unidades decimales más una única etiqueta name, guardá el desglose por línea en metadata para conciliación, y usá sales_tax_type/sales_tax_value cuando necesités...
modeno existeROKI no tiene parámetro mode ni motor de suscripciones - POST /payments es siempre un checkout hospedado de pago único - así que manejá el cobro recurrente desde tu propio scheduler llamando a POST /payments/token-charge con un payment_token guardado en cada ciclo,...
urlcheckout_urlROKI devuelve checkout_url en el 201 de POST /payments - redirigí al string exacto que devuelve y nunca hardcodeés el dominio o el slug, ni los metás en lista de permitidos ni los validés con patrones, porque el valor real (aura.roki.systems/pay/link/{12 caracteres en minúsculas...
amount_totaltotalEl total de ROKI es la cifra autoritativa y va en unidades decimales (subtotal + sales_tax_amount + service_fee_amount) - leelo de la respuesta en vez de recalcularlo, y acordate de que la propina la elige el cliente en el checkout, así que el amount...
expires_atexpires_atMismo nombre, formato completamente distinto: ROKI quiere un string como '2026-08-13 18:00:00' (o ISO 8601) en hora local de Honduras UTC-6 sin marcador de offset y tiene que estar en el futuro o te da 422 - pasar un timestamp Unix, o parsear el...
payment_methodpayment_tokenLas tarjetas guardadas de ROKI llevan el mismo prefijo pm_, lo que hace de este la suposición equivocada más convincente de la migración: el campo es payment_token en el cuerpo de POST /payments/token-charge (o el segmento de ruta {payment_method_id} de POST...
application_fee_amountno existeROKI no tiene campo de comisión de plataforma o marketplace; su única bandera de comisión es el booleano service_fee_enabled, que significa algo distinto - le traslada al cliente los costos de procesamiento propios de ROKI mediante cálculo inverso para que al comercio le quede neto amount...
localeAccept-LanguageROKI no tiene campo en el cuerpo para esto - mandá en su lugar el header Accept-Language: es|en (español es el default si el valor falta, está vacío o no está soportado) - pero fijate en su alcance más limitado: localiza solo los mensajes del API y de validación, el ruteo...

Desde Mercado Pago

EscribisteEn ROKIQue hacer
itemsno existeROKI no tiene líneas de detalle en absoluto - sumá el carrito en tu propio backend y mandá un solo amount, y si necesitás conservar el desglose ponelo en metadata, que ROKI devuelve intacto al consultarlo y en cada webhook.
unit_priceno existeEn ROKI no existe nada por unidad - multiplicá por quantity, sumá todos los ítems, y mandá el resultado como amount (unidades decimales, mínimo 0.01, el API no impone máximo, así que poné el tope de tu lado).
quantityno existeIncorporá quantity al total antes de llamar a ROKI, y nunca dejés la key en el cuerpo como un extra por las dudas: ROKI ignora en silencio los campos desconocidos y devuelve 201 igual, así que el error es invisible.
transaction_amountamountEl calce 1:1 más cercano de toda la migración - también unidades decimales y no centavos (150.50 = L 150.50), también obligatorio, mínimo 0.01 - pero ROKI puede sumar encima impuesto de venta, propina y comisión de servicio, así que la cifra autoritativa de lo cobrado es total en el...
payercustomerEl customer de ROKI acepta solo name, email, phone e identity_number (sin surname ni address), y es solo un PRELLENADO del checkout hospedado que el cliente todavía puede editar a menos que también mandés lock_customer_fields: true.
external_referenceexternal_referenceNombre idéntico pero OBLIGATORIO en ROKI (máx 191) y explícitamente NO único - mandarlo dos veces sin Idempotency-Key crea dos pagos pagaderos por separado - y se puede filtrar vía GET /payments?external_reference=.
notification_urlno existeLos webhooks de ROKI no son por pago - registrá la URL del endpoint y copiá su secreto de firma una vez por ambiente en https://aura.roki.systems/merchant/connect/webhooks, y después verificá el HMAC-SHA256 de ROKI-Signature sobre timestamp + "." +...
back_urlsno existeNo hay objeto anidado en ROKI - lo reemplazan los dos campos planos de nivel superior success_url y cancel_url, y ambos aceptan solo http/https (un esquema de app personalizado como myapp://done devuelve 422, así que el viaje de regreso en móvil necesita Universal Links / App...
auto_returnno existeNo hay switch que configurar - el checkout hospedado de ROKI siempre ofrece el regreso a success_url - y, como en Mercado Pago, el redirect nunca es prueba de un cargo, así que tratalo puramente como UX y confirmá del lado del servidor.
init_pointcheckout_urlEl equivalente limpio y el corazón de la migración - ROKI lo devuelve directo de POST /payments sin paso de preferencia, hay exactamente una URL para ambos ambientes, y el slug es un string a secas de 12 caracteres en minúsculas sin plink_...
sandbox_init_pointno existeROKI no tiene segunda URL - el ambiente lo decide únicamente el prefijo de la llave del API (sk_test_ = sandbox, sk_live_ = producción) sobre rutas idénticas, así que usá checkout_url en ambos y solo cambiá la llave.
preference_ididROKI no tiene objeto de preferencia - POST /payments crea el pago directamente - y el id numérico devuelto sirve solo para GET /payments/{id}, así que persistilo, porque el único otro camino de vuelta a un pago es paginar GET /payments.
payment_method_idno existeEl falso amigo más peligroso de esta tabla - ROKI sí tiene un payment_method_id, pero es un PARÁMETRO DE RUTA en la URL que lleva una referencia opaca de tarjeta guardada (pm_7k2n9xqf31ab), no un selector de marca, y ROKI Connect no ofrece selección de método...
tokenpayment_tokenMisma arquitectura, pero un solo nombre de ROKI cubre dos valores no intercambiables: el modo 2 manda el tok_* del SDK de iframe a POST https://aura.roki.systems/api/connect/embed/confirm junto con publishable_key (ojo que la base es /api/connect/embed, no...
installmentsno existeROKI Connect no expone planes de cuotas en absoluto y no hay workaround - y como los campos desconocidos se descartan en silencio, dejar installments en el cuerpo devuelve 201 mientras al cliente se le cobra completo, así que sacalo...
currency_idcurrency_codeDe nivel superior en vez de por ítem, e inconsistente dentro del propio ROKI: POST /payments requiere el código ISO 4217 NUMÉRICO ("340" = HNL) mientras que POST /payments/token-charge y el confirm de embed aceptan el alfabético "HNL" - y solo las monedas...
expiresno existeROKI no tiene switch de encendido/apagado - simplemente mandá expires_at para fijar un vencimiento, u omitilo por completo para un link sin vencimiento.
expiration_date_toexpires_atTiene que estar en el futuro y se interpreta en hora de Honduras (UTC-6) SIN offset en el string en ninguna dirección, así que parsear expires_at, created_at o paid_at como UTC corre cada valor seis horas - suficiente para hacer que un link vigente parezca...
captureno existeROKI no separa autorización y captura - todo cargo aprobado se captura - así que lo reemplaza la ruta de reversión: intentá POST /payments/{transaction_id}/void (solo monto completo, antes de liquidar) y recurrí a POST /payments/{transaction_id}/refund (completo...
binary_modeno existeNo es configurable en ROKI - un pago queda pendiente hasta que se cobra, y en el modo 2 un desafío 3-D Secure devuelve status: "pending" con un authentication_url que el cliente debe completar, y el resultado final llega por webhook.
status_detailno existeROKI devuelve solo status (pending, paid, partially_refunded, refunded, voided, expired, disabled); el detalle del rechazo llega en una forma completamente distinta, como IsoResponseCode pasado directo del procesador más un array Errors[] con mayúscula inicial de {Code,...