@fire-spark/payments-clisitef-pinpad-rn 0.7.0 → 0.7.2

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/dist/index.d.ts CHANGED
@@ -17,12 +17,18 @@ type ClisitefPinPadOptions = {
17
17
  timeZone?: string;
18
18
  now?: () => Date;
19
19
  confirmationTimeoutMs?: number;
20
+ /**
21
+ * Payment deadline (`policy.timeout_ms`); defaults to 180 s. A
22
+ * `runtime.timeout_ms` in the payment or method config overrides it.
23
+ */
24
+ timeoutMs?: number;
20
25
  };
21
26
  /**
22
- * CliSiTef (Software Express) on the kiosk pinpad, Brazil. One adapter per
23
- * modality payment (DEBIT / CREDIT / VOUCHER in `payments.config`). The
24
- * pinpad waits on the customer: give the payment a `runtime.timeout_ms`
25
- * well above the 30 s default (e.g. 90 000).
27
+ * CliSiTef (Software Express) on the kiosk pinpad, Brazil. The payment lists
28
+ * its `modalities` (DEBIT / CREDIT / VOUCHER); with more than one the
29
+ * customer picks it before the pinpad starts. The pinpad waits on the
30
+ * customer, so the deadline is `timeoutMs` instead of the 30 s library
31
+ * default.
26
32
  */
27
33
  declare const clisitefPinPadPayments: (options?: ClisitefPinPadOptions) => PaymentAdapter;
28
34
  //#endregion
@@ -80,6 +86,11 @@ declare const CLISITEF_CANCEL_CODES: ReadonlySet<number>;
80
86
  declare const CLISITEF_INCONCLUSIVE_CODES: ReadonlySet<number>;
81
87
  /** Approved (`stage 1`) without `stage 2`: undo (legacy `CONFIRMATION_TIMEOUT_MS`). */
82
88
  declare const CLISITEF_CONFIRMATION_TIMEOUT_MS = 60000;
89
+ /**
90
+ * Payment deadline: covers the pinpad table load (`OBTENDO REGISTRO`), which
91
+ * can take minutes, plus card and PIN entry.
92
+ */
93
+ declare const CLISITEF_PAYMENT_TIMEOUT_MS = 180000;
83
94
  /** Legacy operator when the merchant config has none. */
84
95
  declare const CLISITEF_DEFAULT_OPERATOR = "KIOSKO_BR";
85
96
  /** Device-wide record of the last transaction, to undo it after a crash. */
@@ -117,14 +128,20 @@ declare const clisitefPinPadErrors: Readonly<Record<string, PaymentErrorEntry>>
117
128
  //#endregion
118
129
  //#region src/settings.d.ts
119
130
  declare const CLISITEF_PINPAD_TYPES: readonly ["ANDROID_USB", "ANDROID_BT", "ANDROID_AUTO"];
120
- /** Ficha §6: filled per kiosk in the device settings. */
131
+ /**
132
+ * Ficha §6: filled per kiosk in the device settings. SiTef IP, store code
133
+ * and store CNPJ come from the payment's store settings (`config.stores`);
134
+ * the device values only override them.
135
+ */
121
136
  declare const clisitefPinPadDeviceFields: DeviceField[];
122
137
  type ClisitefModality = keyof typeof CLISITEF_MODALITY;
138
+ type ClisitefCardModality = Exclude<ClisitefModality, "PIX">;
123
139
  type ClisitefPinPadSettings = {
124
140
  configure: ClisitefConfigureParams;
125
- modality: Exclude<ClisitefModality, "PIX">;
141
+ /** Asked to the customer when there is more than one. */
142
+ modalities: ClisitefCardModality[];
126
143
  operator: string;
127
- restrictions: string;
144
+ restrictions: Partial<Record<ClisitefCardModality, string>>;
128
145
  terminalNumber: string;
129
146
  };
130
147
  /** `payments.config` (merchant) + device settings; throws when incomplete. */
@@ -204,4 +221,4 @@ type ClisitefTransactionInput = {
204
221
  */
205
222
  declare const runClisitefTransaction: (input: ClisitefTransactionInput) => Promise<ClisitefOutcome>;
206
223
  //#endregion
207
- export { CLISITEF_CANCEL_CODES, CLISITEF_CAPTURE_FIELDS, CLISITEF_COMMAND, CLISITEF_CONFIRMATION_TIMEOUT_MS, CLISITEF_DEFAULT_OPERATOR, CLISITEF_FIELD, CLISITEF_INCONCLUSIVE_CODES, CLISITEF_NO, CLISITEF_PINPAD_TYPES, CLISITEF_STORAGE_KEY, CLISITEF_YES, ClisitefFields, ClisitefModality, ClisitefOutcome, ClisitefOutcomeStatus, ClisitefPinPadOptions, ClisitefPinPadSettings, ClisitefTransactionInput, ClisitefTransactionRecord, ClisitefTransactionState, clisitefDetails, clisitefLast4, clisitefMetadata, clisitefPinPadCapabilities, clisitefPinPadDeviceFields, clisitefPinPadErrors, clisitefPinPadPayments, isOpen, readClisitefPinPadSettings, readTransaction, runClisitefTransaction, writeTransaction };
224
+ export { CLISITEF_CANCEL_CODES, CLISITEF_CAPTURE_FIELDS, CLISITEF_COMMAND, CLISITEF_CONFIRMATION_TIMEOUT_MS, CLISITEF_DEFAULT_OPERATOR, CLISITEF_FIELD, CLISITEF_INCONCLUSIVE_CODES, CLISITEF_NO, CLISITEF_PAYMENT_TIMEOUT_MS, CLISITEF_PINPAD_TYPES, CLISITEF_STORAGE_KEY, CLISITEF_YES, ClisitefCardModality, ClisitefFields, ClisitefModality, ClisitefOutcome, ClisitefOutcomeStatus, ClisitefPinPadOptions, ClisitefPinPadSettings, ClisitefTransactionInput, ClisitefTransactionRecord, ClisitefTransactionState, clisitefDetails, clisitefLast4, clisitefMetadata, clisitefPinPadCapabilities, clisitefPinPadDeviceFields, clisitefPinPadErrors, clisitefPinPadPayments, isOpen, readClisitefPinPadSettings, readTransaction, runClisitefTransaction, writeTransaction };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PaymentError, createPaymentError, definePaymentErrors, toPaymentError } from "@fire-spark/payments";
2
- import { CLISITEF_ABORT_FLAG, CLISITEF_CONFIRM, CLISITEF_MODALITY, CLISITEF_RESULT, CLISITEF_TIMEOUT_CODE, clisitef, clisitefAdditionalParams, clisitefFiscalDateTime, formatClisitefAmount, parseClisitefMenu } from "@fire-spark/payments-clisitef-client";
2
+ import { CLISITEF_ABORT_FLAG, CLISITEF_CONFIRM, CLISITEF_MODALITY, CLISITEF_RESULT, CLISITEF_TIMEOUT_CODE, clisitef, clisitefAdditionalParams, clisitefDebug, clisitefDebugCall, clisitefFiscalDateTime, formatClisitefAmount, parseClisitefMenu } from "@fire-spark/payments-clisitef-client";
3
3
  //#region src/constants.ts
4
4
  /**
5
5
  * `onData` commands handled by the adapter (Fiserv "Tabela de códigos de
@@ -71,6 +71,11 @@ const CLISITEF_INCONCLUSIVE_CODES = /* @__PURE__ */ new Set([
71
71
  ]);
72
72
  /** Approved (`stage 1`) without `stage 2`: undo (legacy `CONFIRMATION_TIMEOUT_MS`). */
73
73
  const CLISITEF_CONFIRMATION_TIMEOUT_MS = 6e4;
74
+ /**
75
+ * Payment deadline: covers the pinpad table load (`OBTENDO REGISTRO`), which
76
+ * can take minutes, plus card and PIN entry.
77
+ */
78
+ const CLISITEF_PAYMENT_TIMEOUT_MS = 18e4;
74
79
  /** Legacy operator when the merchant config has none. */
75
80
  const CLISITEF_DEFAULT_OPERATOR = "KIOSKO_BR";
76
81
  /** Device-wide record of the last transaction, to undo it after a crash. */
@@ -226,40 +231,29 @@ const CLISITEF_PINPAD_TYPES = [
226
231
  "ANDROID_BT",
227
232
  "ANDROID_AUTO"
228
233
  ];
229
- /** Ficha §6: filled per kiosk in the device settings. */
230
- const clisitefPinPadDeviceFields = [
231
- {
232
- key: "sitef_ip",
233
- label: "SiTef server IP",
234
- type: "text",
235
- required: true
236
- },
237
- {
238
- key: "store_code",
239
- label: "SiTef store code",
240
- type: "text",
241
- required: true
242
- },
243
- {
244
- key: "terminal_number",
245
- label: "SiTef terminal number",
246
- type: "text",
247
- required: true
248
- },
249
- {
250
- key: "cnpj_store",
251
- label: "Store CNPJ",
252
- type: "text",
253
- required: true
254
- },
255
- {
256
- key: "pinpad_type",
257
- label: "Pinpad connection",
258
- type: "select",
259
- required: true,
260
- options: [...CLISITEF_PINPAD_TYPES]
261
- }
262
- ];
234
+ /**
235
+ * Ficha §6: filled per kiosk in the device settings. SiTef IP, store code
236
+ * and store CNPJ come from the payment's store settings (`config.stores`);
237
+ * the device values only override them.
238
+ */
239
+ const clisitefPinPadDeviceFields = [{
240
+ key: "terminal_number",
241
+ label: "SiTef terminal number",
242
+ type: "text",
243
+ required: true
244
+ }, {
245
+ key: "pinpad_type",
246
+ label: "Pinpad connection",
247
+ type: "select",
248
+ options: [...CLISITEF_PINPAD_TYPES]
249
+ }];
250
+ /** The API only sends the entry of the kiosk's store. */
251
+ const storeSettingsOf = (config) => {
252
+ const stores = config.stores;
253
+ if (!stores || typeof stores !== "object") return {};
254
+ const [first] = Object.values(stores);
255
+ return first && typeof first === "object" ? first : {};
256
+ };
263
257
  const text = (value) => {
264
258
  return typeof value === "string" ? value.trim() : "";
265
259
  };
@@ -269,17 +263,33 @@ const notConfigured = (missing) => {
269
263
  const isModality = (value) => {
270
264
  return value === "DEBIT" || value === "CREDIT" || value === "VOUCHER";
271
265
  };
266
+ /** `modalities`, or the legacy single `modality` of older configs. */
267
+ const listModalities = (config) => {
268
+ const listed = Array.isArray(config.modalities) ? config.modalities : [];
269
+ return (listed.length ? listed : [config.modality]).map(text).filter(Boolean);
270
+ };
271
+ /** Per modality; the legacy `restrictions` applies to all of them. */
272
+ const readRestrictions = (config, modalities) => {
273
+ const raw = config.restrictions_by_modality;
274
+ const byModality = raw && typeof raw === "object" ? raw : {};
275
+ const legacy = text(config.restrictions);
276
+ const entries = modalities.map((modality) => {
277
+ return [modality, text(byModality[modality]) || legacy];
278
+ });
279
+ return Object.fromEntries(entries.filter(([, value]) => value));
280
+ };
272
281
  /** `payments.config` (merchant) + device settings; throws when incomplete. */
273
282
  const readClisitefPinPadSettings = (config, device) => {
274
- const modality = text(config.modality);
283
+ const listed = listModalities(config);
275
284
  const cnpjEnterprise = text(config.cnpj_enterprise);
276
- const serverIp = text(device.sitef_ip);
277
- const storeCode = text(device.store_code);
285
+ const store = storeSettingsOf(config);
286
+ const serverIp = text(device.sitef_ip) || text(store.sitef_ip);
287
+ const storeCode = text(device.store_code) || text(store.store_code);
278
288
  const terminalNumber = text(device.terminal_number);
279
- const cnpjStore = text(device.cnpj_store).replace(/\D/g, "");
289
+ const cnpjStore = (text(device.cnpj_store) || text(store.cnpj_store)).replace(/\D/g, "");
280
290
  const pinpadType = text(device.pinpad_type) || void 0;
281
291
  const required = {
282
- modality,
292
+ modalities: listed.join(","),
283
293
  cnpj_enterprise: cnpjEnterprise
284
294
  };
285
295
  const fromDevice = {
@@ -296,22 +306,30 @@ const readClisitefPinPadSettings = (config, device) => {
296
306
  };
297
307
  Object.assign(values, more);
298
308
  const missing = Object.keys(values).filter((key) => !values[key]);
309
+ clisitefDebug("pinpad.settings", "read", {
310
+ config,
311
+ device,
312
+ missing
313
+ });
299
314
  if (missing.length) throw notConfigured(missing);
300
- if (!isModality(modality)) throw notConfigured(["a valid modality"]);
315
+ if (!listed.every(isModality)) throw notConfigured(["a valid modality"]);
316
+ const configure = {
317
+ serverIp,
318
+ storeCode,
319
+ terminalNumber,
320
+ additionalParams: clisitefAdditionalParams({
321
+ cnpjStore,
322
+ cnpjEnterprise,
323
+ pinpadType
324
+ })
325
+ };
326
+ const operator = text(config.operator) || "KIOSKO_BR";
327
+ const unique = [...new Set(listed)];
301
328
  return {
302
- configure: {
303
- serverIp,
304
- storeCode,
305
- terminalNumber,
306
- additionalParams: clisitefAdditionalParams({
307
- cnpjStore,
308
- cnpjEnterprise,
309
- pinpadType
310
- })
311
- },
312
- modality,
313
- operator: text(config.operator) || "KIOSKO_BR",
314
- restrictions: text(config.restrictions),
329
+ configure,
330
+ modalities: unique,
331
+ operator,
332
+ restrictions: readRestrictions(config, unique),
315
333
  terminalNumber
316
334
  };
317
335
  };
@@ -324,6 +342,7 @@ const isRecord = (value) => {
324
342
  };
325
343
  const readTransaction = async (storage) => {
326
344
  const raw = await storage.get(CLISITEF_STORAGE_KEY);
345
+ clisitefDebug("pinpad.store", "read", { raw });
327
346
  if (!raw) return null;
328
347
  try {
329
348
  const parsed = JSON.parse(raw);
@@ -333,6 +352,7 @@ const readTransaction = async (storage) => {
333
352
  }
334
353
  };
335
354
  const writeTransaction = async (storage, record) => {
355
+ clisitefDebug("pinpad.store", `write ${record.state}`, record);
336
356
  await storage.set(CLISITEF_STORAGE_KEY, JSON.stringify(record));
337
357
  };
338
358
  const isOpen = (record) => {
@@ -391,7 +411,23 @@ const runClisitefTransaction = (input) => {
391
411
  let queue = Promise.resolve();
392
412
  let resolve = () => void 0;
393
413
  const done = new Promise((r) => resolve = r);
414
+ const log = (event, data) => {
415
+ const flags = {
416
+ captured,
417
+ approved,
418
+ closing,
419
+ aborted
420
+ };
421
+ clisitefDebug("pinpad.transaction", event, {
422
+ ...data && typeof data === "object" ? data : { value: data },
423
+ flags
424
+ });
425
+ };
394
426
  const settle = (status, reason) => {
427
+ log(`settle ${status}`, {
428
+ ...reason,
429
+ fields: Object.fromEntries(fields)
430
+ });
395
431
  clearTimeout(watchdog);
396
432
  for (const subscription of subscriptions) subscription.remove();
397
433
  signal.removeEventListener("abort", onAbort);
@@ -403,6 +439,7 @@ const runClisitefTransaction = (input) => {
403
439
  });
404
440
  };
405
441
  const undo = async (reason) => {
442
+ log("undo (finishTransaction 0)", reason);
406
443
  try {
407
444
  const p1 = {
408
445
  confirm: CLISITEF_CONFIRM.UNDO,
@@ -418,6 +455,7 @@ const runClisitefTransaction = (input) => {
418
455
  }
419
456
  };
420
457
  const close = async (reason) => {
458
+ log("close", reason);
421
459
  if (closing) return;
422
460
  closing = true;
423
461
  if (!approved) await client.abortTransaction(CLISITEF_ABORT_FLAG).catch(() => 0);
@@ -425,6 +463,7 @@ const runClisitefTransaction = (input) => {
425
463
  settle("declined", reason);
426
464
  };
427
465
  function onAbort() {
466
+ log("signal aborted (payment deadline)");
428
467
  aborted = true;
429
468
  close({
430
469
  code: null,
@@ -432,10 +471,18 @@ const runClisitefTransaction = (input) => {
432
471
  });
433
472
  }
434
473
  const reply = async (data) => {
474
+ log("reply", {
475
+ data,
476
+ skipped: closing
477
+ });
435
478
  if (closing) return;
436
479
  await client.continueTransaction(data);
437
480
  };
438
481
  const onData = async (event) => {
482
+ log("onData", {
483
+ ...event,
484
+ title
485
+ });
439
486
  const { command, input: text } = event;
440
487
  if (command === CLISITEF_COMMAND.STORE_FIELD) {
441
488
  fields.set(event.fieldId, text);
@@ -459,16 +506,24 @@ const runClisitefTransaction = (input) => {
459
506
  }
460
507
  if (SILENT.has(command)) return reply("");
461
508
  if (command === CLISITEF_COMMAND.CONFIRM) {
509
+ log("ui.confirm → in", { text: text.trim() || title });
462
510
  const yes = await ui.confirm({ text: text.trim() || title });
511
+ log("ui.confirm ← out", { yes });
463
512
  return reply(yes ? "0" : "1");
464
513
  }
465
514
  if (command === CLISITEF_COMMAND.MENU) {
466
515
  const options = parseClisitefMenu(text);
467
516
  const label = title || "Selecione uma opção";
468
- return reply(await ui.select({
517
+ log("ui.select → in", {
469
518
  title: label,
470
519
  options
471
- }));
520
+ });
521
+ const picked = await ui.select({
522
+ title: label,
523
+ options
524
+ });
525
+ log("ui.select ← out", { picked });
526
+ return reply(picked);
472
527
  }
473
528
  if (READS.has(command)) {
474
529
  const label = text.trim() || title || "Informe o dado";
@@ -478,7 +533,10 @@ const runClisitefTransaction = (input) => {
478
533
  type: inputType(command),
479
534
  maxLength: max
480
535
  };
481
- return reply(await ui.input(p1));
536
+ log("ui.input → in", p1);
537
+ const value = await ui.input(p1);
538
+ log("ui.input ← out", { value });
539
+ return reply(value);
482
540
  }
483
541
  const message = `Unsupported CliSiTef command ${command}`;
484
542
  return close({
@@ -489,6 +547,7 @@ const runClisitefTransaction = (input) => {
489
547
  const confirm = () => {
490
548
  const message = "CliSiTef did not close the confirmation";
491
549
  const expire = () => {
550
+ log("confirmation watchdog expired", { skipped: closing });
492
551
  if (closing) return;
493
552
  closing = true;
494
553
  undo({
@@ -501,6 +560,10 @@ const runClisitefTransaction = (input) => {
501
560
  confirm: CLISITEF_CONFIRM.CONFIRM,
502
561
  ...input.finish
503
562
  };
563
+ log("confirm (finishTransaction 1)", {
564
+ ...p1,
565
+ watchdogMs: input.confirmationTimeoutMs
566
+ });
504
567
  client.finishTransaction(p1).catch((error) => {
505
568
  if (closing) return;
506
569
  closing = true;
@@ -513,6 +576,11 @@ const runClisitefTransaction = (input) => {
513
576
  };
514
577
  const onResult = async (event) => {
515
578
  const { stage, resultCode: code } = event;
579
+ log("onTransactionResult", {
580
+ stage,
581
+ code,
582
+ skipped: closing
583
+ });
516
584
  if (closing) return;
517
585
  if (stage === 1 && code === CLISITEF_RESULT.OK) {
518
586
  approved = true;
@@ -552,6 +620,10 @@ const runClisitefTransaction = (input) => {
552
620
  code: errorCode(error),
553
621
  message: errorMessage(error)
554
622
  };
623
+ log("handler threw", {
624
+ ...reason,
625
+ error
626
+ });
555
627
  if (closing) return;
556
628
  await close({
557
629
  ...reason,
@@ -560,6 +632,10 @@ const runClisitefTransaction = (input) => {
560
632
  });
561
633
  };
562
634
  const begin = async () => {
635
+ log("begin", {
636
+ start: input.start,
637
+ finish: input.finish
638
+ });
563
639
  if (signal.aborted) {
564
640
  aborted = true;
565
641
  return settle("declined", {
@@ -665,6 +741,36 @@ const outcomeError = (outcome, attempt) => {
665
741
  fallback
666
742
  });
667
743
  };
744
+ const MODALITY_LABELS = {
745
+ DEBIT: "Débito",
746
+ CREDIT: "Crédito",
747
+ VOUCHER: "Voucher"
748
+ };
749
+ /** The only modality, or the one the customer picks. */
750
+ const chooseModality = async (ui, modalities) => {
751
+ const [first] = modalities;
752
+ if (modalities.length === 1 && first) return first;
753
+ const options = modalities.map((value) => {
754
+ return {
755
+ label: MODALITY_LABELS[value],
756
+ value
757
+ };
758
+ });
759
+ return ui.select({
760
+ title: "Selecione a forma de pagamento",
761
+ options
762
+ });
763
+ };
764
+ const debugContext = (ctx) => {
765
+ const { attemptReference, attempt, amount, config, deviceSettings } = ctx;
766
+ return {
767
+ attemptReference,
768
+ attempt,
769
+ amount,
770
+ config,
771
+ deviceSettings
772
+ };
773
+ };
668
774
  const terminalError = (error) => {
669
775
  const message = error instanceof Error ? error.message : String(error);
670
776
  return {
@@ -674,21 +780,27 @@ const terminalError = (error) => {
674
780
  };
675
781
  };
676
782
  /**
677
- * CliSiTef (Software Express) on the kiosk pinpad, Brazil. One adapter per
678
- * modality payment (DEBIT / CREDIT / VOUCHER in `payments.config`). The
679
- * pinpad waits on the customer: give the payment a `runtime.timeout_ms`
680
- * well above the 30 s default (e.g. 90 000).
783
+ * CliSiTef (Software Express) on the kiosk pinpad, Brazil. The payment lists
784
+ * its `modalities` (DEBIT / CREDIT / VOUCHER); with more than one the
785
+ * customer picks it before the pinpad starts. The pinpad waits on the
786
+ * customer, so the deadline is `timeoutMs` instead of the 30 s library
787
+ * default.
681
788
  */
682
789
  const clisitefPinPadPayments = (options = {}) => {
683
790
  const client = options.client ?? clisitef;
684
791
  const now = options.now ?? (() => /* @__PURE__ */ new Date());
685
792
  const confirmationMs = options.confirmationTimeoutMs ?? 6e4;
793
+ const timeoutMs = options.timeoutMs ?? 18e4;
686
794
  const lock = createLock();
687
795
  const storageOf = (ctx) => {
688
796
  return options.storage ?? ctx.storage;
689
797
  };
690
798
  const configure = async (settings) => {
691
799
  const code = await client.configure(settings.configure);
800
+ clisitefDebug("pinpad.adapter.configure", "result", {
801
+ code,
802
+ settings
803
+ });
692
804
  if (code === 0) return null;
693
805
  client.invalidate();
694
806
  return toPaymentError(clisitefPinPadErrors, {
@@ -701,6 +813,10 @@ const clisitefPinPadPayments = (options = {}) => {
701
813
  const { fiscalCoupon, fiscalDate, time } = record;
702
814
  const count = client.getQttPendingTransactions;
703
815
  const pending = await count(fiscalDate, fiscalCoupon).catch(() => null);
816
+ clisitefDebug("pinpad.adapter.recover", "pending", {
817
+ pending,
818
+ record
819
+ });
704
820
  if (pending === null) return record;
705
821
  let next;
706
822
  if (pending > 0) {
@@ -740,6 +856,7 @@ const clisitefPinPadPayments = (options = {}) => {
740
856
  error
741
857
  };
742
858
  }
859
+ clisitefDebug("pinpad.adapter.recover", `→ ${next.state}`, next);
743
860
  await writeTransaction(storage, next);
744
861
  return next;
745
862
  };
@@ -750,6 +867,10 @@ const clisitefPinPadPayments = (options = {}) => {
750
867
  const storage = storageOf(ctx);
751
868
  let record = await readTransaction(storage);
752
869
  if (!error && record && isOpen(record)) record = await recover(storage, record);
870
+ clisitefDebug("pinpad.adapter.prepare", "done", {
871
+ error,
872
+ record
873
+ });
753
874
  return {
754
875
  settings,
755
876
  error,
@@ -787,6 +908,7 @@ const clisitefPinPadPayments = (options = {}) => {
787
908
  const error = createPaymentError("TERMINAL_BUSY", { attempt: ctx.attempt });
788
909
  return failed(empty, reference, error);
789
910
  }
911
+ const chosen = await chooseModality(ctx.ui, settings.modalities);
790
912
  const date = now();
791
913
  const fiscal = clisitefFiscalDateTime(date, options.timeZone);
792
914
  const fiscalCoupon = String(date.getTime());
@@ -803,18 +925,18 @@ const clisitefPinPadPayments = (options = {}) => {
803
925
  };
804
926
  await writeTransaction(storage, record);
805
927
  const s1 = {
806
- modality: CLISITEF_MODALITY[settings.modality],
928
+ modality: CLISITEF_MODALITY[chosen],
807
929
  value: formatClisitefAmount(amount),
808
930
  ...finish
809
931
  };
810
- const s2 = { operator: settings.operator };
932
+ const restrictions = settings.restrictions[chosen] ?? "";
811
933
  const start = {
812
934
  ...s1,
813
- ...s2,
814
- restrictions: settings.restrictions
935
+ operator: settings.operator,
936
+ restrictions
815
937
  };
816
938
  const meta = {
817
- modality: settings.modality,
939
+ modality: chosen,
818
940
  fiscalCoupon
819
941
  };
820
942
  const m1 = {
@@ -855,6 +977,11 @@ const clisitefPinPadPayments = (options = {}) => {
855
977
  ...t1,
856
978
  ...t2
857
979
  });
980
+ const fields = Object.fromEntries(outcome.fields);
981
+ clisitefDebug("pinpad.adapter.charge", "outcome", {
982
+ ...outcome,
983
+ fields
984
+ });
858
985
  const metadata = metadataOf(outcome.fields);
859
986
  if (outcome.status === "confirmed") {
860
987
  const details = clisitefDetails(metadata);
@@ -916,8 +1043,14 @@ const clisitefPinPadPayments = (options = {}) => {
916
1043
  error: void 0
917
1044
  };
918
1045
  };
919
- const operation = (run) => {
1046
+ const operation = (run, name = "terminal") => {
920
1047
  return (ctx) => {
1048
+ const scope = `pinpad.terminal.${name}`;
1049
+ const input = {
1050
+ config: ctx.config,
1051
+ deviceSettings: ctx.deviceSettings
1052
+ };
1053
+ const traced = () => clisitefDebugCall(scope, input, task);
921
1054
  const task = async () => {
922
1055
  try {
923
1056
  const data = await run(ctx);
@@ -930,7 +1063,7 @@ const clisitefPinPadPayments = (options = {}) => {
930
1063
  return terminalError(error);
931
1064
  }
932
1065
  };
933
- return lock(task);
1066
+ return lock(traced);
934
1067
  };
935
1068
  };
936
1069
  const terminal = {
@@ -940,15 +1073,17 @@ const clisitefPinPadPayments = (options = {}) => {
940
1073
  const error = await configure(s1);
941
1074
  if (error) throw new Error(error.message);
942
1075
  return "CliSiTef configured";
943
- }),
944
- test: operation(async () => `CliSiTef ${await client.getVersion()}`),
945
- status: operation(async () => client.getHealth() ?? {}),
1076
+ }, "init"),
1077
+ test: operation(async () => {
1078
+ return `CliSiTef ${await client.getVersion()}`;
1079
+ }, "test"),
1080
+ status: operation(async () => client.getHealth() ?? {}, "status"),
946
1081
  extra: [{
947
1082
  key: "submit_pending_messages",
948
1083
  label: "Send pending messages",
949
1084
  run: operation(async () => {
950
1085
  return `Pending messages sent (${await client.submitPendingMessages()})`;
951
- })
1086
+ }, "submit_pending_messages")
952
1087
  }, {
953
1088
  key: "release_pinpad",
954
1089
  label: "Release pinpad",
@@ -957,7 +1092,7 @@ const clisitefPinPadPayments = (options = {}) => {
957
1092
  await client.disconnectSitef();
958
1093
  client.invalidate();
959
1094
  return "Pinpad released";
960
- })
1095
+ }, "release_pinpad")
961
1096
  }]
962
1097
  };
963
1098
  return {
@@ -966,12 +1101,31 @@ const clisitefPinPadPayments = (options = {}) => {
966
1101
  deviceFields: clisitefPinPadDeviceFields,
967
1102
  errors: clisitefPinPadErrors,
968
1103
  capabilities: clisitefPinPadCapabilities,
969
- start: (ctx) => lock(() => charge(ctx)),
970
- query: (ctx, result) => lock(() => query(ctx, result)),
971
- cancel: (ctx, result) => lock(() => cancel(ctx, result)),
1104
+ policy: { timeout_ms: timeoutMs },
1105
+ start: (ctx) => {
1106
+ const run = () => charge(ctx);
1107
+ const traced = () => clisitefDebugCall("pinpad.start", debugContext(ctx), run);
1108
+ return lock(traced);
1109
+ },
1110
+ query: (ctx, result) => {
1111
+ const input = {
1112
+ ctx: debugContext(ctx),
1113
+ result
1114
+ };
1115
+ const run = () => query(ctx, result);
1116
+ return lock(() => clisitefDebugCall("pinpad.query", input, run));
1117
+ },
1118
+ cancel: (ctx, result) => {
1119
+ const input = {
1120
+ ctx: debugContext(ctx),
1121
+ result
1122
+ };
1123
+ const run = () => cancel(ctx, result);
1124
+ return lock(() => clisitefDebugCall("pinpad.cancel", input, run));
1125
+ },
972
1126
  reversalFor: (result) => result.status === "PAID" ? "manual" : "cancel",
973
1127
  terminal
974
1128
  };
975
1129
  };
976
1130
  //#endregion
977
- export { CLISITEF_CANCEL_CODES, CLISITEF_CAPTURE_FIELDS, CLISITEF_COMMAND, CLISITEF_CONFIRMATION_TIMEOUT_MS, CLISITEF_DEFAULT_OPERATOR, CLISITEF_FIELD, CLISITEF_INCONCLUSIVE_CODES, CLISITEF_NO, CLISITEF_PINPAD_TYPES, CLISITEF_STORAGE_KEY, CLISITEF_YES, clisitefDetails, clisitefLast4, clisitefMetadata, clisitefPinPadCapabilities, clisitefPinPadDeviceFields, clisitefPinPadErrors, clisitefPinPadPayments, isOpen, readClisitefPinPadSettings, readTransaction, runClisitefTransaction, writeTransaction };
1131
+ export { CLISITEF_CANCEL_CODES, CLISITEF_CAPTURE_FIELDS, CLISITEF_COMMAND, CLISITEF_CONFIRMATION_TIMEOUT_MS, CLISITEF_DEFAULT_OPERATOR, CLISITEF_FIELD, CLISITEF_INCONCLUSIVE_CODES, CLISITEF_NO, CLISITEF_PAYMENT_TIMEOUT_MS, CLISITEF_PINPAD_TYPES, CLISITEF_STORAGE_KEY, CLISITEF_YES, clisitefDetails, clisitefLast4, clisitefMetadata, clisitefPinPadCapabilities, clisitefPinPadDeviceFields, clisitefPinPadErrors, clisitefPinPadPayments, isOpen, readClisitefPinPadSettings, readTransaction, runClisitefTransaction, writeTransaction };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fire-spark/payments-clisitef-pinpad-rn",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Fire Spark CliSiTef (Software Express) pinpad adapter for Brazil: debit, credit and voucher on Android kiosks",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -17,9 +17,9 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "@fire-spark/payments": "^0.7.0",
21
- "@fire-spark/payments-clisitef-client": "^0.7.0",
22
- "@fire-spark/types": "^0.7.0"
20
+ "@fire-spark/payments": "^0.7.2",
21
+ "@fire-spark/payments-clisitef-client": "^0.7.2",
22
+ "@fire-spark/types": "^0.7.2"
23
23
  },
24
24
  "devDependencies": {
25
25
  "tsdown": "^0.22.14",