@fire-spark/payments-clisitef-pinpad-rn 0.7.1 → 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
@@ -24,10 +24,11 @@ type ClisitefPinPadOptions = {
24
24
  timeoutMs?: number;
25
25
  };
26
26
  /**
27
- * CliSiTef (Software Express) on the kiosk pinpad, Brazil. One adapter per
28
- * modality payment (DEBIT / CREDIT / VOUCHER in `payments.config`). The
29
- * pinpad waits on the customer, so the deadline is `timeoutMs` instead of
30
- * the 30 s library default.
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.
31
32
  */
32
33
  declare const clisitefPinPadPayments: (options?: ClisitefPinPadOptions) => PaymentAdapter;
33
34
  //#endregion
@@ -127,14 +128,20 @@ declare const clisitefPinPadErrors: Readonly<Record<string, PaymentErrorEntry>>
127
128
  //#endregion
128
129
  //#region src/settings.d.ts
129
130
  declare const CLISITEF_PINPAD_TYPES: readonly ["ANDROID_USB", "ANDROID_BT", "ANDROID_AUTO"];
130
- /** 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
+ */
131
136
  declare const clisitefPinPadDeviceFields: DeviceField[];
132
137
  type ClisitefModality = keyof typeof CLISITEF_MODALITY;
138
+ type ClisitefCardModality = Exclude<ClisitefModality, "PIX">;
133
139
  type ClisitefPinPadSettings = {
134
140
  configure: ClisitefConfigureParams;
135
- modality: Exclude<ClisitefModality, "PIX">;
141
+ /** Asked to the customer when there is more than one. */
142
+ modalities: ClisitefCardModality[];
136
143
  operator: string;
137
- restrictions: string;
144
+ restrictions: Partial<Record<ClisitefCardModality, string>>;
138
145
  terminalNumber: string;
139
146
  };
140
147
  /** `payments.config` (merchant) + device settings; throws when incomplete. */
@@ -214,4 +221,4 @@ type ClisitefTransactionInput = {
214
221
  */
215
222
  declare const runClisitefTransaction: (input: ClisitefTransactionInput) => Promise<ClisitefOutcome>;
216
223
  //#endregion
217
- 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, 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
@@ -231,40 +231,29 @@ const CLISITEF_PINPAD_TYPES = [
231
231
  "ANDROID_BT",
232
232
  "ANDROID_AUTO"
233
233
  ];
234
- /** Ficha §6: filled per kiosk in the device settings. */
235
- const clisitefPinPadDeviceFields = [
236
- {
237
- key: "sitef_ip",
238
- label: "SiTef server IP",
239
- type: "text",
240
- required: true
241
- },
242
- {
243
- key: "store_code",
244
- label: "SiTef store code",
245
- type: "text",
246
- required: true
247
- },
248
- {
249
- key: "terminal_number",
250
- label: "SiTef terminal number",
251
- type: "text",
252
- required: true
253
- },
254
- {
255
- key: "cnpj_store",
256
- label: "Store CNPJ",
257
- type: "text",
258
- required: true
259
- },
260
- {
261
- key: "pinpad_type",
262
- label: "Pinpad connection",
263
- type: "select",
264
- required: true,
265
- options: [...CLISITEF_PINPAD_TYPES]
266
- }
267
- ];
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
+ };
268
257
  const text = (value) => {
269
258
  return typeof value === "string" ? value.trim() : "";
270
259
  };
@@ -274,17 +263,33 @@ const notConfigured = (missing) => {
274
263
  const isModality = (value) => {
275
264
  return value === "DEBIT" || value === "CREDIT" || value === "VOUCHER";
276
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
+ };
277
281
  /** `payments.config` (merchant) + device settings; throws when incomplete. */
278
282
  const readClisitefPinPadSettings = (config, device) => {
279
- const modality = text(config.modality);
283
+ const listed = listModalities(config);
280
284
  const cnpjEnterprise = text(config.cnpj_enterprise);
281
- const serverIp = text(device.sitef_ip);
282
- 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);
283
288
  const terminalNumber = text(device.terminal_number);
284
- const cnpjStore = text(device.cnpj_store).replace(/\D/g, "");
289
+ const cnpjStore = (text(device.cnpj_store) || text(store.cnpj_store)).replace(/\D/g, "");
285
290
  const pinpadType = text(device.pinpad_type) || void 0;
286
291
  const required = {
287
- modality,
292
+ modalities: listed.join(","),
288
293
  cnpj_enterprise: cnpjEnterprise
289
294
  };
290
295
  const fromDevice = {
@@ -307,21 +312,24 @@ const readClisitefPinPadSettings = (config, device) => {
307
312
  missing
308
313
  });
309
314
  if (missing.length) throw notConfigured(missing);
310
- 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)];
311
328
  return {
312
- configure: {
313
- serverIp,
314
- storeCode,
315
- terminalNumber,
316
- additionalParams: clisitefAdditionalParams({
317
- cnpjStore,
318
- cnpjEnterprise,
319
- pinpadType
320
- })
321
- },
322
- modality,
323
- operator: text(config.operator) || "KIOSKO_BR",
324
- restrictions: text(config.restrictions),
329
+ configure,
330
+ modalities: unique,
331
+ operator,
332
+ restrictions: readRestrictions(config, unique),
325
333
  terminalNumber
326
334
  };
327
335
  };
@@ -733,6 +741,26 @@ const outcomeError = (outcome, attempt) => {
733
741
  fallback
734
742
  });
735
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
+ };
736
764
  const debugContext = (ctx) => {
737
765
  const { attemptReference, attempt, amount, config, deviceSettings } = ctx;
738
766
  return {
@@ -752,10 +780,11 @@ const terminalError = (error) => {
752
780
  };
753
781
  };
754
782
  /**
755
- * CliSiTef (Software Express) on the kiosk pinpad, Brazil. One adapter per
756
- * modality payment (DEBIT / CREDIT / VOUCHER in `payments.config`). The
757
- * pinpad waits on the customer, so the deadline is `timeoutMs` instead of
758
- * the 30 s library default.
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.
759
788
  */
760
789
  const clisitefPinPadPayments = (options = {}) => {
761
790
  const client = options.client ?? clisitef;
@@ -879,6 +908,7 @@ const clisitefPinPadPayments = (options = {}) => {
879
908
  const error = createPaymentError("TERMINAL_BUSY", { attempt: ctx.attempt });
880
909
  return failed(empty, reference, error);
881
910
  }
911
+ const chosen = await chooseModality(ctx.ui, settings.modalities);
882
912
  const date = now();
883
913
  const fiscal = clisitefFiscalDateTime(date, options.timeZone);
884
914
  const fiscalCoupon = String(date.getTime());
@@ -895,18 +925,18 @@ const clisitefPinPadPayments = (options = {}) => {
895
925
  };
896
926
  await writeTransaction(storage, record);
897
927
  const s1 = {
898
- modality: CLISITEF_MODALITY[settings.modality],
928
+ modality: CLISITEF_MODALITY[chosen],
899
929
  value: formatClisitefAmount(amount),
900
930
  ...finish
901
931
  };
902
- const s2 = { operator: settings.operator };
932
+ const restrictions = settings.restrictions[chosen] ?? "";
903
933
  const start = {
904
934
  ...s1,
905
- ...s2,
906
- restrictions: settings.restrictions
935
+ operator: settings.operator,
936
+ restrictions
907
937
  };
908
938
  const meta = {
909
- modality: settings.modality,
939
+ modality: chosen,
910
940
  fiscalCoupon
911
941
  };
912
942
  const m1 = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fire-spark/payments-clisitef-pinpad-rn",
3
- "version": "0.7.1",
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.1",
21
- "@fire-spark/payments-clisitef-client": "^0.7.1",
22
- "@fire-spark/types": "^0.7.1"
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",