@nile-squad/nylonpay-ts 1.2.1 → 1.3.0

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.cts CHANGED
@@ -89,6 +89,13 @@ type CollectPaymentInput = {
89
89
  method?: PaymentMethod;
90
90
  bank?: BankDetails;
91
91
  metadata?: Record<string, string>;
92
+ /**
93
+ * Business labels to attach to the transaction. Normalized to lowercase;
94
+ * reserved tags (`"live"`, `"test"`) are managed automatically. Max 10 tags,
95
+ * each up to 50 characters. Useful for grouping payments by campaign, product,
96
+ * team, or any merchant-defined dimension.
97
+ */
98
+ tags?: string[];
92
99
  };
93
100
  /**
94
101
  * Input for initiating a payout. Use this to disburse funds to a
@@ -102,6 +109,8 @@ type MakePayoutInput = {
102
109
  description: string;
103
110
  reference?: string;
104
111
  metadata?: Record<string, string>;
112
+ /** Business labels — same normalization rules as {@link CollectPaymentInput.tags}. */
113
+ tags?: string[];
105
114
  };
106
115
  /**
107
116
  * Input for a one-shot status check. Does not start polling; returns
@@ -140,6 +149,8 @@ type CreateInvoiceInput = {
140
149
  redirectUrl?: string;
141
150
  reference?: string;
142
151
  metadata?: Record<string, string>;
152
+ /** Business labels — same normalization rules as {@link CollectPaymentInput.tags}. */
153
+ tags?: string[];
143
154
  };
144
155
  /**
145
156
  * Input for verifying a webhook signature. Operates on raw payload bytes
@@ -414,6 +425,59 @@ type EventData = {
414
425
  * data (if available), and timestamp.
415
426
  */
416
427
  type PaymentEventHandler = (data: EventData) => void;
428
+ /**
429
+ * Lightweight transaction summary returned by `listTransactions`. Carries the
430
+ * fields needed for listing and aggregation without the full provider detail
431
+ * that `getTransaction` exposes. `tags` is included so merchants can see which
432
+ * labels a row carries while paginating.
433
+ */
434
+ type TransactionSummary = {
435
+ id: string;
436
+ reference: string;
437
+ amount: number;
438
+ currency: Currency;
439
+ status: TransactionStatus;
440
+ type: TransactionType;
441
+ method: string | null;
442
+ mode: TransactionMode;
443
+ /** Smart tags on the transaction (system + developer). */
444
+ tags: string[];
445
+ createdAt: string;
446
+ updatedAt: string;
447
+ };
448
+ /**
449
+ * Input for listing and filtering transactions. All fields are optional —
450
+ * omitting filters returns the most recent transactions for the calling
451
+ * key's account and mode.
452
+ */
453
+ type ListTransactionsInput = {
454
+ /** Filter to transactions carrying ALL of these tags (AND semantics). */
455
+ tags?: string[];
456
+ status?: TransactionStatus;
457
+ type?: TransactionType;
458
+ /** Maximum number of results (1–100, default 20). */
459
+ limit?: number;
460
+ /** Zero-based offset for pagination (default 0). */
461
+ offset?: number;
462
+ /** ISO 8601 datetime — only transactions created at or after this time. */
463
+ createdAfter?: string;
464
+ /** ISO 8601 datetime — only transactions created at or before this time. */
465
+ createdBefore?: string;
466
+ };
467
+ /**
468
+ * Response from `listTransactions`. Includes the page of summaries, the count
469
+ * returned, and the effective pagination/filter parameters so callers can build
470
+ * pagination UIs without round-tripping for metadata.
471
+ */
472
+ type ListTransactionsResponse = {
473
+ transactions: TransactionSummary[];
474
+ /** Number of transactions in this page (≤ limit). */
475
+ count: number;
476
+ limit: number;
477
+ offset: number;
478
+ /** The normalized tags that were applied as filters (empty if no tag filter). */
479
+ tags: string[];
480
+ };
417
481
  /**
418
482
  * SDK instance returned by the factory. Provides all payment operations
419
483
  * and the webhook verification utility.
@@ -569,6 +633,38 @@ interface NylonPaySdk {
569
633
  * ```
570
634
  */
571
635
  createInvoice(input: CreateInvoiceInput): Promise<Result<InvoiceResponse, string>>;
636
+ /**
637
+ * List transactions for the calling key's account, with optional filtering.
638
+ * Returns lightweight summaries — use `getTransaction` for full detail.
639
+ *
640
+ * Tag filters use AND semantics: `tags: ["vip", "promo"]` returns only
641
+ * transactions tagged with BOTH labels. Tags are normalized (lowercase) before
642
+ * matching, so `"VIP"` and `"vip"` match the same rows.
643
+ *
644
+ * @example
645
+ * ```ts
646
+ * // All transactions tagged "vip" from the last week
647
+ * const result = await nylonpay.listTransactions({
648
+ * tags: ["vip"],
649
+ * createdAfter: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString(),
650
+ * });
651
+ * if (result.isOk) console.log(result.value.transactions);
652
+ * ```
653
+ */
654
+ listTransactions(input?: ListTransactionsInput): Promise<Result<ListTransactionsResponse, string>>;
655
+ /**
656
+ * Convenience wrapper around `listTransactions` that filters by a single tag.
657
+ * Equivalent to `listTransactions({ tags: [tag], ...options })`.
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * const result = await nylonpay.getTransactionsByTag("campaign-q2");
662
+ * if (result.isOk) {
663
+ * const total = result.value.transactions.reduce((s, t) => s + t.amount, 0);
664
+ * }
665
+ * ```
666
+ */
667
+ getTransactionsByTag(tag: string, options?: Omit<ListTransactionsInput, "tags">): Promise<Result<ListTransactionsResponse, string>>;
572
668
  /**
573
669
  * Verify that an incoming webhook payload was signed by Nylon Pay.
574
670
  * Operates on raw payload bytes (string or Uint8Array), not parsed JSON,
package/dist/index.d.ts CHANGED
@@ -89,6 +89,13 @@ type CollectPaymentInput = {
89
89
  method?: PaymentMethod;
90
90
  bank?: BankDetails;
91
91
  metadata?: Record<string, string>;
92
+ /**
93
+ * Business labels to attach to the transaction. Normalized to lowercase;
94
+ * reserved tags (`"live"`, `"test"`) are managed automatically. Max 10 tags,
95
+ * each up to 50 characters. Useful for grouping payments by campaign, product,
96
+ * team, or any merchant-defined dimension.
97
+ */
98
+ tags?: string[];
92
99
  };
93
100
  /**
94
101
  * Input for initiating a payout. Use this to disburse funds to a
@@ -102,6 +109,8 @@ type MakePayoutInput = {
102
109
  description: string;
103
110
  reference?: string;
104
111
  metadata?: Record<string, string>;
112
+ /** Business labels — same normalization rules as {@link CollectPaymentInput.tags}. */
113
+ tags?: string[];
105
114
  };
106
115
  /**
107
116
  * Input for a one-shot status check. Does not start polling; returns
@@ -140,6 +149,8 @@ type CreateInvoiceInput = {
140
149
  redirectUrl?: string;
141
150
  reference?: string;
142
151
  metadata?: Record<string, string>;
152
+ /** Business labels — same normalization rules as {@link CollectPaymentInput.tags}. */
153
+ tags?: string[];
143
154
  };
144
155
  /**
145
156
  * Input for verifying a webhook signature. Operates on raw payload bytes
@@ -414,6 +425,59 @@ type EventData = {
414
425
  * data (if available), and timestamp.
415
426
  */
416
427
  type PaymentEventHandler = (data: EventData) => void;
428
+ /**
429
+ * Lightweight transaction summary returned by `listTransactions`. Carries the
430
+ * fields needed for listing and aggregation without the full provider detail
431
+ * that `getTransaction` exposes. `tags` is included so merchants can see which
432
+ * labels a row carries while paginating.
433
+ */
434
+ type TransactionSummary = {
435
+ id: string;
436
+ reference: string;
437
+ amount: number;
438
+ currency: Currency;
439
+ status: TransactionStatus;
440
+ type: TransactionType;
441
+ method: string | null;
442
+ mode: TransactionMode;
443
+ /** Smart tags on the transaction (system + developer). */
444
+ tags: string[];
445
+ createdAt: string;
446
+ updatedAt: string;
447
+ };
448
+ /**
449
+ * Input for listing and filtering transactions. All fields are optional —
450
+ * omitting filters returns the most recent transactions for the calling
451
+ * key's account and mode.
452
+ */
453
+ type ListTransactionsInput = {
454
+ /** Filter to transactions carrying ALL of these tags (AND semantics). */
455
+ tags?: string[];
456
+ status?: TransactionStatus;
457
+ type?: TransactionType;
458
+ /** Maximum number of results (1–100, default 20). */
459
+ limit?: number;
460
+ /** Zero-based offset for pagination (default 0). */
461
+ offset?: number;
462
+ /** ISO 8601 datetime — only transactions created at or after this time. */
463
+ createdAfter?: string;
464
+ /** ISO 8601 datetime — only transactions created at or before this time. */
465
+ createdBefore?: string;
466
+ };
467
+ /**
468
+ * Response from `listTransactions`. Includes the page of summaries, the count
469
+ * returned, and the effective pagination/filter parameters so callers can build
470
+ * pagination UIs without round-tripping for metadata.
471
+ */
472
+ type ListTransactionsResponse = {
473
+ transactions: TransactionSummary[];
474
+ /** Number of transactions in this page (≤ limit). */
475
+ count: number;
476
+ limit: number;
477
+ offset: number;
478
+ /** The normalized tags that were applied as filters (empty if no tag filter). */
479
+ tags: string[];
480
+ };
417
481
  /**
418
482
  * SDK instance returned by the factory. Provides all payment operations
419
483
  * and the webhook verification utility.
@@ -569,6 +633,38 @@ interface NylonPaySdk {
569
633
  * ```
570
634
  */
571
635
  createInvoice(input: CreateInvoiceInput): Promise<Result<InvoiceResponse, string>>;
636
+ /**
637
+ * List transactions for the calling key's account, with optional filtering.
638
+ * Returns lightweight summaries — use `getTransaction` for full detail.
639
+ *
640
+ * Tag filters use AND semantics: `tags: ["vip", "promo"]` returns only
641
+ * transactions tagged with BOTH labels. Tags are normalized (lowercase) before
642
+ * matching, so `"VIP"` and `"vip"` match the same rows.
643
+ *
644
+ * @example
645
+ * ```ts
646
+ * // All transactions tagged "vip" from the last week
647
+ * const result = await nylonpay.listTransactions({
648
+ * tags: ["vip"],
649
+ * createdAfter: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString(),
650
+ * });
651
+ * if (result.isOk) console.log(result.value.transactions);
652
+ * ```
653
+ */
654
+ listTransactions(input?: ListTransactionsInput): Promise<Result<ListTransactionsResponse, string>>;
655
+ /**
656
+ * Convenience wrapper around `listTransactions` that filters by a single tag.
657
+ * Equivalent to `listTransactions({ tags: [tag], ...options })`.
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * const result = await nylonpay.getTransactionsByTag("campaign-q2");
662
+ * if (result.isOk) {
663
+ * const total = result.value.transactions.reduce((s, t) => s + t.amount, 0);
664
+ * }
665
+ * ```
666
+ */
667
+ getTransactionsByTag(tag: string, options?: Omit<ListTransactionsInput, "tags">): Promise<Result<ListTransactionsResponse, string>>;
572
668
  /**
573
669
  * Verify that an incoming webhook payload was signed by Nylon Pay.
574
670
  * Operates on raw payload bytes (string or Uint8Array), not parsed JSON,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createHash, createHmac, timingSafeEqual, randomBytes } from 'crypto';
1
+ import { createHash, createHmac, timingSafeEqual, randomUUID, randomBytes } from 'crypto';
2
2
  import { Ok, Err, safeTry } from 'slang-ts';
3
3
  import { type, platform, arch, release, hostname } from 'os';
4
4
 
@@ -70,6 +70,7 @@ var SDK_ACTIONS = {
70
70
  makePayoutAndResolve: "sdk-make-payout-and-resolve",
71
71
  getStatus: "sdk-get-status",
72
72
  getTransaction: "sdk-get-transaction",
73
+ listTransactions: "sdk-list-transactions",
73
74
  verifyPhone: "sdk-verify-phone",
74
75
  createInvoice: "sdk-create-invoice"
75
76
  };
@@ -698,19 +699,13 @@ function verifyWebhookSignature(input) {
698
699
  }
699
700
 
700
701
  // src/sdk.ts
701
- function generateReference() {
702
- return randomBytes(16).toString("hex").slice(0, 15);
703
- }
704
- var REFERENCE_MIN_LENGTH = 13;
705
- var REFERENCE_MAX_LENGTH = 15;
702
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
706
703
  function resolveReference(reference) {
707
704
  if (reference === void 0) {
708
- return generateReference();
705
+ return randomUUID();
709
706
  }
710
- if (reference.length < REFERENCE_MIN_LENGTH || reference.length > REFERENCE_MAX_LENGTH) {
711
- throwValidation(
712
- `reference must be ${REFERENCE_MIN_LENGTH}\u2013${REFERENCE_MAX_LENGTH} characters`
713
- );
707
+ if (!UUID_REGEX.test(reference)) {
708
+ throwValidation("reference must be a valid UUID");
714
709
  }
715
710
  return reference;
716
711
  }
@@ -977,6 +972,19 @@ function createSdkInstance(config) {
977
972
  }
978
973
  return Err(result.error);
979
974
  }
975
+ async function listTransactions(input) {
976
+ const result = await transport.send({
977
+ action: SDK_ACTIONS.listTransactions,
978
+ payload: input ?? {}
979
+ });
980
+ if (result.isOk) {
981
+ return Ok(result.value);
982
+ }
983
+ return Err(result.error);
984
+ }
985
+ async function getTransactionsByTag(tag, options) {
986
+ return listTransactions({ ...options, tags: [tag] });
987
+ }
980
988
  function verifyWebhook(input) {
981
989
  return verifyWebhookSignature(input);
982
990
  }
@@ -987,6 +995,8 @@ function createSdkInstance(config) {
987
995
  makePayoutAndResolve,
988
996
  getStatus,
989
997
  getTransaction,
998
+ listTransactions,
999
+ getTransactionsByTag,
990
1000
  verifyPhone,
991
1001
  createInvoice,
992
1002
  verifyWebhookSignature: verifyWebhook