@p2pdotme/sdk 1.2.16 → 1.2.17
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/country.cjs +390 -39
- package/dist/country.cjs.map +1 -1
- package/dist/country.d.cts +130 -27
- package/dist/country.d.ts +130 -27
- package/dist/country.mjs +372 -39
- package/dist/country.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/qr-parsers.cjs +121 -8
- package/dist/qr-parsers.cjs.map +1 -1
- package/dist/qr-parsers.d.cts +8 -1
- package/dist/qr-parsers.d.ts +8 -1
- package/dist/qr-parsers.mjs +120 -8
- package/dist/qr-parsers.mjs.map +1 -1
- package/package.json +1 -1
package/dist/qr-parsers.mjs
CHANGED
|
@@ -253,7 +253,105 @@ var NGN_COUNTRY_OPTION = {
|
|
|
253
253
|
disabledPaymentTypes: []
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
+
// src/country/types.ts
|
|
257
|
+
var PACKED_PAYMENT_ID_SEP = "||";
|
|
258
|
+
|
|
259
|
+
// src/country/qr-validator.ts
|
|
260
|
+
function crc16ccitt(s) {
|
|
261
|
+
let crc = 65535;
|
|
262
|
+
for (let i = 0; i < s.length; i++) {
|
|
263
|
+
crc ^= s.charCodeAt(i) << 8;
|
|
264
|
+
for (let j = 0; j < 8; j++) {
|
|
265
|
+
crc = crc & 32768 ? crc << 1 ^ 4129 : crc << 1;
|
|
266
|
+
crc &= 65535;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return crc.toString(16).toUpperCase().padStart(4, "0");
|
|
270
|
+
}
|
|
271
|
+
function validatePeruvianQr(payload) {
|
|
272
|
+
if (!payload || payload.trim().length === 0) return false;
|
|
273
|
+
const data = payload.trim();
|
|
274
|
+
const tags = {};
|
|
275
|
+
let pos = 0;
|
|
276
|
+
while (pos + 4 <= data.length) {
|
|
277
|
+
const tag = data.substring(pos, pos + 2);
|
|
278
|
+
const lengthStr = data.substring(pos + 2, pos + 4);
|
|
279
|
+
if (!/^[0-9]{2}$/.test(tag) || !/^[0-9]{2}$/.test(lengthStr)) break;
|
|
280
|
+
const length = Number.parseInt(lengthStr, 10);
|
|
281
|
+
if (pos + 4 + length > data.length) break;
|
|
282
|
+
tags[tag] = data.substring(pos + 4, pos + 4 + length);
|
|
283
|
+
pos += 4 + length;
|
|
284
|
+
}
|
|
285
|
+
if (tags["58"] !== "PE") return false;
|
|
286
|
+
if (tags["53"] !== "604") return false;
|
|
287
|
+
const crcTag = tags["63"];
|
|
288
|
+
if (!crcTag) return false;
|
|
289
|
+
const marker = data.lastIndexOf("6304");
|
|
290
|
+
if (marker === -1) return false;
|
|
291
|
+
const expected = crc16ccitt(data.substring(0, marker + 4));
|
|
292
|
+
return expected.toUpperCase() === crcTag.toUpperCase();
|
|
293
|
+
}
|
|
294
|
+
function validateVenezuelanQr(payload) {
|
|
295
|
+
if (!payload || typeof payload !== "string") return false;
|
|
296
|
+
const trimmed = payload.trim();
|
|
297
|
+
if (trimmed.includes(PACKED_PAYMENT_ID_SEP)) return false;
|
|
298
|
+
const qIdx = trimmed.indexOf("?");
|
|
299
|
+
if (qIdx < 40) return false;
|
|
300
|
+
const blob = trimmed.substring(0, qIdx);
|
|
301
|
+
if (!/^[A-Za-z0-9+/=]+$/.test(blob)) return false;
|
|
302
|
+
return /(?:^|[?&])merchantId=\d{3,4}(?:&|$)/.test(trimmed.substring(qIdx));
|
|
303
|
+
}
|
|
304
|
+
|
|
256
305
|
// src/country/currencies/pen.ts
|
|
306
|
+
function validatePeruvianPhone(value) {
|
|
307
|
+
if (!value || value.trim().length === 0) return false;
|
|
308
|
+
const phone = value.trim().replace(/\s+/g, "").replace(/^\+?51/, "");
|
|
309
|
+
return /^9\d{8}$/.test(phone);
|
|
310
|
+
}
|
|
311
|
+
function normalizePeruvianPaymentKey(value) {
|
|
312
|
+
const trimmed = value.trim();
|
|
313
|
+
const cci = trimmed.replace(/\s+/g, "");
|
|
314
|
+
if (/^\d{20}$/.test(cci)) return cci;
|
|
315
|
+
const phone = trimmed.replace(/\s+/g, "").replace(/^\+?51/, "");
|
|
316
|
+
if (/^9\d{8}$/.test(phone)) return phone;
|
|
317
|
+
return cci;
|
|
318
|
+
}
|
|
319
|
+
function looksLikeTlv(value) {
|
|
320
|
+
if (value.length < 5 || !/^\d{4}/.test(value)) return false;
|
|
321
|
+
const len = Number.parseInt(value.slice(2, 4), 10);
|
|
322
|
+
return !Number.isNaN(len) && len >= 0 && 4 + len <= value.length;
|
|
323
|
+
}
|
|
324
|
+
function phoneFromTlvValue(value) {
|
|
325
|
+
const trimmed = value.trim();
|
|
326
|
+
if (!trimmed) return null;
|
|
327
|
+
if (validatePeruvianPhone(trimmed)) return normalizePeruvianPaymentKey(trimmed);
|
|
328
|
+
if (/^[0-9a-f]+$/i.test(trimmed) && /[a-f]/i.test(trimmed)) return null;
|
|
329
|
+
const match = trimmed.match(/(^|[^0-9])(\+?51)?(9\d{8})(?![0-9])/);
|
|
330
|
+
if (!match) return null;
|
|
331
|
+
const candidate = `${match[2] ?? ""}${match[3]}`;
|
|
332
|
+
return validatePeruvianPhone(candidate) ? normalizePeruvianPaymentKey(candidate) : null;
|
|
333
|
+
}
|
|
334
|
+
function extractPeruvianPhoneFromQr(payload) {
|
|
335
|
+
let pos = 0;
|
|
336
|
+
while (pos + 4 <= payload.length) {
|
|
337
|
+
const tag = payload.slice(pos, pos + 2);
|
|
338
|
+
const len = Number.parseInt(payload.slice(pos + 2, pos + 4), 10);
|
|
339
|
+
if (Number.isNaN(len) || len < 0 || pos + 4 + len > payload.length) break;
|
|
340
|
+
const value = payload.slice(pos + 4, pos + 4 + len);
|
|
341
|
+
const direct = phoneFromTlvValue(value);
|
|
342
|
+
if (direct) return direct;
|
|
343
|
+
if (tag >= "02" && tag <= "51" || tag === "62" || tag === "64" || looksLikeTlv(value)) {
|
|
344
|
+
const nested = extractPeruvianPhoneFromQr(value);
|
|
345
|
+
if (nested) return nested;
|
|
346
|
+
}
|
|
347
|
+
pos += 4 + len;
|
|
348
|
+
}
|
|
349
|
+
const glued = payload.match(/\+51\s*9\d{8}/);
|
|
350
|
+
if (glued && validatePeruvianPhone(glued[0])) {
|
|
351
|
+
return normalizePeruvianPaymentKey(glued[0]);
|
|
352
|
+
}
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
257
355
|
var PEN_COUNTRY_OPTION = {
|
|
258
356
|
country: "Peru",
|
|
259
357
|
currency: CURRENCY.PEN,
|
|
@@ -272,7 +370,13 @@ var PEN_COUNTRY_OPTION = {
|
|
|
272
370
|
precision: 2,
|
|
273
371
|
isAlpha: true,
|
|
274
372
|
disabled: false,
|
|
275
|
-
disabledPaymentTypes: []
|
|
373
|
+
disabledPaymentTypes: [],
|
|
374
|
+
uploadPaymentQR: true,
|
|
375
|
+
validateQr: validatePeruvianQr,
|
|
376
|
+
hydrateFieldsFromQr: (qr) => {
|
|
377
|
+
const phone = extractPeruvianPhoneFromQr(qr);
|
|
378
|
+
return phone ? { phone } : {};
|
|
379
|
+
}
|
|
276
380
|
};
|
|
277
381
|
|
|
278
382
|
// src/country/currencies/php.ts
|
|
@@ -339,7 +443,9 @@ var VEN_COUNTRY_OPTION = {
|
|
|
339
443
|
precision: 2,
|
|
340
444
|
isAlpha: false,
|
|
341
445
|
disabled: false,
|
|
342
|
-
disabledPaymentTypes: []
|
|
446
|
+
disabledPaymentTypes: [],
|
|
447
|
+
uploadPaymentQR: true,
|
|
448
|
+
validateQr: validateVenezuelanQr
|
|
343
449
|
};
|
|
344
450
|
|
|
345
451
|
// src/country/countries.ts
|
|
@@ -900,17 +1006,22 @@ function parseQRPh(qrData, sellPrice) {
|
|
|
900
1006
|
}
|
|
901
1007
|
|
|
902
1008
|
// src/qr-parsers/parsers/ven.ts
|
|
903
|
-
function
|
|
1009
|
+
function isPagoMovilQr(qrData) {
|
|
904
1010
|
if (!qrData || typeof qrData !== "string" || qrData.trim().length === 0) {
|
|
905
|
-
return
|
|
1011
|
+
return false;
|
|
906
1012
|
}
|
|
907
1013
|
const trimmed = qrData.trim();
|
|
908
1014
|
const qIdx = trimmed.indexOf("?");
|
|
909
|
-
if (qIdx === -1)
|
|
910
|
-
return failure("INVALID_QR", "Not a valid Venezuelan QR code");
|
|
911
|
-
}
|
|
1015
|
+
if (qIdx === -1) return false;
|
|
912
1016
|
const payload = trimmed.substring(0, qIdx);
|
|
913
|
-
|
|
1017
|
+
return !!payload && /^[A-Za-z0-9+/=]+$/.test(payload);
|
|
1018
|
+
}
|
|
1019
|
+
function parsePagoMovil(qrData, _sellPrice) {
|
|
1020
|
+
if (!qrData || typeof qrData !== "string" || qrData.trim().length === 0) {
|
|
1021
|
+
return failure("INVALID_QR", "QR data is empty or invalid");
|
|
1022
|
+
}
|
|
1023
|
+
const trimmed = qrData.trim();
|
|
1024
|
+
if (!isPagoMovilQr(trimmed)) {
|
|
914
1025
|
return failure("INVALID_QR", "Not a valid Venezuelan QR code");
|
|
915
1026
|
}
|
|
916
1027
|
return success({ paymentAddress: trimmed });
|
|
@@ -951,6 +1062,7 @@ async function parseQR(params) {
|
|
|
951
1062
|
}
|
|
952
1063
|
export {
|
|
953
1064
|
QRParserError,
|
|
1065
|
+
isPagoMovilQr,
|
|
954
1066
|
parseQR
|
|
955
1067
|
};
|
|
956
1068
|
//# sourceMappingURL=qr-parsers.mjs.map
|