ng-easycommerce 0.0.689 → 0.0.690

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ # Version 0.0.690
2
+ - Mobbex redirect: al volver desde la pasarela con estado `success` o `pending`, el checkout compacto finaliza la compra automáticamente con `checkoutService.complete()`.
3
+ - Mobbex redirect: se alinea el método con otros pagos externos que completan el pedido al regresar al sitio, evitando que el usuario pierda el estado si recarga o cierra la pestaña antes de terminar manualmente.
4
+ - Mobbex redirect: se conserva el flujo de retorno por `payment-state` y la apertura en pestaña nueva, sin embeber la URL externa dentro del checkout.
5
+
1
6
  # Version 0.0.689
2
7
  - SEO: `CollectionEcComponent` normaliza el breadcrumb antes de armar el `title`, aceptando valores string u objetos con `title`, `name` o `label` para evitar renders como `[object Object] | ...`.
3
8
  - SEO: el `title` de colección mantiene el patrón `'<sección> | <sitio>'` y la `description` vuelve a derivarse del texto visible de la categoría o del término de búsqueda.
@@ -11145,7 +11145,8 @@
11145
11145
  _this.isRedirectRedsys(code) ||
11146
11146
  _this.isRedirectCecaBank(code) ||
11147
11147
  _this.isPeyPalExpress(code) ||
11148
- _this.isPlaceToPay(code));
11148
+ _this.isPlaceToPay(code) ||
11149
+ _this.isMobbex(code));
11149
11150
  };
11150
11151
  _this.ecOnConstruct();
11151
11152
  return _this;
@@ -20185,111 +20186,298 @@
20185
20186
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20186
20187
  return c > 3 && r && Object.defineProperty(target, key, r), r;
20187
20188
  };
20189
+ var __values$4 = (this && this.__values) || function(o) {
20190
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
20191
+ if (m) return m.call(o);
20192
+ if (o && typeof o.length === "number") return {
20193
+ next: function () {
20194
+ if (o && i >= o.length) o = void 0;
20195
+ return { value: o && o[i++], done: !o };
20196
+ }
20197
+ };
20198
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
20199
+ };
20188
20200
  var MobbexEcComponent = /** @class */ (function (_super) {
20189
20201
  __extends$_(MobbexEcComponent, _super);
20190
- function MobbexEcComponent(renderer, connection, toastrService, consts, cartService, toastr, activedRoute, sanitizer, modalService) {
20202
+ function MobbexEcComponent(toastrService, cartService) {
20191
20203
  var _this = _super.call(this) || this;
20192
- _this.renderer = renderer;
20193
- _this.connection = connection;
20194
20204
  _this.toastrService = toastrService;
20195
- _this.consts = consts;
20196
20205
  _this.cartService = cartService;
20197
- _this.toastr = toastr;
20198
- _this.activedRoute = activedRoute;
20199
- _this.sanitizer = sanitizer;
20200
- _this.modalService = modalService;
20201
20206
  _this.method = null;
20202
20207
  _this.total_amount = 0;
20203
20208
  _this.user_data = null;
20204
20209
  _this.ready = new core.EventEmitter();
20205
- _this.loading = false;
20206
- _this.isDobleAuth = false;
20207
- _this.urls = [];
20208
- _this.closeModal = '';
20209
- _this.dataRedirect = function () { return _this.consts.getUrlBase() + 'shop-api/' + _this.consts.getChannel() + '/redsys/redirect/' + _this.cartService.cart_token + '/process-payment'; };
20210
- _this.clearStorageState = function () {
20211
- sessionStorage.removeItem('state');
20212
- localStorage.removeItem('state');
20213
- };
20214
- _this.clickClose = function () {
20215
- _this.closeModal = 'cancel';
20216
- _this.modalRef.hide();
20217
- _this.processError('Se cancelo el pago con mobbex');
20218
- };
20219
- _this.callState = function () {
20210
+ _this.loading = true;
20211
+ _this.processing = false;
20212
+ _this.url = null;
20213
+ _this.checkoutData = null;
20214
+ _this.popup = null;
20215
+ _this.pollTimer = null;
20216
+ _this.startedAt = 0;
20217
+ _this.finished = false;
20218
+ _this.checkoutKey = '';
20219
+ _this.bc = null;
20220
+ _this.checkoutRequestInFlight = false;
20221
+ _this.openCheckout = function () {
20222
+ if (!_this.url || _this.processing || typeof window === 'undefined')
20223
+ return;
20224
+ _this.clearStateKeys();
20225
+ _this.finished = false;
20226
+ _this.processing = true;
20227
+ _this.startedAt = Date.now();
20228
+ _this.popup = window.open(_this.url, '_blank');
20229
+ if (!_this.popup || _this.popup.closed) {
20230
+ _this.processing = false;
20231
+ _this.toastrService.show('No se pudo abrir la pasarela de pago. Verifique que su navegador permita nuevas pestañas.');
20232
+ return;
20233
+ }
20220
20234
  try {
20221
- var state = _this.closeModal != '' ? _this.closeModal : localStorage.getItem('state');
20222
- _this.loading = true;
20223
- state && console.log(state);
20224
- if (state) {
20225
- _this.loading = false;
20226
- sessionStorage.removeItem('state');
20227
- localStorage.removeItem('state');
20228
- if (state == 'success') {
20229
- _this.ready.emit(true);
20230
- }
20231
- if (state == 'cancel') {
20232
- return;
20233
- }
20234
- if (state == 'failure') {
20235
- _this.processError('');
20236
- }
20237
- _this.modalRef.hide();
20238
- return;
20239
- }
20240
- setTimeout(function () {
20241
- _this.callState();
20242
- }, 5000);
20235
+ _this.popup.opener = null;
20243
20236
  }
20244
- catch (error) {
20245
- console.error(error);
20237
+ catch (_a) {
20238
+ // Nothing to do.
20246
20239
  }
20240
+ _this.startPolling();
20247
20241
  };
20248
- _this.processError = function (err) {
20249
- _this.toastrService.show(err != '' ? err : 'payment-error');
20250
- console.log("ERROR ENVIO BACK ", err);
20242
+ _this.cancelCheckout = function () {
20243
+ if (_this.finished)
20244
+ return;
20245
+ _this.finishWithState('cancel', true);
20251
20246
  };
20252
20247
  _this.getCheckoutMobbex = function () {
20248
+ if (_this.checkoutRequestInFlight)
20249
+ return;
20253
20250
  _this.loading = true;
20254
- _this.paymentServiceInst.getCheckoutMobbex(_this.allData).then(function (res) {
20251
+ _this.checkoutRequestInFlight = true;
20252
+ var payload = _this.user_data || _this.allData || {};
20253
+ _this.paymentServiceInst.getCheckoutMobbex(payload).then(function (res) {
20255
20254
  var _a, _b, _c, _d;
20256
- _this.dataMobbex = res;
20257
- _this.url = ((_b = (_a = res) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.url) && _this.sanitizer.bypassSecurityTrustResourceUrl((_d = (_c = res) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.url);
20255
+ _this.checkoutData = res || null;
20256
+ _this.checkoutKey = String(((_b = (_a = res) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.id) || _this.cartService.cart_token || '');
20257
+ _this.url = ((_d = (_c = res) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.url) || null;
20258
+ _this.safeSetStorage('mobbex:checkout-id', _this.checkoutKey);
20258
20259
  _this.loading = false;
20259
- }, function (err) {
20260
- _this.processError('operation-error');
20260
+ _this.checkoutRequestInFlight = false;
20261
+ if (!_this.url) {
20262
+ _this.processError('operation-error');
20263
+ }
20264
+ }, function () {
20261
20265
  _this.loading = false;
20266
+ _this.checkoutRequestInFlight = false;
20267
+ _this.processError('operation-error');
20262
20268
  });
20263
20269
  };
20270
+ _this.onStorage = function (event) {
20271
+ var _a;
20272
+ if (!((_a = event) === null || _a === void 0 ? void 0 : _a.key) || _this.finished)
20273
+ return;
20274
+ if (!_this.getStateKeys().includes(event.key))
20275
+ return;
20276
+ var state = _this.normalizeState(event.newValue);
20277
+ if (state) {
20278
+ _this.finishWithState(state, true);
20279
+ }
20280
+ };
20281
+ _this.onMessage = function (event) {
20282
+ _this.onBroadcastMessage(event);
20283
+ };
20284
+ _this.clearStorageState = function () {
20285
+ sessionStorage.removeItem('state');
20286
+ localStorage.removeItem('state');
20287
+ };
20288
+ _this.processError = function (err) {
20289
+ _this.toastrService.show(err !== '' ? err : 'payment-error');
20290
+ };
20264
20291
  _this.ecOnConstruct();
20265
20292
  return _this;
20266
20293
  }
20267
20294
  MobbexEcComponent.prototype.ngOnInit = function () {
20268
- this.getCheckoutMobbex();
20295
+ var _this = this;
20296
+ if (typeof window !== 'undefined') {
20297
+ window.addEventListener('storage', this.onStorage);
20298
+ window.addEventListener('message', this.onMessage);
20299
+ if (window.BroadcastChannel) {
20300
+ this.bc = new BroadcastChannel('mobbex_payment');
20301
+ this.bc.onmessage = function (event) { return _this.onBroadcastMessage(event); };
20302
+ }
20303
+ }
20304
+ this.loadCheckout();
20269
20305
  this.ecOnInit();
20270
20306
  };
20271
20307
  MobbexEcComponent.prototype.ngOnDestroy = function () {
20272
- // console.log("SE DESTROZA");
20308
+ if (typeof window !== 'undefined') {
20309
+ window.removeEventListener('storage', this.onStorage);
20310
+ window.removeEventListener('message', this.onMessage);
20311
+ }
20312
+ if (this.bc) {
20313
+ try {
20314
+ this.bc.close();
20315
+ }
20316
+ catch (_a) {
20317
+ // Nothing to do.
20318
+ }
20319
+ this.bc = null;
20320
+ }
20321
+ this.stopPolling();
20322
+ this.closePopup();
20273
20323
  };
20274
- MobbexEcComponent.prototype.ngOnChanges = function () {
20275
- // console.log("SE CAMBIO");
20324
+ MobbexEcComponent.prototype.loadCheckout = function () {
20325
+ if (!this.paymentServiceInst || !this.method)
20326
+ return;
20327
+ if (this.url && !this.loading)
20328
+ return;
20329
+ this.getCheckoutMobbex();
20276
20330
  };
20277
- MobbexEcComponent.prototype.openModal = function (template) {
20331
+ MobbexEcComponent.prototype.startPolling = function () {
20332
+ var _this = this;
20333
+ this.stopPolling();
20334
+ this.pollTimer = setInterval(function () {
20335
+ var _a, _b, _c, _d, _e, _f;
20336
+ if (_this.finished) {
20337
+ _this.stopPolling();
20338
+ return;
20339
+ }
20340
+ var state = _this.readState();
20341
+ if (state) {
20342
+ _this.finishWithState(state, true);
20343
+ return;
20344
+ }
20345
+ if ((_a = _this.popup) === null || _a === void 0 ? void 0 : _a.closed) {
20346
+ _this.finishWithState('cancel', true);
20347
+ return;
20348
+ }
20349
+ var rawTimeoutMinutes = Number((_f = (_d = (_c = (_b = _this.checkoutData) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.timeout, (_d !== null && _d !== void 0 ? _d : (_e = _this.checkoutData) === null || _e === void 0 ? void 0 : _e.timeout)), (_f !== null && _f !== void 0 ? _f : 60)));
20350
+ var timeoutMinutes = Number.isFinite(rawTimeoutMinutes) && rawTimeoutMinutes > 0 ? rawTimeoutMinutes : 60;
20351
+ var timeoutMs = Math.max(5, timeoutMinutes + 1) * 60 * 1000;
20352
+ if (Date.now() - _this.startedAt > timeoutMs) {
20353
+ _this.finishWithState('failure', true, 'Tiempo de espera agotado al procesar el pago con Mobbex.');
20354
+ }
20355
+ }, 1000);
20356
+ };
20357
+ MobbexEcComponent.prototype.onBroadcastMessage = function (event) {
20358
+ var _a;
20359
+ var payload = (_a = event) === null || _a === void 0 ? void 0 : _a.data;
20360
+ if (!payload || payload.type !== 'mobbex:state' || this.finished)
20361
+ return;
20362
+ if (this.checkoutKey && payload.checkoutKey && payload.checkoutKey !== this.checkoutKey)
20363
+ return;
20364
+ var state = this.normalizeState(payload.state);
20365
+ if (state) {
20366
+ this.finishWithState(state, true);
20367
+ }
20368
+ };
20369
+ MobbexEcComponent.prototype.finishWithState = function (state, closePopup, customMessage) {
20370
+ if (closePopup === void 0) { closePopup = false; }
20371
+ if (customMessage === void 0) { customMessage = ''; }
20372
+ if (this.finished)
20373
+ return;
20374
+ this.finished = true;
20375
+ this.processing = false;
20376
+ this.stopPolling();
20377
+ if (closePopup) {
20378
+ this.closePopup();
20379
+ }
20380
+ this.clearStateKeys();
20381
+ if (state === 'success' || state === 'pending') {
20382
+ this.ready.emit(true);
20383
+ return;
20384
+ }
20385
+ this.processError(customMessage || (state === 'cancel' ? 'Se canceló el pago con Mobbex' : ''));
20386
+ };
20387
+ MobbexEcComponent.prototype.readState = function () {
20388
+ var e_1, _a;
20389
+ var keys = this.getStateKeys();
20390
+ try {
20391
+ for (var keys_1 = __values$4(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
20392
+ var key = keys_1_1.value;
20393
+ var value = this.safeGetStorage(key);
20394
+ var normalized = this.normalizeState(value);
20395
+ if (normalized)
20396
+ return normalized;
20397
+ }
20398
+ }
20399
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
20400
+ finally {
20401
+ try {
20402
+ if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
20403
+ }
20404
+ finally { if (e_1) throw e_1.error; }
20405
+ }
20406
+ return null;
20407
+ };
20408
+ MobbexEcComponent.prototype.normalizeState = function (value) {
20409
+ var raw = String(value || '').toLowerCase();
20410
+ if (!raw)
20411
+ return null;
20412
+ if (raw === '200' || raw === 'ok' || raw === 'success')
20413
+ return 'success';
20414
+ if (raw === 'pending' || raw === 'in_process' || raw === 'in_review' || raw === 'challenge')
20415
+ return 'pending';
20416
+ if (raw === 'cancel' || raw === '0' || raw === 'none')
20417
+ return 'cancel';
20418
+ if (raw === 'failure' || raw === 'error' || raw === 'expired' || raw === '401')
20419
+ return 'failure';
20420
+ return null;
20421
+ };
20422
+ MobbexEcComponent.prototype.getStateKeys = function () {
20423
+ var keys = ['state'];
20424
+ if (this.checkoutKey) {
20425
+ keys.unshift("mobbex:state:" + this.checkoutKey);
20426
+ }
20427
+ return keys;
20428
+ };
20429
+ MobbexEcComponent.prototype.clearStateKeys = function () {
20278
20430
  this.clearStorageState();
20279
- this.modalRef = this.modalService.show(template, { class: 'modal-lg modal-dialog-centered ', keyboard: false, backdrop: 'static', animated: true });
20280
- this.closeModal = '';
20281
- this.callState();
20431
+ if (this.checkoutKey) {
20432
+ this.safeRemoveStorage("mobbex:state:" + this.checkoutKey);
20433
+ this.safeRemoveStorage('mobbex:checkout-id');
20434
+ }
20435
+ };
20436
+ MobbexEcComponent.prototype.stopPolling = function () {
20437
+ if (this.pollTimer) {
20438
+ clearInterval(this.pollTimer);
20439
+ this.pollTimer = null;
20440
+ }
20441
+ };
20442
+ MobbexEcComponent.prototype.closePopup = function () {
20443
+ if (!this.popup)
20444
+ return;
20445
+ try {
20446
+ if (!this.popup.closed)
20447
+ this.popup.close();
20448
+ }
20449
+ catch (_a) {
20450
+ // Nothing to do.
20451
+ }
20452
+ this.popup = null;
20453
+ };
20454
+ MobbexEcComponent.prototype.safeGetStorage = function (key) {
20455
+ try {
20456
+ return localStorage.getItem(key);
20457
+ }
20458
+ catch (_a) {
20459
+ return null;
20460
+ }
20461
+ };
20462
+ MobbexEcComponent.prototype.safeRemoveStorage = function (key) {
20463
+ try {
20464
+ localStorage.removeItem(key);
20465
+ }
20466
+ catch (_a) {
20467
+ // Nothing to do.
20468
+ }
20469
+ };
20470
+ MobbexEcComponent.prototype.safeSetStorage = function (key, value) {
20471
+ try {
20472
+ localStorage.setItem(key, value);
20473
+ }
20474
+ catch (_a) {
20475
+ // Nothing to do.
20476
+ }
20282
20477
  };
20283
20478
  MobbexEcComponent.ctorParameters = function () { return [
20284
- { type: core.Renderer2 },
20285
- { type: ConnectionService },
20286
- { type: ToastService },
20287
- { type: Constants },
20288
- { type: CartService },
20289
20479
  { type: ToastService },
20290
- { type: router.ActivatedRoute },
20291
- { type: platformBrowser.DomSanitizer },
20292
- { type: modal.BsModalService }
20480
+ { type: CartService }
20293
20481
  ]; };
20294
20482
  __decorate$1F([
20295
20483
  core.Input()
@@ -20309,15 +20497,11 @@
20309
20497
  __decorate$1F([
20310
20498
  core.Output()
20311
20499
  ], MobbexEcComponent.prototype, "ready", void 0);
20312
- __decorate$1F([
20313
- core.ViewChild('template')
20314
- ], MobbexEcComponent.prototype, "template", void 0);
20315
20500
  MobbexEcComponent = __decorate$1F([
20316
20501
  core.Component({
20317
20502
  selector: 'app-mobbex-ec',
20318
- template: "<div class=\"text-center\">\n <h3>Continuar con el pago en Mobbex</h3>\n <p *ngIf=\"method\" class=\"px-5\">{{ method?.description }}</p>\n <p *ngIf=\"method\" class=\"px-5\">{{ method?.instructions }}</p>\n <ng-container *ngIf=\"!loading ; else loadingUrl\">\n <button class=\"btn btn-outline-secondary comprar\" (click)=\"openModal(template)\">Pagar</button>\n </ng-container>\n</div>\n\n<ng-template #template>\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button\" class=\"btn-close\" aria-label=\"Close\" (click)=\"modalRef.hide(); loading = false;\">\n </button>\n </div>\n <div class=\"modal-body\">\n <iframe [src]=\"url\" frameborder=\"0\" class=\"iframeStyle\"></iframe>\n </div>\n </div>\n</ng-template>\n\n<ng-template #loadingUrl>\n <div class=\"d-flex flex-column jusitfy-content-center align-items-center mt-2\">\n <app-loading-full-ec></app-loading-full-ec>\n </div>\n</ng-template>",
20319
- providers: [modal.BsModalService],
20320
- styles: [".half-width{width:49%!important}.ml-1{margin-left:1%}#card-form{height:450px}.iframeStyle{height:800px;width:100%;max-height:800px}"]
20503
+ template: "<div class=\"text-center\">\n <h3>Continuar con el pago en Mobbex</h3>\n <p *ngIf=\"method\" class=\"px-5\">{{ method?.description }}</p>\n <p *ngIf=\"method\" class=\"px-5\">{{ method?.instructions }}</p>\n\n <ng-container *ngIf=\"loading; else checkoutReady\">\n <div class=\"d-flex flex-column justify-content-center align-items-center mt-2\">\n <app-loading-full-ec></app-loading-full-ec>\n <p class=\"mt-3 px-5 mobbex-note\">Preparando la pasarela de pago...</p>\n </div>\n </ng-container>\n\n <ng-template #checkoutReady>\n <p class=\"mt-3 px-5 mobbex-note\">\n Se abrir\u00E1 una nueva pesta\u00F1a para completar el pago.\n </p>\n\n <div class=\"d-flex flex-column align-items-center\">\n <button\n class=\"btn btn-outline-secondary comprar\"\n [disabled]=\"processing || !url\"\n (click)=\"openCheckout()\">\n Ir al sitio de Mobbex\n </button>\n\n <a\n *ngIf=\"url\"\n class=\"mt-2 small mobbex-link\"\n [href]=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n (click)=\"$event.preventDefault(); openCheckout()\">\n Si el bot\u00F3n no abre una nueva pesta\u00F1a, toc\u00E1 aqu\u00ED para continuar.\n </a>\n\n <button\n *ngIf=\"processing\"\n type=\"button\"\n class=\"btn btn-link text-secondary mt-2\"\n (click)=\"cancelCheckout()\">\n Cancelar pago\n </button>\n\n <p *ngIf=\"!url\" class=\"mt-2 px-5 text-danger\">\n No fue posible preparar la pasarela de pago.\n </p>\n </div>\n </ng-template>\n</div>\n",
20504
+ styles: [".mobbex-note{color:#6c757d}"]
20321
20505
  })
20322
20506
  ], MobbexEcComponent);
20323
20507
  return MobbexEcComponent;