Pago asistido
Sumario
- 1 Pago asistido "mdpay"
- 2 Configuración y puesta en marcha
- 2.1 Disponer de canal mdpay
- 2.2 Disponer de las modificaciones específicas en dialplan
- 2.3 Activar mdpay
- 2.4 Adaptar el trunk SIP a la plataforma de pagos
- 2.5 Para llamadas inversas, adaptar el trunk SIP a la PBX externa
- 2.6 Definir tiempos de espera
- 2.7 Desactivar trazas de multifrecuencia (desactivar DTMF, verbose máximo 3)
- 2.8 Definir que llamadas pasarán tendrán pago asistido
- 3 API Omnisuite para mdpay
- 4 Instalación de mdpay en versiones anteriores de VIVAit Call
1 Pago asistido "mdpay"
1.1 Introducción
mdtel ha desarrollado en VIVAit Call un módulo específico que facilita la existencia de pago telefónico con tarjeta de crédito en pasarela de pago, pero asistido por agente humano, cumpliendo normativa PCIDSS.
Esta funcionalidad es muy útil en (por ejemplo) entornos de televenta, donde el cliente desea realizar una compra, llama por teléfono a un contact center, el agente consigue la venta, y para realizar el pago ha de pasarle a la plataforma de pagos. El funcionamiento tradicional ha sido que el agente transfiere la llamada a la plataforma de pagos, el cliente paga, y el agente posteriormente recupera la llamda para continuar con la venta.
Este modelo tradicional adolece del problema de la falta de control del proceso por parte del agente; con la funcionalidad "mdpay" se consigue que el agente continúe en comunicación con el cliente durante el proceso de pago, cumpliendo normativa PCIDSS.
- El agente no escucha ni ve información alguna de tarjeta de crédito.
- VIVAit Call no almacena información alguna sobre tarjeta de crédito durante el proceso de pago asistido.
1.2 Nomenclatura
| Término | Definición |
|---|---|
| Cliente | Persona que desea realizar la compra |
| Agente | Profesional de ventas en contact center que atiende al cliente |
| Pasarela de pagos | Entorno de pagos telefónicos que se encarga de realizar la transacción de pago |
| PBX externa | Contact center al que está conectado el agente |
| CRM | Aplicación de negocio que maneja el agente |
| Identificador de pago | Identificador único del pago de la transacción |
1.3 Interconexiones
La arquitectura del sistema y sus interconexiones s la reflejada en la figura siguiente.
1.4 Proceso general
El proceso general para la realización del pago asistido será el que se muestra a continuación; se muestra el flujo para llamadas directas; el flujo para llamadas inversas será el equivalente a la inversa :
- El cliente llama a la PBX externa y es atendido por un agente; la comunicación entre cliente y agente no solo pasa por la PBX externa, sino también por VIVAit Call.
- Una vez conseguida la venta:
- El CRM del agente habrá obtenido un identificador de pago de la pasarela de pagos
- Para iniciar el proceso de pago el agente pulsará un botón en el CRM de "inicio de pago asistido".
- Este botón invocará a una API en la PBX externa para el envío de códigos DTMF
###{numero Pasarela de pagos}*{Identificador pago}#. - Los códigos DTMF son capturados por VIVAit Call.
- VIVAit Call envía la llamada del cliente a la plataforma de pagos con los headers adecuados (en
X-PBC-LOCATORva el UCID y enX-PBC-COMMERCE_IDva el identificador de pago). - VIVait Call mantiene la llamada de agente, aparcándola (importante para que el agente no quede disponible y pueda entrarle otra llamada del contact center).
- Con la llamada en la plataforma de pagos y el agente aparcado:
- La plataforma de pagos:
- Realiza una llamada a VIVAit con los headers adecuados (en la cabecera
X-PBC-LOCATORva el UCID y enX-PBC-COMMERCE_IDva el identificador de pago) - Establece una multiconferencia entre la llamada entante de VIVAit Call y la llamada saliente a VIVAit Call
- Se asegura de no enviar DTMF's
- Realiza una llamada a VIVAit con los headers adecuados (en la cabecera
- VIVAit Call:
- Correla llamada entrante de plataforma de pagos y llamada de agente aparcado
- Desaparca agente y le conecta la llamada entrante de la plataforma de pagos
- La plataforma de pagos:
Durante esta fase:
- El cliente podrá realizar el proceso de pago en la plataforma de pagos
- El agente seguirá manteniendo la comunicación con el cliente, pudiendo asistirle en todo lo que sea necesario
- El cliente no ve ni escucha ningún dato de tarjeta de crédito
- Una vez finalizado el pago
- La plataforma de pagos finalizará la multiconferencia
- VIVAit Call reconecta la llamada cliente-agente
2 Configuración y puesta en marcha
Para versiones de VIVAit Call anteriores a la 5.2, las instrucciones de instalación y configuración se encuentran en #Instalación de mdpay en versiones anteriores de VIVAit Call
Los pasos fundamentales para poner en marcha el pago asistido serán:
- Disponer de canal mdpay
- Disponer de las modificaciones específicas en dialplan
ext_MARCAR_Externo.conf - Activar mdpay
- Adaptar el trunk SIP a la plataforma de pagos
- Para llamadas inversas, adaptar el trunk SIP a la PBX externa (añadir un contexto, se proporciona ejemplo de ese contexto en
ext_mdpay_Particular.conf.ejemplo) - Definir tiempos de espera
- Desactivar trazas de multifrecuencia (desactivar DTMF, verbose máximo 3)
- Definir que llamadas pasarán tendrán pago asistido
2.1 Disponer de canal mdpay
Para confirmar que disponemos de canal mdpay, usaremos el comando de consola asterisk core show channeltypes
Ejemplo de salida
Type Description Devicestate Presencestate Indications Transfer ------------- ------------- ------------- ------------- ------------- ------------- Recorder Bridge Media Recording Channel Driver no no yes no Announcer Bridge Media Announcing Channel Driver no no yes no CBAnn Conference Bridge Announcing Channel no no yes no CBRec Conference Bridge Recording Channel no no no no UnicastRTP Unicast RTP Media Channel Driver no no no no MulticastRTP Multicast RTP Paging Channel Driver no no no no SIP Session Initiation Protocol (SIP) yes no yes yes DAHDI DAHDI Telephony yes no yes no IAX2 Inter Asterisk eXchange Driver (Ver 2) yes no yes yes mdtap Tap Channel Driver yes no yes yes mdpay Pay Channel Driver yes no yes yes Local Local Proxy Channel Driver yes no yes no Surrogate Surrogate channel used to pull channel f no no no no
En el ejemplo anterior se puede observar que el canal tipo mdpay (descripción "Pay Channel Driver") está instalado
2.2 Disponer de las modificaciones específicas en dialplan
En el archivo ext_MARCAR_Externo.conf encontraremos las siguientes líneas
;-----------------------------------------------------------------
[Cen_Marcar_Externo]
;-----------------------------------------------------------------
exten => _[*#%0-9a-zA-Z].,1,NoOp(MDMAREXT**CadMarcar=${Enr_CadMar}**CID=${Enr_CalID}*)
same => n,GotoIf($["${R_RUT_SAL_${ENR_RUTA_CAD}}"=""]?finLlamada)
same => n,GotoIf($["${R_RUT_NODO_${ENR_RUTA_CAD}}"=""]?:nodo)
;***********************MDPAY**********************
same => n,GotoIf($["${hay_mdpay}"!="1"]?finmdpay)
same => n,Set(activar_mdpay=)
same => n,GosubIf($[${DIALPLAN_EXISTS(Cen_mdpay_directo_Particular,${EXTEN},1)}>0]?Cen_mdpay_directo_Particular,${EXTEN},1)
same => n,GotoIf($["${activar_mdpay}"!="1"]?finmdpay)
same => n,Set(__MDPAY_SENTIDO=1)
same => n,Set(__MDPAY_CONTEXT=${CONTEXT})
same => n,Set(__MDPAY_EXTEN=${EXTEN})
same => n,Set(__MDPAY_PRIO=$[${PRIORITY}+2])
same => n,Goto(Cen_mdpay,${R_DEST_${ENR_RUTA_CAD}},1)
same => n(finmdpay),NoOp(Retorno mdpay)
;***********************MDPAY**********************
Caso de no existir, ver instrucciones en #Instalación de mdpay en versiones anteriores de VIVAit Call
2.3 Activar mdpay
Para activar mdpay deberemos configurar el archivo ext_MDtel_Particular.conf
El archivo debe contener las siguientes lineas
;---------------------------------------------------------------------------- ;mdpay ;---------------------------------------------------------------------------- hay_mdpay=1
si no existen hay que incluirlas y si esta comentada la línea o tiene un valor diferente a 1 hay que configurarlo con el valor 1
2.4 Adaptar el trunk SIP a la plataforma de pagos
VIVAit call tendrá configurado un trunk SIP con la plataforma de pagos
El contexto de entrada del trunk con la plataforma de pagos debe ser Cen_mdpay_ret_retorno
Este contexto esta incluido en el archivo ext_mdpay_Particular.conf
En el contexto [Cen_mdpay_cli_pagos] de ese archivo ext_mdpay_Particular.conf se debe de configurar la marcación al trunk de pagos
por ejemplo:
same => n,Dial(SIP/${EXTEN}@Trunk_mdpay,30,g)
En este ejemplo el trunk que tenemos en VIVIAit Call configurado con la plataforma de pagos se llama Trunk_mdpay
2.5 Para llamadas inversas, adaptar el trunk SIP a la PBX externa
Las llamadas inversas hay que configurar el trunk de unión entre VIVAit Call y la PBX externa con un contexto de inicio que incluya el mdpay, se da un contexto de ejemplo que puede utilizarse en el archivo ext_mdpay_Particular.conf.ejemplo, el contexto es Cen_Inicio_TrunkSip_Omni
; Ejemplo Inicio de las llamadas que entren de una centralita externa por un TrunkSIP
[Cen_Inicio_TrunkSip_Omni]
exten => _[+*#%0-9].,1,NoOp(MDINITRUNKSIPOMNI**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Gosub(Cen_Sub_ucid,${EXTEN},1)
same => n,NoOp(ucid=${UCID})
same => n,Set(__ID_DISPOSITIVO=${ID_DISPOSITIVO})
;***********************MDPAY**********************
same => n,GotoIf($["${hay_mdpay}"!="1"]?finmdpay)
same => n,Set(activar_mdpay=)
same => n,GosubIf($[${DIALPLAN_EXISTS(Cen_mdpay_inverso_Particular,${EXTEN},1)}>0]?Cen_mdpay_inverso_Particular,${EXTEN},1)
same => n,GotoIf($["${activar_mdpay}"!="1"]?finmdpay)
same => n,Set(__MDPAY_SENTIDO=2)
same => n,Set(__MDPAY_CONTEXT=${CONTEXT})
same => n,Set(__MDPAY_EXTEN=${EXTEN})
same => n,Set(__MDPAY_PRIO=$[${PRIORITY}+2])
same => n,Goto(Cen_mdpay,${R_DEST_${ENR_RUTA_CAD}},1)
same => n(finmdpay),NoOp(Retorno mdpay)
;***********************MDPAY**********************
same => n,Goto(Cen_Inicio_TrunkSip,${numMarcar},1)
2.6 Definir tiempos de espera
En el archivo ext_mdpay_Particular.conf, contexto [Cen_mdpay] podemos manejar la línea
same => n,ExecIf($["${MDPAY_CAUSA_REENTRADA}" ="R"]?mdpay(reconxEsperaAgente,10000))
que configura el tiempo que despues de que la pasarela de pago cuelgue al cliente se espera a que el agente este disponible (la pasarela de pago cuelga la llamada de retorno)
2.7 Desactivar trazas de multifrecuencia (desactivar DTMF, verbose máximo 3)
En el entorno de pago asistido, y para cumplir con normativa PCIDSS es importante que no quede rastro de pulsaciones DTMF. Para ello, y a nivel global del sistema (se pierde la información de pulsaciones DTMF para todo el VIVAit Call, no solo para llamadas con pago asistido) debemos modificar la configuración del archivo /etc/asterisk/logger.conf en sus parámetros console y full
Configuración de /etc/asterisk/logger.conf
;console => notice,warning,error,debug,dtmf console => notice,warning,error,debug messages => warning,error ;full => notice,warning,error,debug,verbose(3),dtmf,fax full => notice,warning,error,debug,verbose(3)
2.8 Definir que llamadas pasarán tendrán pago asistido
2.8.1 En llamadas directas
Para definir que llamadas directas tienen opción de pago asistido (recordemos que este solo se producirá en el momento en el que el agente lo active) es necesario configurar en el archivo ext_mdpay_Particular el contexto [Cen_mdpay_directo_Particular]
En este contexto si se devuelve la variable activar_mdpay con valor 1 la llamada tendŕa la opción de pago asistido.
Ejemplo: Todas las llamadas externas tienen posibilidad de pago asistido (activar_mdpay siempre será 1)
[Cen_mdpay_directo_Particular]
exten => _[+*#%0-9].,1,NoOp(MDMDPAYPARTDIR**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=1)
same => n,Return
Ejemplo: Solo las llamadas que vayan al número externo 10000 tengan opción de pago asistido
[Cen_mdpay_directo_Particular]
exten => _[+*#%0-9].,1,NoOp(MDMDPAYPARTDIR**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=0)
same => n,Return
exten => _10000,1,NoOp(MDMDPAYPARTDIR10000**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=1)
same => n,Return
Ejemplo: Todas las llamadas que vayan al trunk de la PBX externa tendrán opción de pago asistido, en el ejemplo el dato asterisk del trunk de la centralita externa es OmniLab
[Cen_mdpay_directo_Particular]
exten => _[+*#%0-9].,1,NoOp(MDMDPAYPARTDIR**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=0)
same => n,ExecIf($["${R_RUT_SAL_${ENR_RUTA_CAD}}" ="OmniLab"]?Set(activar_mdpay=1))
same => n,Return
2.8.2 En llamadas inversas
Para definir que llamadas inversas tienen posibilidad de pago asistido es necesario configurar en el archivo ext_mdpay_Particular el contexto [Cen_mdpay_inverso_Particular]
En este contexto, si se devuelve la variable activar_mdpay con valor 1 la llamada tendŕa la opción de pago asistido.
Ejemplo: Todas las llamadas inversas (vienen de la PBX externa) tienen opción de pago asistido
[Cen_mdpay_inverso_Particular]
exten => _[+*#%0-9].,1,NoOp(MDMDPAYPARTINV**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=1)
same => n,Return
Ejemplo: Todas las llamadas inversas con ANI 1111111 tendrán posibilidad de pago asistido
[Cen_mdpay_inverso_Particular]
exten => _[+*#%0-9].,1,NoOp(MDMDPAYPARTINV**EXTEN=${EXTEN}**CID=${CALLERID(NUM)}*)
same => n,Set(activar_mdpay=1)
same => n,GotoIf($["${CALLERID(num)}"="1111111"]?finmdpay)
same => n,Set(activar_mdpay=0)
same => n(finmdpay),Return
3 API Omnisuite para mdpay
3.1 Introducción
En este documento definimos las invocaciones mínimas a realizar a endpoints de Omnisuite para activar el pago asistido Será necesario:
- Obtener Id de usuario
- Obtener UniqueId de la llamada del usuario
- Enviar tonos DTMF a esa llamada
3.2 Autenticación
Todas las peticiones deben incluir el siguiente encabezado de seguridad:
- Header: x-api-key
- Valor: El API KEY de usuario de omnisuite proporcionado.
3.3 Endpoints
3.3.1 Obtener ID de un usuario
Recupera el identificador de un usuario específico basado en filtros.
- Método: GET
- URL: https://omnisuite.cliente.com/users
- Parámetros de consulta (Query Params):
- fields: Especifica los campos a retornar (ej. id).
- filter: Criterio de búsqueda (ej. jac).
- sort: Orden de los resultados (ej. id).
Ejemplo de solicitud:
GET https://omnisuite.cliente.com//users?fields=id&filter=jac&sort=id
Ejemplo de respuesta:
{
"count": 1,
"rows": [
{
"id": 5
}
]
}
3.3.2 Consultar llamadas de un usuario
Obtiene el registro o estado de las llamadas asociadas a un ID de usuario.
- Método: POST
- URL: https://omnisuite.cliente.com/webbar/calls
- Cuerpo de la petición (JSON):
{
"userId": 5
}
Ejemplo de respuesta
{
"count": 1,
"rows": [
{
"abandoned": false,
"accountcode": "",
"answertime": "2026-02-10 14:53:54",
"answered": true,
"billableseconds": 0,
"channel": "SIP/Trunk_PrepoCopr0-00000022",
"callerid": "",
"calleridname": "/50002",
"calleridnum": "50002",
"connectedlinename": "JAC",
"connectedlinenum": "1004",
"context": "from-voip-provider",
"destination": "",
"destinationchannel": "SIP/jac-00000023",
"disposition": "ANSWERED",
"duration": 0,
"endtime": null,
"exten": "10000",
"holdtime": 6,
"lastapplication": "queue",
"lastdata": "Desarrollo,xX,,,300,,,,,",
"linkedid": "1770731628.77",
"membername": "jac",
"monitor": true,
"monitors": [
{
"filename": "/var/spool/asterisk/monitor/1770731628.76.wav",
"createdAt": "2026-02-10 14:53:54",
"mixmonitorid": "",
"status": "rec"
}
],
"monitorFilename": "/var/spool/asterisk/monitor/1770731628.76.wav",
"mohtime": 0,
"queue": "Desarrollo",
"sipcalllinkedid": "23f0e8b840c85fd057d7474a5fc68844@172.25.129.174:0",
"sipcalluniqueid": "067515e4161a16e9594cd0aa6ea74fed@172.25.128.251:5060",
"starttime": "2026-02-10 14:53:48",
"tag": null,
"type": "inbound",
"uniqueid": "1770731628.76",
"unmanaged": false,
"UserId": 5,
"routeid": "287"
}
]
}
3.3.3 Enviar DTMF a una llamada
Permite enviar una secuencia de dígitos DTMF a una llamada activa.
- Método: POST
- URL: https://omnisuite.cliente.com/webbar/send-dtmf
- Cuerpo de la petición (JSON)
{
"digits": "###444*12345#",
"duration": 100,
"uniqueId": "1770732063.80",
"userId": 5
}
El valor “duration” indica la duración del envío en ms (en el ejemplo anterior serían 100ms, que es el valor recomendado)
Ejemplo de respuesta:
{
"error": false,
"message": "SendDTMF [###444*12345#] executed"
}
4 Instalación de mdpay en versiones anteriores de VIVAit Call
4.1 Instalación de canal mdpay en asterisk
En el caso que no este instalado procederemos a incluir el canal en asterisk
En el directorio de los fuentes de asterisk, tipicamente /usr/src/MDtel/asterisk hay que añadir el archivo chan_mdpay.c en el directorio channels
tipicamente: /usr/src/MDtel/asterisk/channels/chan_mdpay.c
En el directorio raiz de los fuentes de asterisk
- lanzamos el comando
make - una vez compilado sin errores paramos asterisk(
/etc/init.d/asterisk stop) - lanzamos el comando
make installpara poner los binarios en su lugar - volvemos a arrancar asterisk (
/etc/init.d/asterisk start)
En la consola asterisk podemos teclear el comando core show channeltypes
y ahora debe aparecer el canal mdpay Pay channel Driver
4.1.1 Fichero de configuración de canal mdpay
La configuración del canal mdpay se encuentra en /etc/asterisk/mdpay.conf
[general] ; debug ; 0 - no hay debug ; 1 - debug on (se puede activar por comando (mdpay debug on)) debug=0 ;Tiempo que se colgara al agente si no hay cliente to_colgar_aparcado_sin_cli_ms=5000 ;Tiempo para introducir la secuencia multifrecuencia dtmf_caduca_segs=10 ;Numero de parrillas al principio de la cadena de pagos ; ejemplo: ##[*|#]<exten_pagos>*<id_pagos># dtmf_parrillas_prefijo=2
4.2 modificaciones en dialplan
En ext_MARCAR_Externo.conf deben incluirse las siguientes líneas
;-----------------------------------------------------------------
[Cen_Marcar_Externo]
;-----------------------------------------------------------------
exten => _[*#%0-9a-zA-Z].,1,NoOp(MDMAREXT**CadMarcar=${Enr_CadMar}**CID=${Enr_CalID}*)
same => n,GotoIf($["${R_RUT_SAL_${ENR_RUTA_CAD}}"=""]?finLlamada)
same => n,GotoIf($["${R_RUT_NODO_${ENR_RUTA_CAD}}"=""]?:nodo)
;***********************MDPAY**********************
same => n,GotoIf($["${hay_mdpay}"!="1"]?finmdpay)
same => n,Set(activar_mdpay=)
same => n,GosubIf($[${DIALPLAN_EXISTS(Cen_mdpay_directo_Particular,${EXTEN},1)}>0]?Cen_mdpay_directo_Particular,${EXTEN},1)
same => n,GotoIf($["${activar_mdpay}"!="1"]?finmdpay)
same => n,Set(__MDPAY_SENTIDO=1)
same => n,Set(__MDPAY_CONTEXT=${CONTEXT})
same => n,Set(__MDPAY_EXTEN=${EXTEN})
same => n,Set(__MDPAY_PRIO=$[${PRIORITY}+2])
same => n,Goto(Cen_mdpay,${R_DEST_${ENR_RUTA_CAD}},1)
same => n(finmdpay),NoOp(Retorno mdpay)
;***********************MDPAY**********************