punch-library

Framework-agnostic payment orchestration library for Node.js with Punch CLI


Keywords
payments, payment-gateway, stripe, paypal, adyen, square, nestjs, nodejs, webhook, cli, api-getway, payment-integration, payment-library, stripe-payments
License
MIT
Install
npm install punch-library@0.1.4

Documentation

punch-library

Punch Library logo

Framework-agnostic payment orchestration library for Node.js with a punch CLI.

Documentation is powered by Docsify.

Package

  • npm: https://www.npmjs.com/package/punch-library
  • GitHub: https://github.com/oguzhan18/punch-library

Install

# npm
npm install punch-library

# yarn
yarn add punch-library

# pnpm
pnpm add punch-library

Maintainer

  • Name: Oguzhan Cart
  • Website: https://oguzhancart.dev
  • Email: oguzhancart1@gmail.com
  • LinkedIn: https://www.linkedin.com/in/o%C4%9Fuzhan-%C3%A7art-b73405199/
  • GitHub: http://github.com/oguzhan18
  • Medium: https://medium.com/@oguzhancart1
  • CodePen: https://codepen.io/oguzhan1881

Features

  • Unified payment API across providers (create/capture/cancel/refund)
  • Provider-level custom-operation API to access advanced provider endpoints beyond unified contract
  • Provider catalog with payment/webhook documentation links
  • Programmatic webhook parsing API (parseWebhook)
  • Idempotency key support (x-idempotency-key or idempotencyKey)
  • Correlation ID support (x-correlation-id) + structured HTTP logs
  • Phase-3 platform controls:
    • Provider rate limiting
    • Provider circuit breaker
    • Webhook idempotency handling
    • Webhook dead-letter queue (DLQ)
    • Outbox event store (memory or file)
  • Stripe support:
    • Payment intent creation
    • Capture, cancel, refund
    • Webhook signature verification (stripe-signature)
  • PayPal support:
    • OAuth2 token flow
    • Order create/capture + capture refund
    • Webhook signature verification (verify-webhook-signature API)
  • Adyen support:
    • Payment create/capture/cancel/refund
    • Webhook signature verification (HMAC)
  • Square support:
    • Payment create/capture/cancel/refund
    • Webhook signature verification

Supported Providers

stripe, paypal, adyen, square, braintree, checkout, worldpay, razorpay, paddle, twocheckout, iyzico, paytr, parampos, sipay, hepsipay

Current Status

Full live API + webhook support is not complete for all providers yet.

  • Implemented: stripe, paypal, adyen, square
  • Stub adapters: all other providers (visible in catalog)

Setup

npm install
npm run build

Run Docs (Docsify)

npm run docs:serve

Then open:

  • http://localhost:3004

Vercel Deployment (Docsify)

Vercel is configured to deploy Docsify static docs (not NestJS runtime) via vercel.json.

Library API

Instantiate the library:

import { Punch } from 'punch-api';

const punch = new Punch({
  exposeUnconfiguredProviders: false,
  stateStoreMode: 'memory'
});

Main methods:

  • listProviders()
  • listCatalog()
  • createIntent() / createPayment()
  • capturePayment()
  • cancelPayment()
  • refundPayment()
  • executeCustomOperation()
  • parseWebhook()
  • listOutbox() / clearOutbox()
  • listWebhookDlq() / replayWebhookDlqItem() / clearWebhookDlq()
  • resilienceSnapshot()

Example intent payload:

{
  "provider": "stripe",
  "amount": 1000,
  "currency": "TRY",
  "idempotencyKey": "pay-create-ord-42",
  "customerId": "cust_1",
  "metadata": {
    "orderId": "ORD-42"
  }
}

Example custom operation payload:

{
  "endpoint": "/payment_intents",
  "method": "POST",
  "bodyType": "form",
  "idempotencyKey": "custom-op-42",
  "body": {
    "amount": 1000,
    "currency": "usd",
    "automatic_payment_methods[enabled]": true
  }
}

Environment Variables

  • PUNCH_STRIPE_API_KEY
  • PUNCH_STRIPE_WEBHOOK_SECRET (required for Stripe webhook verification)
  • PUNCH_PAYPAL_CLIENT_ID, PUNCH_PAYPAL_CLIENT_SECRET, PUNCH_PAYPAL_WEBHOOK_ID
  • PUNCH_ADYEN_API_KEY, PUNCH_ADYEN_MERCHANT_ACCOUNT
  • PUNCH_ADYEN_HMAC_KEY (required for Adyen webhook verification)
  • PUNCH_SQUARE_API_KEY, PUNCH_SQUARE_LOCATION_ID
  • PUNCH_SQUARE_WEBHOOK_SIGNATURE_KEY, PUNCH_SQUARE_WEBHOOK_NOTIFICATION_URL
  • PUNCH_<PROVIDER>_API_KEY for other providers
  • Stub provider live mode (for braintree, checkout, worldpay, razorpay, paddle, twocheckout, iyzico, paytr, parampos, sipay, hepsipay):
    • If API key includes _mock_, mock mode is used.
    • If API key does not include _mock_, these are required:
      • PUNCH_<PROVIDER>_CREATE_ENDPOINT
      • PUNCH_<PROVIDER>_CAPTURE_ENDPOINT
      • PUNCH_<PROVIDER>_CANCEL_ENDPOINT
      • PUNCH_<PROVIDER>_REFUND_ENDPOINT
    • Optional:
      • PUNCH_<PROVIDER>_AUTH_MODE (bearer|basic|api_key)
      • PUNCH_<PROVIDER>_BASIC_USERNAME, PUNCH_<PROVIDER>_BASIC_PASSWORD
      • PUNCH_<PROVIDER>_API_KEY_HEADER
      • PUNCH_<PROVIDER>_IDEMPOTENCY_HEADER
      • PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_REQUIRED
      • PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_HEADER
      • PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_SECRET
      • PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_ALGORITHM
  • Optional base URLs for custom operation mode:
    • PUNCH_STRIPE_BASE_URL
    • PUNCH_PAYPAL_BASE_URL
    • PUNCH_ADYEN_BASE_URL
    • PUNCH_SQUARE_BASE_URL
    • PUNCH_CHECKOUT_BASE_URL
    • PUNCH_WORLDPAY_BASE_URL
    • PUNCH_RAZORPAY_BASE_URL
    • PUNCH_PADDLE_BASE_URL
    • PUNCH_IYZICO_BASE_URL
    • PUNCH_PAYTR_BASE_URL
    • PUNCH_BRAINTREE_BASE_URL
    • PUNCH_TWOCHECKOUT_BASE_URL
    • PUNCH_PARAMPOS_BASE_URL
    • PUNCH_SIPAY_BASE_URL
    • PUNCH_HEPSIPAY_BASE_URL
  • PUNCH_EXPOSE_UNCONFIGURED_PROVIDERS=true to expose unconfigured providers in API responses
  • PUNCH_RATE_LIMIT_WINDOW_MS, PUNCH_RATE_LIMIT_MAX
  • PUNCH_CIRCUIT_FAILURE_THRESHOLD, PUNCH_CIRCUIT_OPEN_MS
  • PUNCH_WEBHOOK_IDEMPOTENCY_TTL_MS
  • PUNCH_WEBHOOK_MAX_ATTEMPTS, PUNCH_WEBHOOK_RETRY_DELAY_MS
  • PUNCH_STATE_STORE_MODE (memory or file)
  • PUNCH_STATE_STORE_DIR (default .punch-state)

CLI (Direct punch ... Usage)

Link the CLI once:

npm run cli:link

Then use it directly:

punch list
punch status
punch new stripe
punch new paypal --key=live_or_sandbox_key
punch remove stripe
punch doctor
punch doctor --fix
punch template stripe

Disable CLI banner if needed:

PUNCH_NO_BANNER=true punch status

CLI commands:

  • punch new <provider>
    • Creates/updates provider API key in .env
    • Adds provider-specific extra keys for implemented providers (Stripe/PayPal/Adyen/Square)
    • Updates PUNCH_ENABLED_PROVIDERS
    • Creates/updates punch.providers.json
    • --key=... to provide a custom API key
    • --no-enable to skip enabling provider in PUNCH_ENABLED_PROVIDERS
  • punch status [--json]
    • Shows provider configuration status from .env and punch.providers.json
  • punch list [--json]
    • Lists provider, env key, and docs URL
  • punch remove <provider>
    • Removes provider key and enablement from .env
    • Removes provider from punch.providers.json
  • punch doctor [--json]
    • Validates .env and punch.providers.json consistency
    • Returns exit code 1 on critical errors
  • punch doctor --fix [--json]
    • Auto-creates missing .env
    • Backfills PUNCH_ENABLED_PROVIDERS from punch.providers.json when missing
    • Adds mock API keys for enabled providers that are missing keys
    • Synchronizes punch.providers.json with PUNCH_ENABLED_PROVIDERS
  • punch template <provider> [--print]
    • Generates provider-specific custom operation templates
    • Writes template to punch.templates/<provider>.json
    • --print returns JSON template to stdout

Unlink when needed:

npm run cli:unlink

Library Usage

import { PunchClient } from 'punch-api';

const client = new PunchClient();
const payment = await client.createPayment({
  provider: 'stripe',
  amount: 1200,
  currency: 'TRY'
});

await client.refundPayment({
  provider: 'stripe',
  paymentId: payment.id,
  amount: 1200,
  currency: 'TRY'
});

await client.executeCustomOperation({
  provider: 'stripe',
  endpoint: '/customers',
  method: 'POST',
  bodyType: 'form',
  body: {
    email: 'dev@company.com'
  }
});

import { Punch } from 'punch-api';

const punch = new Punch({ stateStoreMode: 'file' });
const providers = punch.listProviders();
console.log(providers);

Tests

  • test/provider-registry.spec.ts: configured provider filtering
  • test/stripe-webhook.spec.ts: Stripe webhook signature verification
  • test/cli.spec.ts: CLI integration checks (new/remove/doctor/template)
  • test/payment-provider-resilience.spec.ts: rate limit + circuit breaker checks
  • test/payment-webhook-idempotency.spec.ts: webhook duplicate detection
  • test/payments.service.phase3.spec.ts: outbox + DLQ behavior
  • test/provider-definition-of-done.spec.ts: per-provider Definition of Done contract checks
  • test/persistent-storage.spec.ts: file-backed outbox + DLQ persistence checks
  • test/stub-provider-standardization.spec.ts: standardized lifecycle on stub providers
  • test/payments.e2e.ts: e2e API flow checks

Quality gates:

  • GitHub Actions CI: .github/workflows/ci.yml (build + unit/integration + e2e on Node 20/22)

Release

Before publish:

npm run release:preflight

Publish to npm:

npm login
npm run publish:npm

If your account requires publish 2FA:

NPM_OTP=123456 npm run publish:npm

Publish with Yarn Berry:

yarn npm login
npm run publish:yarn

Publish with Yarn Classic:

npm run publish:yarn:classic

Documentation Files

  • Docsify app entry: docs/index.html
  • Sidebar: docs/_sidebar.md
  • Navbar: docs/_navbar.md
  • Home page: docs/README.md
  • Technical reference: docs/technical-documentation.md