Nylon PayNylon Pay

Smart Tags

Attach business labels to transactions and filter or aggregate them by any dimension

Smart tags let you attach labels to transactions at creation time, then filter your payments by campaign, product, team, channel, or any dimension you define. Query results stay scoped to your account with no extra setup required.

Setup

import { createNylonPay } from '@nile-squad/nylonpay-ts'

const nylonpay = createNylonPay({
  apiKey: 'npk_test_your_key',
  apiSecret: 'nps_test_your_secret',
})

Attaching Tags

Pass tags to any payment-creation method:

// Collection
await nylonpay.collectPayment({
  amount: 25000,
  currency: "UGX",
  customer: { name: "Jane", phoneNumber: "+256700000000" },
  description: "Q2 promo order",
  tags: ["campaign-q2", "product:pro", "channel:web"],
})

// Payout
await nylonpay.makePayout({
  amount: 50000,
  currency: "UGX",
  customer: { name: "Jane", phoneNumber: "+256700000000" },
  destination: { accountHolderName: "Jane Doe", accountNumber: "123456" },
  description: "Partner payout",
  tags: ["partner:acme", "batch:jun-2026"],
})

// Invoice
await nylonpay.createInvoice({
  amount: 10000,
  currency: "UGX",
  description: "Monthly subscription",
  tags: ["subscription", "plan:starter"],
})

Tags appear on the transaction record. You can attach up to 10 tags per transaction.

Tag Format

Tags are normalized when attached:

RuleExample
Lowercased"VIP" becomes "vip"
Whitespace trimmed" web " becomes "web"
Max 50 characters per taglonger tags are dropped
Max 10 tags per transactionextras are dropped; first 10 are kept
Allowed characters: letters a–z, digits 0–9, - _ : .tags with other characters are dropped
Deduplicated["vip", "VIP"] becomes ["vip"]

Reserved Tags

"live" and "test" mark the transaction's mode and are set automatically. Passing either in tags has no effect.

Filtering Transactions

listTransactions

// All "vip" transactions in the last 30 days
const result = await nylonpay.listTransactions({
  tags: ["vip"],
  createdAfter: new Date(Date.now() - 30 * 24 * 3600 * 1000).toISOString(),
})

if (result.isOk) {
  const { transactions, count } = result.value
  const totalRevenue = transactions.reduce((s, t) => s + t.amount, 0)
}

Passing multiple tags returns only transactions carrying all of them. tags: ["vip", "campaign-q2"] matches transactions with both labels, not either.

getTransactionsByTag

A shorthand for filtering by a single tag:

const result = await nylonpay.getTransactionsByTag("campaign-q2", {
  status: "successful",
  limit: 50,
})

Equivalent to listTransactions({ tags: ["campaign-q2"], status: "successful", limit: 50 }).

Parameters

ParameterTypeDefaultDescription
tagsstring[]noneReturns transactions carrying all listed tags
statusstringnonepending, successful, failed, processing, cancelled
typestringnonecollection, payout, invoice
limitnumber20Results per page (1–100)
offsetnumber0Zero-based pagination offset
createdAfterstringnoneISO 8601 datetime — earliest creation time
createdBeforestringnoneISO 8601 datetime — latest creation time

Dashboard Filter

The transaction history page shows a Tags dropdown when your account has tagged transactions. Selecting a tag shows only matching transactions. The filter works alongside the existing status, type, and source filters.

Common Patterns

Per-campaign revenue

const campaigns = ["campaign-q1", "campaign-q2", "campaign-q3"]

const revenues = await Promise.all(
  campaigns.map(async (tag) => {
    const result = await nylonpay.getTransactionsByTag(tag, {
      status: "successful",
    })
    if (!result.isOk) return { tag, total: 0 }
    return {
      tag,
      total: result.value.transactions.reduce((s, t) => s + t.amount, 0),
    }
  })
)

Paginating a large set

async function* allByTag(tag: string) {
  const PAGE = 100
  let offset = 0
  while (true) {
    const result = await nylonpay.getTransactionsByTag(tag, {
      limit: PAGE,
      offset,
    })
    if (!result.isOk || result.value.transactions.length === 0) break
    yield* result.value.transactions
    if (result.value.count < PAGE) break
    offset += PAGE
  }
}

for await (const tx of allByTag("partner:acme")) {
  console.log(tx.id, tx.amount)
}

Multi-dimensional labeling

A single transaction can carry labels from multiple dimensions at once:

tags: [
  "channel:mobile-app",
  "product:premium",
  "region:east-africa",
  "cohort:2026-q2",
]

Filter by any one dimension or combine labels to narrow results further.

On this page