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

@smarthivelabs-devs/payments-next

v1.2.0

Published

Next.js integration for SmartHive Payments — server utilities, App Router webhook handler, and React hooks

Readme

@smarthivelabs-devs/payments-next

Official Next.js SDK for SmartHive Payments — App Router route handlers, server utilities, client hooks, and webhook processing.

Installation

npm install @smarthivelabs-devs/payments-next

This automatically installs @smarthivelabs-devs/payments (Node.js core SDK) and @smarthivelabs-devs/payments-react (React hooks). You also need:

npm install next react react-dom

Environment Variables

SMARTHIVE_PAYMENTS_API_KEY=sk_test_...
SMARTHIVE_PAYMENTS_BASE_URL=https://api.smarthivepayments.com
SMARTHIVE_PAYMENTS_WEBHOOK_SECRET=whsec_...

| Variable | Required | Description | |---|---|---| | SMARTHIVE_PAYMENTS_API_KEY | Yes | Your API key (sk_test_... or sk_live_...) | | SMARTHIVE_PAYMENTS_BASE_URL | Yes | SmartHive Payments API base URL | | SMARTHIVE_PAYMENTS_WEBHOOK_SECRET | Webhooks only | Your webhook signing secret |


Quick Start

1. Create the server-side client

// lib/payments.ts
import { createSmartHiveClient } from '@smarthivelabs-devs/payments-next/server';

const apiKey = process.env.SMARTHIVE_PAYMENTS_API_KEY!;

export const payments = createSmartHiveClient({
  apiKey,
  baseUrl: process.env.SMARTHIVE_PAYMENTS_BASE_URL!,
  // Derive mode from key prefix so they always agree.
  // sk_test_... → sandbox database  |  sk_live_... → live database
  mode: apiKey.startsWith('sk_live_') ? 'live' : 'sandbox',
});

Or use the singleton version (one instance for the whole server):

import { getSmartHiveClient } from '@smarthivelabs-devs/payments-next/server';

// Creates the client on first call, reuses it after
const payments = getSmartHiveClient({
  apiKey: process.env.SMARTHIVE_PAYMENTS_API_KEY!,
  baseUrl: process.env.SMARTHIVE_PAYMENTS_BASE_URL!,
});

2. Create a checkout session route

// app/api/payments/checkout/session/route.ts
import { NextResponse } from 'next/server';
import { payments } from '@/lib/payments';

export async function POST(req: Request) {
  const { amount, currency, countryCode, customerEmail, customerName } = await req.json() as {
    amount: number;
    currency: string;
    countryCode: string;
    customerEmail?: string;
    customerName?: string;
  };

  const session = await payments.checkout.createSession({
    amount: String(amount),
    currency,
    countryCode,
    customerEmail,
    customerName,
    platform: 'web',
    returnUrl: `${process.env.NEXT_PUBLIC_APP_URL}/order/complete`,
    callbackUrl: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/payments`,
    // mode is inherited from the client's default (derived from key prefix above)
  });

  return NextResponse.json(session);
}

3. Add the verify endpoint

This route is called after payment, not after session creation. SmartHive appends ?reference=txn_xxx to your returnUrl when the customer pays — pass that txn_xxx here. Calling it with a session ID (chs_xxx) or before the customer has paid will return 404.

// app/api/payments/verify/[reference]/route.ts
import { NextResponse } from 'next/server';
import { payments } from '@/lib/payments';

export async function GET(
  _req: Request,
  { params }: { params: { reference: string } },
) {
  // params.reference must be a payment reference (txn_xxx) from:
  //   • the ?reference= query param on your returnUrl after checkout, OR
  //   • event.data.reference from a payment.success webhook
  const result = await payments.payments.verify(params.reference);
  return NextResponse.json(result);
}

4. Set up webhooks

// app/api/webhooks/payments/route.ts
import { createWebhookHandler } from '@smarthivelabs-devs/payments-next/server';

export const POST = createWebhookHandler({
  secret: process.env.SMARTHIVE_PAYMENTS_WEBHOOK_SECRET!,
  handlers: {
    'payment.success': async (event) => {
      // Fulfill the order
      await db.orders.update({
        where: { reference: event.data.reference },
        data: { status: 'paid', paidAt: new Date() },
      });
    },
    'payment.failed': async (event) => {
      await notifyCustomer(event.data.reference);
    },
    'payout.success': async (event) => {
      await db.payouts.markComplete(event.data.reference);
    },
  },
  onError: (err, req) => {
    // Optional: log webhook errors
    console.error('Webhook error:', err.message);
  },
});

5. Add React hooks to your UI

// app/checkout/page.tsx
'use client';
import { SmartHiveProvider, CheckoutButton } from '@smarthivelabs-devs/payments-next/client';

export default function CheckoutPage() {
  return (
    <SmartHiveProvider apiBaseUrl="">
      <CheckoutButton
        params={{ amount: 5000, currency: 'GHS', countryCode: 'GH' }}
        label="Pay GHS 50"
        onSuccess={(data) => console.log('Paid:', data.reference)}
      />
    </SmartHiveProvider>
  );
}

Server API Reference

createSmartHiveClient(config?)

Creates a new SmartHivePayments instance. Config is optional — omit to read from env vars.

import { createSmartHiveClient } from '@smarthivelabs-devs/payments-next/server';

const apiKey = process.env.SMARTHIVE_PAYMENTS_API_KEY!;

const payments = createSmartHiveClient({
  apiKey,
  baseUrl: process.env.SMARTHIVE_PAYMENTS_BASE_URL!,
  // sk_test_... → sandbox DB  |  sk_live_... → live DB (server-enforced)
  mode: apiKey.startsWith('sk_live_') ? 'live' : 'sandbox',
  timeout: 30_000,   // ms
  maxRetries: 2,
});

getSmartHiveClient(config?)

Same as createSmartHiveClient but returns a singleton — useful in serverless environments to avoid creating a new client per request.

createWebhookHandler(config)

Returns a Next.js App Router POST handler function. Reads the raw body, verifies the HMAC signature, and dispatches to your handlers.

createWebhookHandler({
  secret: string;              // HMAC signing secret (or set SMARTHIVE_PAYMENTS_WEBHOOK_SECRET env var)
  handlers: {
    [eventType: string]: (event: SmartHiveEvent) => Promise<void>;
    '*'?: (event: SmartHiveEvent) => Promise<void>;  // catch-all for all events
  };
  onError?: (err: Error, req: Request) => void;
})

Supported event types:

| Event | Description | |---|---| | payment.success | Payment completed | | payment.failed | Payment failed | | payment.pending | Awaiting confirmation | | payment.abandoned | Customer abandoned checkout | | payout.success | Payout completed | | payout.failed | Payout failed | | mandate.approved | Direct debit mandate approved | | mandate.declined | Mandate declined by customer | | refund.success | Refund processed | | * | Catch-all (runs before the specific handler) |


All Use Cases

Checkout flow (hosted page)

Two-phase flow: createSession only creates a pre-payment container — no transaction exists yet. The payment reference (txn_xxx) is created when the customer completes payment on the hosted checkout page. Read it from the ?reference= query parameter on your returnUrl, or from the payment.success webhook.

// STEP 1: Server creates a checkout session and returns the URL to the frontend.
// At this point there is NO payment transaction — just a checkout container.
const session = await payments.checkout.createSession({
  amount: '5000',
  currency: 'GHS',
  countryCode: 'GH',
  platform: 'web',
  customerEmail: '[email protected]',
  returnUrl: 'https://yourapp.com/order/complete',  // SmartHive adds ?reference=txn_xxx here after payment
  callbackUrl: 'https://yourapp.com/api/webhooks/payments',
  callerReference: 'ORDER-001',  // optional — attach your own ID, verify with it later
  mode: 'sandbox',
});

// session.data.sessionId       is a session ID (chs_xxx), NOT a payment reference.
// session.data.callerReference is echoed back ('ORDER-001') if you passed one.
// Do NOT call payments.payments.verify() with sessionId — use callerReference or txn_xxx.
return NextResponse.json({ checkoutUrl: session.data.checkoutUrl });

// STEP 2: Frontend redirects the customer to checkoutUrl.
// Customer pays on the SmartHive hosted page.

// STEP 3A: After payment, SmartHive redirects to your returnUrl with ?reference=txn_xxx&status=success
// app/order/complete/page.tsx
// const reference = searchParams.get('reference'); // e.g. txn_xxx
// → call GET /api/payments/verify/txn_xxx to confirm the payment

// STEP 3B: Simultaneously, SmartHive POSTs a payment.success webhook to your callbackUrl
// with event.data.reference = 'txn_xxx' — use this to fulfill the order server-side

Direct payment initialization

This is an alternative to the checkout session flow, not an addition. Do not call both createSession and payments.initialize for the same payment — they create independent records and each produces its own checkout URL. Pick one flow per payment.

const payment = await payments.payments.initialize({
  amount: '5000',
  currency: 'GHS',
  countryCode: 'GH',
  customerEmail: '[email protected]',
  paymentMethod: 'card',
  returnUrl: 'https://yourapp.com/order/complete',
  callbackUrl: 'https://yourapp.com/api/webhooks/payments',
  reference: 'ORDER-001',  // optional custom reference
  mode: 'sandbox',
});

// Redirect to payment.data.checkoutUrl

Verify a payment

Pass a payment reference — one of:

  • The ?reference= query parameter on your returnUrl after the customer pays
  • event.data.reference from a payment.success webhook event
  • Your own callerReference passed to createSession (e.g. 'ORDER-001')

Do not pass a session ID (chs_xxx from createSession) — no transaction exists under that ID.

// Option A: use the txn_xxx from ?reference= on your returnUrl or webhook
const result = await payments.payments.verify(reference);

// Option B: if you passed callerReference: 'ORDER-001' to createSession, use that directly
const result = await payments.payments.verify('ORDER-001');

if (result.data.status === 'success') {
  await fulfillOrder(result.data.reference);
}

Direct debit (Paystack + Hubtel — GH, NG)

Two providers are supported. Pass preferredProvider to select one.

// ── Paystack: card authorization ──────────────────────────────────────────
// Step 1: Customer approves on a hosted page — you receive a card token
const mandate = await payments.directDebit.createMandate({
  amount: '5000', currency: 'GHS', countryCode: 'GH',
  customerEmail: '[email protected]',
  returnUrl: 'https://yourapp.com/mandate/complete',
  callbackUrl: 'https://yourapp.com/api/webhooks/payments',
  preferredProvider: 'paystack',
  mode: 'sandbox',
});
// Redirect customer to mandate.data.checkoutUrl (Paystack authorization page)
// Receive card authorizationCode via mandate.approved webhook

// ── Hubtel: mobile money USSD/OTP ─────────────────────────────────────────
// Step 1: Customer approves via USSD/OTP on their phone — no redirect
const mandate = await payments.directDebit.createMandate({
  amount: '5000', currency: 'GHS', countryCode: 'GH',
  customerEmail: '[email protected]',
  customerPhone: '233244123456',    // required
  callbackUrl: 'https://yourapp.com/api/webhooks/payments',
  preferredProvider: 'hubtel',
  metadata: { mobileMoneyProvider: 'mtn' },   // mtn | vodafone | airteltigo
  mode: 'sandbox',
});
// No checkoutUrl — store mandate.data.rawResponse.authorizationCode (the MSISDN)
// Receive confirmation via mandate.approved webhook

// ── Step 2: Charge (both providers, no customer interaction) ──────────────
const charge = await payments.directDebit.chargeMandate({
  amount: '5000', currency: 'GHS', countryCode: 'GH',
  customerEmail: '[email protected]',
  authorizationCode: 'auth_code_from_webhook',  // card token (Paystack) or MSISDN (Hubtel)
  reference: 'SUBSCRIPTION-001',
  metadata: { mobileMoneyProvider: 'mtn' },     // required for Hubtel only
  mode: 'live',
});

Payouts

// Step 1: Create recipient
const recipient = await payments.payouts.createRecipient({
  type: 'mobile_money',
  name: 'Kwame Mensah',
  accountNumber: '0244123456',
  countryCode: 'GH',
  currency: 'GHS',
  mode: 'live',
});

// Step 2: Send payout
const payout = await payments.payouts.send({
  amount: '10000',
  currency: 'GHS',
  countryCode: 'GH',
  recipientCode: recipient.data.recipientCode,
  payoutMethod: 'mobile_money',
  reason: 'Contest winnings',
  mode: 'live',
});
// Confirmed via payout.success webhook

Bank verification

// List banks
const banks = await payments.payments.listBanks({ countryCode: 'GH', mode: 'sandbox' });

// Verify account before payout
const account = await payments.payments.verifyBankAccount({
  accountNumber: '0123456789',
  bankCode: 'GCB',
  countryCode: 'GH',
  currency: 'GHS',
  mode: 'sandbox',
});
console.log(account.data.accountName);

Idempotency

// Safe to retry — won't double-charge
const payment = await payments.payments.initialize(
  { amount: '5000', currency: 'GHS', countryCode: 'GH', ... },
  'order-001-attempt-1', // idempotency key
);

Error handling in route handlers

import {
  AuthenticationError,
  ValidationError,
  PaymentError,
  RateLimitError,
} from '@smarthivelabs-devs/payments-next/server';

export async function POST(req: Request) {
  try {
    const session = await payments.checkout.createSession({ ... });
    return NextResponse.json(session);
  } catch (err) {
    if (err instanceof AuthenticationError) {
      return NextResponse.json({ error: 'Invalid API key' }, { status: 401 });
    }
    if (err instanceof ValidationError) {
      return NextResponse.json({ error: err.message }, { status: 422 });
    }
    if (err instanceof RateLimitError) {
      return NextResponse.json(
        { error: 'Rate limited', retryAfter: err.retryAfter },
        { status: 429 },
      );
    }
    if (err instanceof PaymentError) {
      return NextResponse.json({ error: err.message, code: err.code }, { status: 400 });
    }
    throw err;
  }
}

Subscriptions

Server helpers

Gate server components, middleware, and Route Handlers against subscription access with a single import:

import {
  getCustomerSubscription,
  getCustomerSubscriptions,
  getSubscription,
  hasSubscriptionAccess,
  hasAnySubscriptionAccess,
} from '@smarthivelabs-devs/payments-next/server';

hasSubscriptionAccess — middleware gate

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { hasSubscriptionAccess } from '@smarthivelabs-devs/payments-next/server';

export async function middleware(req: NextRequest) {
  const userId = req.cookies.get('user_id')?.value;

  const ok = await hasSubscriptionAccess(
    'plan_pro',
    { customerId: userId },
    process.env.SMARTHIVE_PAYMENTS_API_KEY!,
  );

  if (!ok) return NextResponse.redirect(new URL('/upgrade', req.url));
  return NextResponse.next();
}

export const config = { matcher: ['/dashboard/pro/:path*'] };

hasAnySubscriptionAccess — multi-plan gate

// Gate access if the user has ANY of these plans
const ok = await hasAnySubscriptionAccess(
  ['plan_weekly_pro', 'plan_monthly_pro'],
  { customerId: userId },
  process.env.SMARTHIVE_PAYMENTS_API_KEY!,
);

getCustomerSubscription — fetch subscription data

// app/api/subscription/route.ts
import { getCustomerSubscription } from '@smarthivelabs-devs/payments-next/server';

export async function GET(req: Request) {
  const userId = getUserId(req); // your auth logic
  const sub = await getCustomerSubscription(
    'plan_pro',
    { customerId: userId },
    process.env.SMARTHIVE_PAYMENTS_API_KEY!,
  );
  if (!sub) return Response.json({ subscribed: false }, { status: 200 });
  return Response.json({ subscribed: true, status: sub.status });
}

getCustomerSubscriptions — batch lookup (single request)

const subs = await getCustomerSubscriptions(
  ['plan_basic', 'plan_pro', 'plan_enterprise'],
  { customerId: userId },
  process.env.SMARTHIVE_PAYMENTS_API_KEY!,
);

// subs is Record<string, Subscription | null>
const hasBasic = subs['plan_basic'] !== null;
const hasPro   = subs['plan_pro'] !== null;

getSubscription — fetch by subscription code

// app/api/webhooks/payments/route.ts — after receiving subscription.charged event
const sub = await getSubscription(event.data.subscriptionCode, process.env.SMARTHIVE_PAYMENTS_API_KEY!);

Client-side subscription hooks

All subscription hooks and components from @smarthivelabs-devs/payments-react are available via /client:

'use client';
import {
  useSubscription,
  useMultiPlanAccess,
  SubscriptionGuard,
  GracePeriodBanner,
} from '@smarthivelabs-devs/payments-next/client';

export default function PremiumFeaturePage({ userId }: { userId: string }) {
  return (
    <>
      <GracePeriodBanner
        planCode="plan_pro"
        customerId={userId}
        apiBaseUrl="/api"
        ctaLabel="Update Payment"
        onCtaClick={() => router.push('/billing')}
      />
      <SubscriptionGuard
        planCode="plan_pro"
        customerId={userId}
        apiBaseUrl="/api"
        fallback={<UpgradePrompt />}
        graceFallback={<PaymentFailedBanner />}
      >
        <ProFeature />
      </SubscriptionGuard>
    </>
  );
}

Multi-plan access (different tiers on the same page)

'use client';
import { SubscriptionGuard } from '@smarthivelabs-devs/payments-next/client';

export default function AppPage({ userId }: { userId: string }) {
  return (
    <>
      {/* Basic features — any active basic subscription */}
      <SubscriptionGuard planCode="plan_basic" customerId={userId} apiBaseUrl="/api" fallback={<Upgrade />}>
        <BasicFeature />
      </SubscriptionGuard>

      {/* Pro features — weekly OR monthly pro plan */}
      <SubscriptionGuard
        planCodes={['plan_weekly_pro', 'plan_monthly_pro']}
        customerId={userId}
        apiBaseUrl="/api"
        fallback={<UpgradeToPro />}
      >
        <ProFeature />
      </SubscriptionGuard>

      {/* Specific entitlement gate */}
      <SubscriptionGuard
        planCode="plan_pro"
        entitlement="download"
        customerId={userId}
        apiBaseUrl="/api"
        fallback={<UpgradeForDownloads />}
      >
        <DownloadButton />
      </SubscriptionGuard>
    </>
  );
}

Subscription webhook events

Add these handlers to your existing createWebhookHandler:

export const POST = createWebhookHandler({
  secret: process.env.SMARTHIVE_PAYMENTS_WEBHOOK_SECRET!,
  handlers: {
    'subscription.created':     async (event) => { /* new subscriber */ },
    'subscription.activated':   async (event) => { /* trial → active */ },
    'subscription.charged':     async (event) => { /* recurring charge succeeded */ },
    'subscription.charge_failed': async (event) => { /* charge failed, entering grace period */ },
    'subscription.paused':      async (event) => { /* merchant paused */ },
    'subscription.resumed':     async (event) => { /* merchant resumed */ },
    'subscription.cancelled':   async (event) => { /* cancelled or max retries exhausted */ },
    'subscription.trial_ending': async (event) => { /* 72h before trial ends — send reminder */ },
    'subscription.trial_ended': async (event) => { /* trial just ended */ },
  },
});

Coupons

Server-side helpers

Validate a coupon code or fetch its details in a Route Handler or Server Component without importing browser code.

// app/api/payments/coupon/validate/route.ts
import { validateCoupon, getCoupon } from '@smarthivelabs-devs/payments-next/server';

export async function POST(req: Request) {
  const { code, amountMinor, currency } = await req.json();

  const result = await validateCoupon(
    code,
    { amountMinor, currency, applicableTo: 'checkout' },
    process.env.SMARTHIVE_PAYMENTS_API_KEY!,
    { baseUrl: process.env.SMARTHIVE_PAYMENTS_BASE_URL! },
  );

  if (!result) return Response.json({ valid: false }, { status: 400 });

  return Response.json(result);
  // { valid: true, couponCode: 'SUMMER20', discountAmountMinor: 1000, finalAmountMinor: 4000 }
}
// Get a coupon's details (e.g. to display name + discount type in the UI)
const coupon = await getCoupon('SUMMER20', process.env.SMARTHIVE_PAYMENTS_API_KEY!);
if (coupon) console.log(coupon.name, coupon.discountType, coupon.currentUses);

Signature

import {
  validateCoupon,
  getCoupon,
} from '@smarthivelabs-devs/payments-next/server';

validateCoupon(
  code: string,
  params: CouponValidateParams,
  apiKey: string,
  options?: { baseUrl?: string }
): Promise<CouponValidateResponse | null>

getCoupon(
  code: string,
  apiKey: string,
  options?: { baseUrl?: string }
): Promise<Coupon | null>

Apply coupon at session creation (server-side)

Pass couponCode to createSession to pre-apply a discount. Set allowCouponInput: true to show a coupon entry field on the hosted checkout page — without this flag the coupon UI is hidden regardless of whether the app has active coupons.

const session = await payments.checkout.createSession({
  amount: '5000',
  currency: 'GHS',
  countryCode: 'GH',
  couponCode: 'SUMMER20',   // optional — pre-apply; discount stored server-side
  allowCouponInput: true,   // optional — show coupon input on the hosted checkout page
  customerEmail: '[email protected]',
  returnUrl: `${process.env.NEXT_PUBLIC_APP_URL}/order/complete`,
  callbackUrl: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/payments`,
});

// session.data.originalAmountMinor  — '5000'
// session.data.discountAmountMinor  — '1000'
// session.data.amountMinor          — '4000'  (what the customer pays)

Client-side coupon hooks and components

useCouponValidate and CouponInput from @smarthivelabs-devs/payments-react are re-exported from /client:

'use client';
import {
  useCouponValidate,
  CouponInput,
} from '@smarthivelabs-devs/payments-next/client';

function CheckoutForm() {
  const [coupon, setCoupon] = useState<{ code: string; final: number } | null>(null);

  return (
    <CouponInput
      amountMinor={5000}
      currency="GHS"
      apiKey={process.env.NEXT_PUBLIC_SMARTHIVE_API_KEY!}
      onApply={(code, discountAmountMinor, finalAmountMinor) =>
        setCoupon({ code, final: finalAmountMinor })
      }
      onRemove={() => setCoupon(null)}
    />
  );
}

See the @smarthivelabs-devs/payments-react README for full hook and component props.


Import Paths

| Path | Use in | What it provides | |---|---|---| | @smarthivelabs-devs/payments-next/server | Server Components, Route Handlers, middleware | createSmartHiveClient, getSmartHiveClient, createWebhookHandler, subscription server helpers, coupon server helpers (validateCoupon, getCoupon), all types | | @smarthivelabs-devs/payments-next/client | Client Components ('use client') | All React hooks + subscription hooks + all components + useCouponValidate + CouponInput | | @smarthivelabs-devs/payments-next | Barrel (re-exports server) | Same as /server |


Client Components

All React hooks from @smarthivelabs-devs/payments-react are available via @smarthivelabs-devs/payments-next/client:

'use client';
import {
  SmartHiveProvider,
  useCheckout,
  useCheckoutSession,
  usePaymentStatus,
  CheckoutButton,
  PaymentStatusDisplay,
  // Subscription
  useSubscription,
  useMultiPlanAccess,
  SubscriptionGuard,
  GracePeriodBanner,
} from '@smarthivelabs-devs/payments-next/client';

See the @smarthivelabs-devs/payments-react README for full hook documentation.


TypeScript

Types are available from both import paths:

// Server types
import type {
  SmartHivePaymentsConfig,
  WebhookHandlerConfig,
  WebhookEventHandler,
  SmartHiveEvent,
  SmartHiveEventType,
  PaymentInitializeParams,
  CheckoutSessionParams,
  DirectDebitMandateParams,
  DirectDebitChargeParams,
  PayoutParams,
  PaymentMode,
  // Coupon types (server)
  Coupon,
  CouponValidateParams,
  CouponValidateResponse,
  CouponDiscountType,
  CouponApplicableTo,
} from '@smarthivelabs-devs/payments-next/server';

// Coupon types (client)
import type {
  UseCouponValidateOptions,
  UseCouponValidateResult,
  CouponInputProps,
} from '@smarthivelabs-devs/payments-next/client';

Support

Contact Smart Hive Labs or open an issue in the workspace repository.