npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@undernouzen/ay-payments-sdk

v3.2.0

Published

TypeScript SDK for AY Payments API integrations

Readme

AY Payments SDK

SDK TypeScript/JavaScript oficial para a API da AY Payments.

Docs completas: https://aypayments.undernouzen.com.br/docs/

Instalar

npm install @undernouzen/ay-payments-sdk
pnpm add @undernouzen/ay-payments-sdk

Cliente

import { createAYPaymentsClient } from "@undernouzen/ay-payments-sdk";

const ay = createAYPaymentsClient({
  baseUrl: "https://aypayments.undernouzen.com.br",
  apiKey: process.env.AYP_API_KEY,
  language: "pt-BR",
});

O endpoint publico continua sendo:

https://aypayments.undernouzen.com.br/api/v1

v3 e o contrato atual de dados da plataforma. A URL publica permanece /api/v1.

Idioma

O SDK envia x-ay-language e Accept-Language quando language e configurado.

const ay = createAYPaymentsClient({
  apiKey: "ayp_secret",
  language: "pt-BR",
});

await ay.language("en-US").products.list();
await ay.idioma("pt-BR").products.list();

await ay.checkouts.create(payload, {
  headers: { "x-ay-language": "pt-BR" },
});

Erros

Todos os erros da API retornam code estavel e error humano.

import { isApiError } from "@undernouzen/ay-payments-sdk";

const result = await ay.products.get("product_id");

if (isApiError(result)) {
  console.log(result.code, result.error);
}

Produtos v3

Produtos usam type: "single" | "variant" e sempre possuem pricing, inventory e availability.

const product = await ay.products.createGlobal({
  projectId: "project_id",
  connectedAccountId: "acct_connected",
  type: "variant",
  sku: "guild-vip",
  name: "VIP Guild",
  pricing: {
    defaultCurrency: "BRL",
    prices: [
      {
        currency: "BRL",
        value: "29.90",
        compareAtValue: "39.90",
        promotion: { enabled: true, label: "Lancamento" },
      },
      { currency: "USD", value: "7.99" },
    ],
  },
  inventory: {
    trackStock: true,
    stockQuantity: 500,
    maxQuantityPerOrder: 5,
  },
  availability: {
    availableFrom: Date.now(),
  },
  variants: [
    {
      externalId: "base",
      sku: "guild-vip-base",
      name: "Base",
      isDefault: true,
      pricing: { mode: "base", prices: [] },
      inventory: { mode: "inherit" },
      availability: { mode: "inherit" },
    },
    {
      externalId: "premium",
      sku: "guild-vip-premium",
      name: "Premium",
      pricing: {
        mode: "absolute",
        prices: [{ currency: "BRL", value: "49.90" }],
      },
      inventory: {
        mode: "override",
        trackStock: true,
        stockQuantity: 100,
      },
      availability: { mode: "inherit" },
    },
  ],
  metadata: { guildId: "832320430277918720" },
  mediaGallery: [{ type: "image", url: "https://cdn.example.com/vip.png" }],
});

Produtos salvos nao aceitam override de preco no checkout. O preco e a moeda sao resolvidos pelo produto, variante e price selecionados.

Categorias

await ay.categories.createGlobal({
  projectId: "project_id",
  name: "Discord",
  icon: "https://cdn.example.com/category.png",
  metadata: { source: "panel" },
});

Contas de provedores

name identifica a conta global reutilizavel do merchant. alias identifica o nome custom dessa conta dentro de um projeto.

await ay.accounts.updateProjects("provider-account-id", {
  projectIds: ["project_id"],
  alias: "Mercado Pago - Loja Discord",
});

await ay.projects.accounts.update("project_id", "connection_id", {
  alias: "Mercado Pago - Loja Discord",
});

O campo legado name ainda e aceito em conexoes de projeto para compatibilidade, mas novas integracoes devem usar alias.

Cupons v3

Cupons usam discount, targets, limits e availability.

await ay.coupons.create({
  projectId: "project_id",
  name: "Promocao VIP",
  code: "VIP10",
  discount: {
    type: "percentage",
    value: "10",
    maxDiscountAmount: "25.00",
  },
  targets: [
    { type: "product", id: "product_id" },
    { type: "product_category", id: "category_id" },
    { type: "subscription_plan", id: "plan_id" },
  ],
  limits: {
    minimumAmount: "20.00",
    maxRedemptions: 500,
    maxRedemptionsPerCustomer: 1,
  },
  availability: {
    availableFrom: Date.now(),
  },
});

Checkouts

Um checkout pode ter multiplos itens, inclusive do mesmo produto/variante. Todos os itens devem resolver para a mesma currency.

const checkout = await ay.checkouts.create({
  projectId: "project_id",
  provider: "stripe",
  currency: "BRL",
  commissionProfileKey: "default_sale",
  idempotencyKey: "guild-832320430277918720-order-001",
  customer: {
    email: "[email protected]",
    name: "Luis",
  },
  items: [
    {
      productId: "product_id",
      variantId: "premium",
      quantity: 2,
      metadata: { slot: "discord-role" },
    },
  ],
  couponCodes: ["VIP10"],
  metadata: {
    guildId: "832320430277918720",
  },
  webhookEndpoints: [
    {
      name: "Backend principal",
      url: "https://merchant.example.com/webhooks/aypayments",
      secret: "secret_opcional",
      events: ["order.created", "payment.paid", "refund.succeeded"],
    },
  ],
}, {
  idempotencyKey: "guild-832320430277918720-order-001",
});

Tambem e possivel usar commissionProfileId. Se nenhum profile for enviado, a API usa o default compativel quando existir; policies obrigatorias sem profile explicito/default bloqueiam o calculo.

Checkout de assinatura ainda nao esta habilitado. Planos de assinatura podem ser cadastrados, mas a criacao de checkout recorrente sera ligada em uma fase futura.

Payments, refunds e finance

await ay.payments.list({ projectId: "project_id", status: "paid" });
await ay.payments.sync("payment_id");

await ay.refunds.create({
  orderId: "order_id",
  amount: "10.00",
  reason: "customer_request",
  idempotencyKey: "refund-order-001",
});

await ay.finance.ledger.list({ projectId: "project_id" });
await ay.finance.auditLogs.list({ resourceType: "order" });
await ay.finance.providerEvents.reprocess("provider_event_id");

Refund parcial e previsto pelo contrato. Quando o provider nao suportar ou a credencial ainda nao permitir a operacao, a API retorna erro claro com code.

Webhook endpoints e deliveries

Configure destinos com webhookEndpoints. O secret nunca volta na resposta; use hasSecret.

await ay.webhookEndpoints.createForProject("project_id", {
  name: "Projeto",
  url: "https://merchant.example.com/webhooks/project",
  secret: "secret_opcional",
  events: ["payment.paid"],
});

await ay.webhookEndpoints.createForProduct("product_id", {
  name: "Produto VIP",
  url: "https://merchant.example.com/webhooks/product-vip",
  events: ["payment.paid", "refund.succeeded"],
});

const { webhookEndpoints } = await ay.webhookEndpoints.listForProject("project_id");

Webhooks enviados pela AY Payments ficam em webhooks.deliveries.

await ay.webhooks.deliveries.list({ status: "failed" });
await ay.webhooks.deliveries.get("delivery_id");
await ay.webhooks.deliveries.retry("delivery_id");
await ay.webhooks.retryMany({ ids: ["delivery_id"] });

Eventos recebidos de Stripe/Mercado Pago ficam em finance.providerEvents.

Subscription plans

Planos de assinatura estao disponiveis para cadastro e preparacao de catalogo.

await ay.subscriptionPlans.create({
  projectId: "project_id",
  slug: "premium-monthly",
  name: "Premium mensal",
  interval: "month",
  intervalCount: 1,
  prices: [{ currency: "BRL", value: "29.90" }],
  features: [
    { key: "support", label: "Suporte prioritario", included: true },
  ],
});

Raw

const response = await ay.raw<{ ok: boolean }>({
  method: "GET",
  url: "/projects",
});