======
Cargos
======
En este apartado de documenta el proceso de adquisición de recargas
y productos de tiempo, indicando las respectivas interacciones entre
el WebService de Cinemex y el Sistema Arena.
Compra de un producto de recarga
================================
Los usuarios solicitan a un miembro del staff asistente la recarga
a sus cuentas de un producto de recarga. El asistente adquiere
el producto para el usuario en el punto de venta de la sucursal,
obteniendo un ticket. Posteriormente, y como se describe a
continuación, se ingresa dicho ticket al Sistema Arena para
solicitar la carga del producto de recarga adquirido al usuario
o a una tarjeta virgen.
Descripción general
-------------------
.. image:: /images/charges/recharge_purchase_overview.svg
:align: center
1. Un asistente solicita la carga de los productos adquiridos en el
punto de venta, proporcionando el número de ticket al servidor
Offsite.
2. Offsite consulta la validez y los productos del Ticket con el
WS de Cinemex.
3. Una vez validado el ticket en el Web Service, este responde al
servidor Offsite con el listado de productos de recarga
contenidos en el ticket. En consecuencia, Offsite abona al
usuario o a la tarjeta virgen tantas monedas como la suma
de aquellas en cada recarga.
4. Offsite responde al cliente Assistant con el resultado de la
operación.
Flujo
-----
A continuación se describe el flujo de carga de monedas a la cuenta
de un jugador o a una tarjeta virgen. En ambos casos, se asume
que el jugador fue buscado como se indica en :ref:`obtener-jugadores`.
.. image:: /images/charges/recharge_purchase_sequence.svg
:align: center
.. _obtener-jugadores:
Offsite: ``GET /players``
^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Kiosk, Assistant
Mediante esta ruta se solicita la información de un jugador
registrado en el sistema Arena. La ruta responde con el estado
``200 OK`` acompañado de la información de los jugadores que
coincidan con alguno de los criterios de búsqueda proporcionados,
los cuales pueden ser:
============ =========================================================
Parámetro Descripción
============ =========================================================
``nick`` | Obtiene al jugador cuyo nick coincida con
el proporcionado.
``email`` | Obtiene al jugador cuya dirección de correo
se igual a la cadena proporcionada.
``card_key`` | Obtiene al jugador cuya tarjeta vinculada coincida
en su llave con aquella que es proporcionada. Si
| la tarjeta es virgen, no será devuelto ningún
jugador.
============ =========================================================
Para cada jugador incluido en la respuesta, debe verificarse que la
fecha de su última transacción sea menor a tres meses. En caso contrario,
debe crearse una transacción negativa con el monto igual al saldo del
jugador; esto con el objetivo de expirar sus monedas. Esta transacción no
será reportada al sistema Vista.
Un vez localizado el jugador de la recarga, o identificado la tarjeta
proporcionada como virgen, se hace uso de las siguientes rutas para el
ligado de productos de recargas a la cuenta del jugador.
Onsite: ``POST /players/recharges``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Assistant
Mediante esta ruta se solicita al servidor Onsite la carga
de los productos en el ticket al jugador proporcionado.
El cuerpo de la petición es el siguiente:
.. code-block:: yaml
nick: EsLaBoa
ticketFolio: USlkjdl27
Al recibir la petición, se solicita al servidor Offsite la
carga de los productos en el ticket.
La ruta responde con el estado ``200 OK`` acompañado de
la información devuelta por el servidor Offsite.
Si el usuario no existe se responde con el estado
``404 Not Found``. Si el folio de ticket es inválido, se
responde con el estado ``409 Conflict``. Si el jugador
es de tipo *guest* y no cuenta con un check in abierto
en la sucursal, se responde con el estado
``412 Precondition Failed``. Si el
servidor del sistema Cinemex no responde, se devuelve el
estado ``503 Service Unavailable``.
Offsite: ``POST /players/recharges``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Location
Mediante esta ruta se solicita la carga al jugador proporcionado
de los productos adquiridos en el ticket. El cuerpo de la petición
es el siguiente:
.. code-block:: yaml
nick: EsLaBoa
ticketFolio: USlkjdl27
Como consecuencia de la recepción de la petición se
verifica la existencia del jugador, para posteriormente
invocar la ruta :ref:`wsc-consulta-ticket` en el Web Service
de Cinemex para consultar la validez del folio; operación
a la cual responde con el listado de productos adquiridos
en el ticket.
Previo a la recarga, debe verificarse que la fecha de la última transacción
del jugador sea menor a tres meses. En caso contrario,
debe crearse una transacción negativa con el monto igual al saldo del
jugador; esto con el objetivo de expirar sus monedas. Esta transacción no
será reportada al sistema Vista.
Para cada producto adquirido, se lleva a cabo una transacción
positiva de moneda Arena al jugador por la cantidad de coins
asociada al producto. La ejecución de la recarga al jugador se
considera un proceso atómico.
La ruta responde con el estado ``200 OK`` acompañado de
la información del jugador, incluyendo la cantidad de
monedas. Cada producto recibido en el ticket que no
corresponda a un producto de recarga es ignorado.
Si el usuario no existe se responde con el estado
``404 Not Found``. Si el folio de ticket es inválido, se
responde con el estado ``409 Conflict``. Si el folio de ticket
ya ha sido usado, se responde con el estado ``412 Precondition
Failed``. Si el servidor del sistema Cinemex no responde, se devuelve el
estado ``503 Service Unavailable``.
Onsite: ``POST /id_cards``
^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Assistant
Mediante esta ruta se solicita la creación de una tarjeta
con su correspondiente carga inicial de moneda. El cuerpo
de la petición es el siguiente:
.. code-block:: yaml
key: dfkj7iKJhdjkygts876BNVS
ticketFolio: USlkjdl27
Al recibir la petición, el servidor Onsite canalizará la
petición al servidor Offsite como se indica en :ref:`offsite-post-card`,
con el objetivo de que se registre el país de la carga inicial de la tarjeta.
La ruta responde con el estado ``201 Created`` acompañado de
la información devuelta por el servidsor Offsite.
Si Offsite indica que ya existe registro de una tarjeta con
la misma llave que aquella proporcionada, o si el folio de
ticket es inválido, se responde con el estado ``409 Conflict``. Si el
servidor del sistema Cinemex no responde, se devuelve el
estado ``503 Service Unavailable``.
.. _offsite-post-card:
Offsite: ``POST /id_cards``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Location
Mediante esta ruta se solicita la carga a la tarjeta proporcionada
de los productos adquiridos en el ticket. El cuerpo de la petición
es el siguiente:
.. code-block:: yaml
key: dfkj7iKJhdjkygts876BNVS
ticketFolio: USlkjdl27
Como consecuencia de la recepción de la petición el servidor
Offsite comprobará que no exista registro de una tarjeta con
la llave indicada para después crearla, y posteriormente
invocar la ruta :ref:`wsc-consulta-ticket` en el Web Service
de Cinemex para consultar la validez del folio; operación
a la cual responde con el listado de productos adquiridos
en el ticket.
Las cantidades en moneda Arena de los productos
adquiridos son sumadas para después llevar a cabo la carga inicial
de moneda Arena a la tarjeta por la cantidad total de coins.
La ejecución de la recarga a la tarjeta se considera un proceso atómico.
La ruta responde con el estado ``201 Created`` acompañado de
la información de la tarjeta recién registrada en el sistema.
Cada producto recibido en el ticket que no corresponda a un
producto de recarga es ignorado.
Como parte del comportamiento exitoso, debe vincularse la tarjeta
con el país al que pertenece el servidor Onsite que lleva a cabo
la petición.
Si ya existe registro de una tarjeta con la misma llave que
aquella proporcionada, o si el folio de ticket es inválido, se
responde con el estado ``409 Conflict``. Si el folio de ticket
ya ha sido usado, se responde con el estado ``412 Precondition
Failed``. Si el servidor del sistema Cinemex no responde, se devuelve el
estado ``503 Service Unavailable``.
.. _wsc-consulta-ticket:
WS Cinemex: ``POST /wsARES/wsValidateTransaction.asmx``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Username/Password
Mediante esta ruta se consulta la validez de un ticket,
así como la lista de productos de recarga adquiridos.
El cuerpo de la petición es el siguiente
.. code-block:: xml
Al recibir la petición, el WS consulta la validez del
producto de tiempo, para posteriormente devolver el
listado de productos adquiridos como en el siguiente
esquema:
.. code-block:: xml
true
6017
0.00000000
100
Folio Valido
2018-03-08T00:00:00
``Valido``
Indica si el folio indicado corresponde a una transacción válida.
En caso negativo, no se procede con la transacción sobre las monedas
del jugador.
``Folio``
Folio del ticket consultado, sobre el cual se devuelve la información.
``Horas`` **Obsoleto**
Cantidad de horas adquiridas en el ticket.
``Ares``
Suma de Ares en los productos de recarga adquiridos. El monto devuelto
es aquel que debe cargarse al balance del jugador.
``Mensaje``
Cadena con descripción del resultado de la operación.
``FechaTransacción``
Fecha en la que el WS registró la operación de compra.
.. _redencion-tiempo-offsite:
Redención de un producto de tiempo
==================================
Los usuarios solicitan al sistema Arena el uso de un
producto del catálogo distinto a recargas, el cual
puede ser tiempo de uso de consola o pago de servicios
en moneda Arena (ej. entrada a torneo). A cada redención
de un producto que disminuya las monedas de un jugador
debe corresponder una autorización por parte de Cinemex.
A continuación se describe el proceso mediante el
cual se solicita autorización para la redención de
productos por parte de usuarios.
Descripción general
-------------------
.. image:: /images/charges/product_redemption_overview.svg
:align: center
1. El servidor Onsite de la sucursal solicita autorización
a Offsite para el uso de un producto por parte de un jugador.
2. Offsite solicita al WS de Cinemex autorización para
llevar a cabo un descuento de moneda Arena de los productos
a usar por cada jugador. Este proceso es llevado a cabo en dos
pasos, simulando una compra desde Offsite hacia el WS.
3. El WS procesa la compra de los productos indicados con
cargo efectuado en Ares y responde al servidor Offsite
con el código de transacción. Offsite decrementa la
cantidad de monedas de los jugadores, las cuales corresponden,
para cada jugador, al costo del producto de tiempo a redimir.
4. Offsite responde a Onsite con el resultado del cobro del
producto.
Flujo
-----
.. image:: /images/charges/product_redemption_sequence.svg
:align: center
Se hace uso de las siguientes rutas para la autorización
de compra de un producto
Offsite: ``POST /players/transactions``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Location
Mediante esta ruta se procesa una secuencia de transacciones
solicitadas por un servidor Onsite como sigue:
.. code-block:: yaml
- nick: aleexkj
action: purchase
timeProductId: 2
- nick: susuRockstar
action: hold
timeProductId: 4
- nick: cealmees
action: charge_hold
transactionId: 12
- nick: josedejesus
action: free_hold
transactionId: 23
- nick: shoshana
action: charge_hold_and_purchase
transactionId: 867
timeProductId: 3
========================= ===============================================
Acción Comportamiento
========================= ===============================================
purchase | Carga al jugador con la cantidad de monedas
| que cuesta el producto elegido en el país de
| la sucursal, previa autorización del WS
| de Cinemex. La fecha en la que se carga el
| producto debe ser igual a la fecha de
| creación. El tipo de cargo es negativo.
| El producto de tiempo a redimir se
| notifica al WS según su correspondiente
| ``wsItemId``.
hold | Crea una transacción negativa sin cobrar al
| jugador por el 50% del costo del producto
| de tiempo elegido en el país de la sucursal,
| lo cual no involucra una autorización con el
| WS de Cinemex. Este comportamiento
| corresponde a una retención.
charge_hold | Carga al jugador la transacción negativa
| existente. Para efectuar este proceso,
| se establece comunicación con el WS de
| Cinemex para notificar el producto de tiempo
| a cobrar, el cual debe corresponder al
| identificador del producto de penalización
| correspondiente.
free_hold | Libera una retención de moneda Arena
| existente en el historial de transacciones
| del jugador. Dicha retención no debe haber
| sido cobrada. Dado que una retención se
| maneja de manera interna, para la
| liberación de la misma tampoco es necesaria
| la notificación al WS de Cinemex.
charge_hold_and_purchase | Se solicita el cobro de una retención como
| se indica en ``charge_hold``. Además,
| se solicita la redención de un producto
| de tiempo cuyo costo debe ser menor
| al 50% del costo del producto retenido y
| recién cobrado. Por tanto, el nuevo
| producto adquirido se paga del costo de
| la retención. La relación con el Access
| Key de la transacción original no se
| sobreescribe.
free_hold_and_purchase | Se solicita la liberación de una retención
| como se indica en `free_hold`. Además,
| se solicita la redención de un producto
| de tiempo como se indica en ``purchase``.
| La relación con el Access Key de la
| transacción original no se sobreescribe.
| El producto de tiempo a redimir se
| notifica al WS según su correspondiente
| ``wsItemId``.
========================= ===============================================
Al recibir la petición, el servidor Offsite validará la existencia
de cada jugador y producto de tiempo, para posteriormente
comprobar que cada jugador pueda ser cargado con la cantidad de
monedas que cuesta el producto elegido en el país de la
sucursal.
Posterior a las validaciones, se procede a armar una petición
que contenga el conjunto de productos de tiempo a consumir. Este
listado de productos es añadido a una orden que se almacena en
el WS, identificándola por un token de compra. Después, Offsite
solicita al procesador de pagos la compra por el monto total
de Ares correspondiente a la suma de los costos de los
productos de tiempo añadidos a la orden. Este proceso se lleva a
cabo mediante las rutas :ref:`wsc-actualiza-orden` y :ref:`wsc-procesa-pago`.
Esta ruta responde con el estado ``200 OK`` acompañado del
resultado de la transacción en monedas de cada uno de los
jugadores. Si alguno de los jugadores o productos de
tiempo no existe, se responde con el estado ``404 Not Found``.
Se responde con el estado ``409 Conflict`` si sucede alguno
de los siguientes casos:
- Si alguno de los jugadores no cuenta con la cantidad de
monedas suficientes para hacer efectivo un producto. En
este caso, se anula la compra de todos los jugadores y se
responde indicando a aquellos jugadores cuya cantidad de
monedas fue insuficiente. En caso de llevar a cabo una
operación ``[ free | charge ]_hold_and_purchase``, se
cancela la liberación / aplicación del cargo.
- Si no existe el producto en el país de la sucursal.
Si no se proporciona producto de tiempo o identificador
de transacción, se responde con el estado ``400 Bad Request``.
Por otro lado, si la transacción con la que se operará no
corresponde al jugador indicado, se responde con el
estado ``422 Unprocessable Entity``.
Si el servidor del sistema Cinemex no responde, se devuelve el
estado ``503 Service Unavailable``.
.. _wsc-actualiza-orden:
WS Cinemex: ``POST /wsVistaWebClient/RESTTicketing.svc/order/concessions``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Header ``connectapitoken``
Mediante esta ruta se solicita la actualización de la orden de
compra representada por el valor ``UserSessionId``. Esta ruta
permite a Offsite la compra de productos de tiempo en nombre
de los jugadores.
Para identificar la orden, debe generarse una cadena alfanumérica
de 32 caracteres que llevará por nombre ``UserSessionId``.
El cuerpo de la petición es el siguiente:
.. code-block:: javascript
{
"UserSessionId": "mQWNMbIfL3UXZR05LoBwgytlORu3L7zy",
"CinemaId": "526",
"Concessions": [
{
"ItemId": "7820002",
"Quantity": 2
},
{
"ItemId": "7820001",
"Quantity": 1
}
],
"ReturnOrder": true,
"OptionalClientId": "111.111.111.111"
}
``UserSessionId``
Identificador de la orden. Cadena alfanumérica de 32
caracteres. Debe ser creada con un generador de UIDs.
``CinemaId``
Identificador de la sucursal sobre la cual se procesará
la compra. Se obtiene a partir de la sucursal Onsite
de la cual Offsite recibe la petición.
``Concessions.ItemId``
Identificador del producto de tiempo o penalización que
se solicita redimir.
``Concessions.Quantity``
Número de instancias del producto que se desean redimir.
``ReturnOrder``
Debe ser ``true`` en todo momento, solicitando así
obtener en la respuesta el valor de la orden actualizado.
``OptionalClientId``
Cadena en formato IP que tiene el objetivo de
identificar al cliente. Debe tener el valor constante
de ``111.111.111.111``.
La ruta responde con el estado ``200 OK`` acompañado de la
siguiente información:
.. code-block:: javascript
{
"ExtendedResultCode": 0,
"Order": {
"BookingFeeValueCents": 0,
"CinemaId": "526",
"Concessions": [
{
"DeliveryInfo": null,
"GetBarcodeFromVGC": false,
"HeadOfficeItemCode": null,
"IsLoyaltyMembershipActivation": false,
"ItemId": "7820002",
"Modifiers": null,
"PackageChildItems": null,
"ParentSaleItem": null,
"PromoCode": "",
"Quantity": 2,
"RecognitionId": "",
"RecognitionSequenceNumber": 0,
"VoucherBarcode": null
},
{
"DeliveryInfo": null,
"GetBarcodeFromVGC": false,
"HeadOfficeItemCode": null,
"IsLoyaltyMembershipActivation": false,
"ItemId": "7820001",
"Modifiers": null,
"PackageChildItems": null,
"ParentSaleItem": null,
"PromoCode": "",
"Quantity": 1,
"RecognitionId": "",
"RecognitionSequenceNumber": 0,
"VoucherBarcode": null
}
],
"Customer": null,
"LastUpdated": "/Date(1521765176920-0600)/",
"LoyaltyPointsCost": null,
"Sessions": null,
"TotalOrderCount": 3,
"TotalTicketFeeValueInCents": null,
"TotalValueCents": 25000,
"UserSessionId": "mQWNMbIfL3UXZR05LoBwgytlORu3L7zy",
"VistaBookingNumber": 0,
"VistaTransactionNumber": 0
},
"Result": 0
}
.. _wsc-procesa-pago:
WS Cinemex: ``POST /wsVistaWebClient/RESTTicketing.svc/order/payment``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Header ``connectapitoken``
Solicita el procesamiento de pago de la orden indicada por su
``UserSessionId``. El cuerpo de la petición es el siguiente:
.. code-block:: javascript
{
"UserSessionId": "tmQWNMbIfL3UXZR05LoBwgytlORu3L7A",
"PaymentInfo": {
"PaymentTenderCategory":"Ares",
"PaymentValueCents": 25000
},
"PerformPayment": false,
"OptionalClientId": "111.111.111.111"
}
``UserSessionId``
Cadena que identifica la orden.
``PaymentInfo.PaymentTenderCategory``
Tipo de pago. El valor debe ser ``Ares``.
``PaymentInfo.PaymentValueCents``
Monto en centavos que corresponde a la suma en MXN del costo
de todos los productos de tiempo. Esto se obtiene a partir
de una equivalencia entre Ares y MXN.
``PerformPayment``
Constante ``false``, indicando que no se efectúa pago.
``OptionalClientId``
Cadena en formato IP que representa al cliente. Valor fijo
``111.111.111.111``.
De manera alternativa, se puede establecer el siguiente cuerpo
de petición en caso de que el cargo corresponda a Ares, el cual
debe ser liquidado en moneda nacional:
.. code-block:: javascript
{
"UserSessionId": "QCtSH6n3HrMXu8JsLFIUkAkT2eGa2E5t",
"PaymentInfo": {
"CardNumber": "4111111111111111",
"CardType": "VISA",
"CardExpiryMonth": "12",
"CardExpiryYear": "2020",
"PaymentValueCents": 10000,
"PaymentSystemId": "-",
"CardCVC": "111"
},
"PerformPayment": true,
"CustomerEmail": "some_email@domain.com",
"CustomerName": "Client name",
"OptionalClientId": "111.111.111.111"
}
``UserSessionId``
Cadena que identifica la orden.
``PaymentInfo.CardNumber``
Cadena correspondiente a los 16 dígitos de la tarjeta.
``PaymentInfo.CardType``
Tipo de tarjeta. Son soportados los valores ``VISA``
y ``MASTERCARD``.
``PaymentInfo.CardExpiryMonth``
Mes de expiración de la tarjeta.
``PaymentInfo.CardExpiryYear``
Año de expiración de la tarjeta.
``PaymentInfo.PaymentValueCents``
Monto en centavos que corresponde a la suma en MXN del costo
de todos los productos de recarga.
``PaymentInfo.PaymentSystemId``
Constante ``-``.
``PaymentInfo.CardCVC``
Código de seguridad de la tarjeta.
``PerformPayment``
Constante ``true``, indicando que se efectúa el pago.
``CustomerEmail``
Dirección de correo del jugador que lleva a cabo la compra.
``CustomerName``
Nombre del jugador que lleva a cabo la compra.
``OptionalClientId``
Cadena en formato IP que representa al cliente. Valor fijo
``111.111.111.111``.
El WS procesa la transacción y responde con el estado ``200 OK``
acompañado de la siguiente información:
.. code-block:: javascript
{
"BalanceList": null,
"CinemaID": "526",
"ErrorDescription": null,
"ExtendedResultCode": 0,
"HistoryID": "9",
"PassCollection": null,
"PaymentInfoCollection": [
{
"BankReference": null,
"BankTransactionNumber": null,
"BillFullOutstandingAmount": false,
"BillingValueCents": 25000,
"CardBalance": 0,
"CardCVC": "",
"CardExpiryMonth": "",
"CardExpiryYear": "",
"CardHash": "",
"CardIssueNumber": "",
"CardNumber": "",
"CardType": "",
"CardValidFromMonth": "",
"CardValidFromYear": "",
"CustomerTaxName": null,
"CustomerTaxNumber": null,
"MemberId": null,
"PaymentErrorCode": "",
"PaymentErrorDescription": "",
"PaymentStatus": "NA",
"PaymentSystemId": "-",
"PaymentTenderCategory": "Ares",
"PaymentToken": null,
"PaymentTokenType": null,
"PaymentValueCents": 25000,
"SaveCardToWallet": false,
"UseAsBookingRef": true,
"WalletAccessToken": null
}
],
"PrintStream": "",
"PrintStreamCollection": null,
"Result": 0,
"VistaBookingId": "WK8ZSW6",
"VistaBookingNumber": "12",
"VistaTransNumber": "6021"
}
Donde únicamente un valor ``0`` para ``Result`` indica que la operación
fue exitosa. Cualquier otro código de resultado se interpreta como
un error.
En caso de procesar un pago con tarjeta, el servidor Offsite debe
registrar los valores ``BankReference`` y ``BankTransactionNumber``
asociados a la transacción.
Compra de tiempo adicional
==========================
A continuación se describe el proceso que tiene lugar al adquirir
más tiempo para un jugador en el local, ya sea desde un cliente
Assistant o desde un Timer.
Flujo
-----
La siguiente ruta cuenta con la lógica del procesamiento de una compra
de tiempo desde el local
Onsite: ``POST /players/purchased_times``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Autorización:** Timer, Assistant
Mediante la cual se adquiere un nuevo producto de tiempo para su redención
en el local, cobrado únicamente en moneda Arena. La petición de renovación
lleva por cuerpo
.. code-block:: yaml
nick: aleexkj
timeProductId: 2
donde
``nick``
El nombre del usuario que desea adquirir tiempo adicional.
``timeProductId``
El identificador en Onsite del producto de tiempo a comprar.
Al momento de recibir esta petición, se procesa la compra con el servidor
Offsite como se indica en :ref:`redencion-tiempo-offsite` en el
caso ``purchase``, se crea un nuevo registro de tiempo para el jugador que
realiza la compra y se actualiza la hora de expiración del tiempo
contratado por el jugador.
Si la compra del producto de tiempo es exitosa, se responde con el estado
``200 OK`` acompañado de la siguiente información:
.. code-block:: yaml
nick: aleexkj
timeProductId: 2
expiresAt: 1480642412
isTimeRunning: true
coins: 300
``expiresAt``
Nueva fecha de expiración del tiempo actualizado del jugador.
``coins``
Nueva cantidad de monedas para el país de la sucursal con las que
cuenta el jugador después de llevar a cabo la compra. Es obtenido
a partir de la confirmación de compra del servidor Offsite.
Dependiendo del cliente que realice la petición, se tienen los siguientes
comportamientos:
Timer
*****
Únicamente está permitido comprar un producto de tiempo de la misma
categoría de la estación en la cual se juega actualmente. Al comprar
dicho producto, el tiempo restante del jugador es sumado con el nuevo
tiempo adquirido. La categoría de producto contratado por el usuario
cambiará a la categoría recién adquirida.
Si no se cuenta con moneda suficiente para realizar
la compra, se responde con el estado ``422 Unprocessable Entity``.
Por otro lado, si la compra de tiempo no es para la misma categoría de
producto que está siendo jugado, se responde con el estado
``409 Conflict``.
La compra de un producto de tiempo desde el Timer se lleva a cabo
únicamente para jugadores que tienen una partida activa. Por lo
tanto, si un jugador ya no cuenta con tiempo disponible o si no
pertenece a un Match activo, esta ruta responde con el estado
``403 Forbidden``.
Assistant
*********
Si el tiempo del jugador al cual se asociará un nuevo producto sigue
corriendo, el asistente únicamente puede realizar una transacción para
una categoría de producto igual a la de aquella estación donde se
está jugando actualmente, para lo cual la lógica es equivalente a la
compra desde Timer. Para cualquier otra categoría de producto,
el tiempo del jugador debe estar pausado.
En caso de renovar tiempo para una categoría distinta a aquella
de la estación donde se está jugando actualmente, o distinta a la
categoría del último producto de tiempo adquirido (en caso de no estar
asignado a ninguna estación), el tiempo con el que cuente el jugador
al momento de realizar la compra se vuelve inutilizable.
.. note::
El remanente de tiempo con el que cuente un usuario se pierde
al abandonar el local o al adquirir un producto de tiempo de
distinta categoría.
Un jugador no puede contar con más de un producto de tiempo activo,
a menos que únicamente uno de estos (necesariamente el más antiguo)
tenga duración de todo el día y una categoría menor al
segundo producto. Al adquirir un segundo producto de tiempo
en una categoría mayor se pausa el primero, se corre el tiempo del
segundo producto comprado y, posteriormente, se continúa la redención
del primer tiempo, que debe tener una duración de todo el día.
Si no se cuenta con moneda suficiente para realizar
la compra, o si la compra viola las restricciones sobre un
segundo producto de tiempo, se responde con el estado ``409
Conflict``.
Como resultado de la compra exitosa de un producto para un jugador
que se encuentra en una estación, se comunica a los asistentes de
la actualización del Match al que pertenece el jugador
como se indica en :ref:`broadcast-update-match`.
Interpretación del modelo de transacción
========================================
Un jugador posee múltiples monederos de coins Arena,
uno por país. La decisión del monedero vigente está en
función del país en el que se encuentra la sucursal donde
lleven a cabo transacciones.
El modelo *Cutoff Period* corresponde a un periodo de
corte de las transacciones de un usuario. Estos periodos
corren mensualmente, y la necesidad de creación de uno
se determina cuando, al insertar una nueva transacción,
se verifica si ha transcurrido un mes desde la apertura
del último corte. Es por esto que un jugador tiene *n*
periodos de corte de moneda Arena vigentes, donde *n*
es el número de países donde existen sucursales Arena.
Al cerrar un periodo de corte, se registra la cantidad
de monedas Arena al cierre del mismo, cantidad que
debe coincidir con el saldo inicial del siguiente
periodo.
El conteo de monedas de un jugador se lleva a cabo
siguiendo los pasos descritos a continuación:
1. Se obtiene el periodo de corte vigente del jugador
en el país donde se solicita la transacción. El
campo ``initial_balance`` corresponde al monto
inicial de monedas que registra el periodo.
2. Se cuentan las transacciones de moneda en el
periodo de corte, donde ``is_negative`` indica
si el monto es en contra o a favor, es decir, se
precisa un decremento o incremento de moneda si
la variable es ``true`` o ``false``,
respectivamente. Las transacciones que no tengan
una fecha de aplicación, es decir, aquellas donde
el campo ``charged_at`` no esté establecido,
también son contadas en el cálculo de la moneda
del jugador. Este tipo de transacciones se
encuentran ligadas al modelo ``Hold``.
3. La cantidad resultante corresponde al saldo en
moneda Arena de un jugador.
Los campos de una transacción de moneda Arena son
los siguientes:
``id``
Identificador de la transacción, el cual es
almacenado por el servidor Onsite que la
solicita.
``amount``
Cantidad de moneda Arena cargada o descontada
del balance del jugador.
``isNegative``
Si el valor de verdad es ``true``, la cantidad
corresponde a un decremento de moneda. En caso
contrario, la moneda Arena debe incrementarse
como se indique en ``amount``.
``vistaTransNumber``
Corresponde al identificador de transacción
otorgado por el WS de Cinemex al momento de
efectuar compras de productos o verificaciones
de compra.
Este campo corresponde con el número de
ticket devuelto por puntos de venta Vista o
por el sistema en línea de venta.
Dado que puede solicitarse que se validen
múltiples transacciones en una sola petición,
este campo puede repetirse para múltiples
transacciones.
``userSessionId``
Identificador de la operación de compra.
Este campo existe cuando, desde el servidor Offsite,
se solicita la compra de productos de recarga
o tiempo/penalización.
Es una cadena de 32 símbolos alfanuméricos
tomados de manera aleatoria.
``chargedAt``
Fecha de aplicación de la transacción. En
caso de no estar establecido este campo,
la transacción cuenta como una retención
que no ha sido reportada al sistema de
Cinemex; aunque de igual manera debe ser
considerada en el conteo de monedas.
``accessKey``
Corresponde a la autorización de la
entidad que solicitó la transacción.
El conteo de monedas es cacheado con el objetivo de limitar
la cantidad de operaciones durante la consulta del balance
del jugador. Al llevar a cabo una operación que ingrese
directamente al período de corte vigente del jugador, se
actualiza el campo ``current_balance`` para reflejar el
último estado calculado.
Cuando se solicite conocer la cantidad de monedas de un
jugador, el balance más reciente del corte en el país
será operado con el total de retenciones efectuadas al
Player.
Consulta de productos
=====================
A continuación, se expone la ruta en el WS de Cinemex que
permite la consulta de productos de tiempo, recarga,
y penalización.
WS Cinemex: ``GET /wsVistaWebClient/RESTData.svc/concession-items``
-------------------------------------------------------------------
**Autorización:** Header ``connectapitoken``
Mediante esta ruta se obtiene el listado de productos de tiempo
del complejo indicado. La petición admite los siguientes parámetros:
========== ============ ======================================== ===============
Nombre Tipo Descripción Ejemplo
========== ============ ======================================== ===============
cinemaId * Integer | Identificador de la sucursal de la 526
cual se solicitan productos.
clientId * Integer | Cadena que representa al cliente 111.111.111.111
========== ============ ======================================== ===============
La ruta responde con el estado ``200 OK`` acompañado de la
siguiente información:
.. code-block:: yaml
{
"ConcessionItems": [
{
"AlternateItems": [],
"CanGetBarcode": false,
"Description": "IMMERSIVE ZONE 1H",
"DescriptionAlt": "PZA",
"DescriptionTranslations": [],
"ExtendedDescription": "",
"ExtendedDescriptionAlt": "",
"HeadOfficeItemCode": "C000000294",
"Id": "7810015",
"IsAvailableForInSeatDelivery": true,
"IsAvailableForPickupAtCounter": true,
"IsRecognitionOnly": false,
"ItemClassCode": "0002",
"LoyaltyDiscountCode": "",
"ModifierGroups": [],
"PackageChildItems": [],
"PriceInCents": 100,
"RecognitionExpiryDate": null,
"RecognitionId": 0,
"RecognitionMaxQuantity": 0,
"RecognitionPointsCost": 0,
"RecognitionSequenceNumber": 0,
"RedeemableType": 1,
"RequiresPickup": false,
"RestrictToLoyalty": false,
"ShippingMethod": "N",
"SmartModifiers": [],
"VoucherSaleType": ""
}
]
}