====== 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": "" } ] }