pagarme-bifrost-js
Version:
PagarMe Bifrost WebSocket JS Class. An easy implementation of PagarMe Bifrost WebSocket Service.
8 lines (7 loc) • 16.1 kB
JavaScript
/*!
* pagarme-bifrost-js v0.2.5
* (c) Heitor Ramon Ribeiro <heitor.ramon@gmail.com>
* Released under the MIT License.
*/
;function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),e}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_nonIterableSpread()}function _arrayWithoutHoles(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t<e.length;t++)r[t]=e[t];return r}}function _iterableToArray(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}var NAME="%c Pagar.Me Bifrost ",BACKGROUND="background:#f26722 ; padding: 2px; border-radius: 2px; color: #fff ";function required(e,t){if(void 0===t)throw new Error("Parâmetro obrigatório ".concat(e," não declarado."));return t}function logInfo(e){console.log(NAME,BACKGROUND,e)}function logError(e){console.error(NAME,BACKGROUND,e)}function addSpaces(e,t){var r;return(r=e.split("")).concat.apply(r,_toConsumableArray(Array(t).fill(" "))).slice(0,t).join("")}function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}function _awaitIgnored(e,t){if(!t)return e&&e.then?e.then(_empty):Promise.resolve()}function _async(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function _empty(){}function _finallyRethrows(e,t){try{var r=e()}catch(e){return t(!0,e)}return r&&r.then?r.then(t.bind(null,!1),t.bind(null,!0)):t(!1,value)}function _call(e,t,r){if(r)return t?t(e()):e();try{var n=Promise.resolve(e());return t?n.then(t):n}catch(e){return Promise.reject(e)}}function _rethrow(e,t){if(e)throw t;return t}function _catch(e,t){try{var r=e()}catch(e){return t(e)}return r&&r.then?r.then(void 0,t):r}function _await(e,t,r){return r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var privateVariables={request:{listDevices:1,initialize:2,process:4,finish:5,displayMessage:6,status:7,closeContext:8},response:{unknownCommand:0,devicesListed:1,initialized:2,alreadyInitialized:3,processed:4,finished:5,messageDisplayed:6,status:7,contextClosed:8,error:9},paymentMethods:{credit:1,debit:2},errorStrings:{errorContextString:"Device already in use by context ",errorInitialize:"An error has occured with the [Initialize] request. See the log and contact the support.",errorOperationErrored:"Transaction Errored",errorOperationFailed:"Error: 43",errorOperationCanceled:"Transaction Canceled",catastroficError:"Error: 14"},ws:null,timeout:null,close:!0,timeoutConn:null};function _connect(e,t){return null===privateVariables.ws?privateVariables.ws=new WebSocket(e):2!==privateVariables.ws.readyState&&3!==privateVariables.ws.readyState||(_disconnect(),privateVariables.ws=new WebSocket(e)),new Promise(function(e,r){try{_timeout();var n=function(){_clearTimeout(),privateVariables.ws.send(JSON.stringify(t)),_timeout(6e4)};0===privateVariables.ws.readyState?privateVariables.ws.onopen=function(){n()}:1===privateVariables.ws.readyState&&n(),privateVariables.ws.onmessage=function(t){_clearTimeout(),e(JSON.parse(t.data))},privateVariables.ws.onerror=function(e){_clearTimeout(),e&&r(e)}}catch(e){r(e)}})}function _disconnect(){privateVariables.ws.close(),privateVariables.ws=null}function _clearTimeout(){privateVariables.close=!1,clearTimeout(privateVariables.timeoutConn)}function _timeout(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1e4;privateVariables.close=!0,privateVariables.timeoutConn=setTimeout(function(){privateVariables.close?privateVariables.ws.close():_clearTimeout()},e)}var BifrostWebSocket=function(){function e(t){var r=t.contextId,n=t.baudRate,i=t.debug,o=t.host;_classCallCheck(this,e),this.debug=i||!1,this.contextId=required("contextId",r),this.baudRate=n||115200,this._connected=!1,this.devices=[],this._host=o||"wss://localhost:2000/mpos",this._amount=0,this._method="",this.lastRequest=null}return _createClass(e,[{key:"debugLog",value:function(e){this.debug&&logInfo(e)}},{key:"classError",value:function(e){throw this.debugLog("object"===_typeof(e)?e.text:e),new Error(e)}},{key:"defineRequest",value:function(e){void 0===e&&(this.lastRequest=null),null!==this.lastRequest&&this.classError("Não é possível fazer requisições asíncronas, termine uma ação antes de executar a outra."),"number"==typeof e&&(this.lastRequest=e)}},{key:"closePinPadContext",value:function(e){var t=this;return _await(_finallyRethrows(function(){return _catch(function(){return t.debugLog("Fechando contexto do Serviço Bifrost."),t.defineRequest(privateVariables.request.closeContext),_await(_connect(t._host,{request_type:privateVariables.request.closeContext,context_id:e||t.contextId}),function(){return t._connected=!1,t.defineRequest(),Promise.resolve(!0)})},function(e){return t.defineRequest(),Promise.reject(e)})},function(e,t){return _call(_disconnect,function(){return _rethrow(e,t)})}))}},{key:"getPinPadDevices",value:_async(function(){var e=this;return _catch(function(){return e.debugLog("Buscando lista de dispositivos do sistema."),e.defineRequest(privateVariables.request.listDevices),_await(_connect(e._host,{request_type:privateVariables.request.listDevices,context_id:e.contextId}),function(t){return e.debugLog(t),e.devices=t.device_list,e.defineRequest(),Promise.resolve(e.devices)})},function(t){return e.defineRequest(),Promise.reject(t)})})},{key:"initialize",value:_async(function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return _finallyRethrows(function(){return _catch(function(){return t.debugLog("Conectando ao PinPad ".concat(t.devices[r].id,".")),t.defineRequest(privateVariables.request.initialize),_await(_connect(t._host,{request_type:privateVariables.request.initialize,context_id:t.contextId,initialize:{device_id:t.devices[r].id,encryption_key:e.encryptionKey,baud_rate:t.baudRate,simple_initialize:e.simpleInitialize,timeout_milliseconds:e.timeoutMilliseconds}}),function(n){var i=!1;return _invoke(function(){if(t.lastRequest===privateVariables.request.initialize)return t.defineRequest(),n.response_type===privateVariables.response.initialized?(t._connected=!0,i=!0,t.debugLog("PinPad ".concat(t.devices[r].id," inicializado com sucesso."))):_invoke(function(){if(n.response_type===privateVariables.response.alreadyInitialized)return t.debugLog("Serviço Bifrost já inicializado, reiniciando a conexão."),_await(t.closePinPadContext(n.context_id),function(){return _await(t.initialize({encryptionKey:e.encryptionKey,baud_rate:t.baudRate,simpleInitialize:e.simpleInitialize,timeoutMilliseconds:e.timeoutMilliseconds},0),function(){return i=!0,!1})})},function(o){return i?o:_invoke(function(){if(n.response_type===privateVariables.response.error&&privateVariables.errorStrings.errorInitialize){var o=r+1;return o>t.devices.length?_call(_disconnect,function(){t.classError("Não foi possível inicial a conexão com nenhum dispositivo.")}):(t.debugLog("Dispositivo selecionado não é válido, inicializando novamente com próximo dispositivo da lista."),_await(t.initialize({encryptionKey:e.encryptionKey,baud_rate:t.baudRate,simpleInitialize:e.simpleInitialize,timeoutMilliseconds:e.timeoutMilliseconds},o),function(){return i=!0,!1}))}},function(r){return n.error===privateVariables.errorStrings.catastroficError?(t.classError("Erro catastrófico no sistema. Por favor, reinicialize o PinPad e o Serviço do Bifrost"),_disconnect(),i=!0,!1):function(){if(n.error&&n.error.includes(privateVariables.errorStrings.errorContextString)){t.debugLog("Serviço Bifrost com contexto diferente do definido na classe.");var r=n.error.split(privateVariables.errorStrings.errorContextString)[1];return _await(t.closePinPadContext(r),function(r){return _invoke(function(){if(r)return _awaitIgnored(t.initialize({encryptionKey:e.encryptionKey,baud_rate:t.baudRate,simpleInitialize:e.simpleInitialize,timeoutMilliseconds:e.timeoutMilliseconds},0))},function(){return i=!0,!1})})}}()})})},function(e){return i?e:n})})},function(e){return Promise.reject(e)})},function(e,r){return t.defineRequest(),_rethrow(e,r)})})},{key:"getPinPanStatus",value:_async(function(){var e=this;return _finallyRethrows(function(){return _catch(function(){return e.debugLog("Buscando status do serviço Bifrost."),e.defineRequest(privateVariables.request.status),_await(_connect(e._host,{request_type:privateVariables.request.status,context_id:e.contextId}),function(e){return logInfo(e),Promise.resolve({connected:!!e.status.code,contextId:e.context_id,connectedDeviceId:e.status.connected_device_id})})},function(e){return Promise.reject(e)})},function(t,r){return e.defineRequest(),_rethrow(t,r)})})},{key:"displayMessageOnPinPadScreen",value:_async(function(e){var t=this;return _finallyRethrows(function(){return _catch(function(){return t.debugLog('Mostrando "'.concat(e,'" no display do PinPad.')),t.defineRequest(privateVariables.request.displayMessage),_await(_connect(t._host,{request_type:privateVariables.request.displayMessage,context_id:t.contextId,display_message:{message:e}}),function(e){return Promise.resolve(e)})},function(e){return Promise.reject(e)})},function(e,r){return t.defineRequest(),_rethrow(e,r)})})},{key:"startPayment",value:function(e){try{this.amount=e.amount,this.method=e.method||privateVariables.paymentMethods.credit}catch(e){throw new Error(e)}}},{key:"startPaymentProcess",value:_async(function(){var e=this;return _finallyRethrows(function(){return _catch(function(){return e.debugLog("Iniciando processo de pagamento. Venda via ".concat(e.method,", valor ").concat(e.amount/100)),e.defineRequest(privateVariables.request.process),_await(_connect(e._host,{request_type:privateVariables.request.process,context_id:e.contextId,process:{amount:e.amount,magstripe_payment_method:e.method}}),function(t){if(e.lastRequest===privateVariables.request.process){if(t.error===privateVariables.errorStrings.errorOperationCanceled){var r={text:"Operação cancelada pelo usuário.",type:"cardCanceled"};return e.debugLog(r.text),Promise.reject(r)}if(t.error===privateVariables.errorStrings.errorOperationErrored||t.error===privateVariables.errorStrings.errorOperationFailed){var n={text:"Aconteceu algum erro na operação, tente novamente.",type:"operationError"};return e.debugLog(n.text),Promise.reject(n)}if(t.response_type===privateVariables.response.processed)return Promise.resolve(t.process)}})},function(e){return Promise.reject(e)})},function(t,r){return e.defineRequest(),_rethrow(t,r)})})},{key:"finishPaymentProcess",value:_async(function(e,t){var r=this;return _finallyRethrows(function(){return _catch(function(){return r.debugLog("Finalizando a venda via ".concat(r.method)),r.defineRequest(privateVariables.request.finish),_await(_connect(r._host,{request_type:privateVariables.request.finish,context_id:r.contextId,finish:{success:!(!e||!t),response_code:e||"0000",emv_data:t||"000000000.0000"}}))},function(e){return Promise.reject(e)})},function(e,t){return r.defineRequest(),_rethrow(e,t)})})},{key:"amount",get:function(){return this._amount},set:function(e){if("number"==typeof e&&e<=0)throw new Error("Não é possível definir um valor menor ou igual a zero.");this._amount=100*parseFloat(e)}},{key:"connected",get:function(){return this._connected}},{key:"method",get:function(){return this._method},set:function(e){if("string"==typeof e)Object.keys(privateVariables.paymentMethods).includes(e)&&(this._method=e);else{if("number"!=typeof e)throw new Error("Método de pagamento não permitido.");privateVariables.paymentMethods.find(function(t){return t===e})&&(this._method=Object.keys(privateVariables.paymentMethods).find(function(t){return privateVariables.paymentMethods[t]===e}))}}}]),e}();function _awaitIgnored$1(e,t){if(!t)return e&&e.then?e.then(_empty$1):Promise.resolve()}function _empty$1(){}function _async$1(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function _catch$1(e,t){try{var r=e()}catch(e){return t(e)}return r&&r.then?r.then(void 0,t):r}function _await$1(e,t,r){return r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}function notConnected(){throw new Error("PinPad não foi inicializado. Por favor, inicie o PinPad antes de executar outro comando.")}var PagarMeBifrost=function(){function e(t){_classCallCheck(this,e);try{this.baudRate=t.baudRate||115200,this.contextId=required("contextId",t.contextId),this.encryptionKey=required("encryptionKey",t.encryptionKey),this.pinPadMaxCharLine=t.pinPadMaxCharLine||16,this.pinPadMaxChar=t.pinPadMaxChar||32,this.pinPanDisplayLines=t.pinPanDisplayLines||2;var r={debug:t.debug||!1,contextId:this.contextId,host:t.host||"wss://localhost:2000/mpos"};this.__bifrost__=new BifrostWebSocket(r)}catch(e){logError(e,!0)}}return _createClass(e,[{key:"initialize",value:_async$1(function(){var e=this;return _catch$1(function(){return _await$1(e.__bifrost__.getPinPadDevices(),function(){return _await$1(e.__bifrost__.initialize({encryptionKey:e.encryptionKey}),function(){return Promise.resolve(!0)})})},function(e){return Promise.reject(e)})})},{key:"terminate",value:_async$1(function(){var e=this;return new Promise(function(t,r){e.connected?e.__bifrost__.closePinPadContext().then(function(){t(!0)}).catch(function(e){r(e)}):notConnected()})})},{key:"restart",value:_async$1(function(){var e=this;return _catch$1(function(){return _await$1(e.terminate(),function(){return e.initialize()})},function(e){return Promise.reject(e)})})},{key:"status",value:_async$1(function(){try{return this.connected||notConnected(),this.__bifrost__.getPinPanStatus()}catch(e){return Promise.reject(e)}})},{key:"showMessage",value:_async$1(function(e){var t=this;return _catch$1(function(){t.connected||notConnected();var r=t.pinPadMaxCharLine,n=t.pinPadMaxChar,i="";return Array.isArray(e)&&(i=e.slice(0,t.pinPanDisplayLines).map(function(e){return addSpaces(e,r)}).join("")),"string"==typeof e&&(i=addSpaces(e,n)),_await$1(t.__bifrost__.displayMessageOnPinPadScreen(i),function(){return Promise.resolve(i)})},function(e){return Promise.reject(e)})})},{key:"payment",value:_async$1(function(e,t){var r=this;return _catch$1(function(){return r.connected||notConnected(),r.__bifrost__.startPayment({amount:e,method:t}),_await$1(r.__bifrost__.startPaymentProcess(),function(e){return Promise.resolve(e)})},function(e){return logError(e),_await$1(r.showMessage(e.text),function(){return setTimeout(_async$1(function(){return _await$1(r.finish(),function(){return _await$1(r.terminate(),function(){setTimeout(_async$1(function(){return _awaitIgnored$1(r.initialize())}),2e3)})})}),2e3),Promise.reject(e)})})})},{key:"finish",value:_async$1(function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return _catch$1(function(){e.connected||notConnected();var r=t.code||"",n=t.emvData||"",i=t.timeout||2e3,o=t.messages||null;return _await$1(e.__bifrost__.finishPaymentProcess(r,n),function(t){return Array.isArray(o)&&o.forEach(function(t,r){setTimeout(_async$1(function(){return _awaitIgnored$1(e.showMessage(t))}),i*(r+1))}),"string"==typeof o&&setTimeout(_async$1(function(){return _awaitIgnored$1(e.showMessage(o))}),i),Promise.resolve(t)})},function(e){return Promise.reject(e)})})},{key:"connected",get:function(){return this.__bifrost__.connected}}]),e}();module.exports=PagarMeBifrost;
//# sourceMappingURL=index.js.map