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

@teyaproduct/teya-blocks-react

v0.0.1

Published

React components for Teya Blocks payment SDK

Readme

Teya Blocks React

React components and hooks for Teya Blocks payment integration.

npm version

Requirements

  • @teyaproduct/teya-blocks-js 1.0+
  • React 18.0+ or 19.0+

Getting Started

Installation

npm install @teyaproduct/teya-blocks-js @teyaproduct/teya-blocks-react

Minimal Example

import { useMemo } from 'react';
import { initTeyaBlocks } from '@teyaproduct/teya-blocks-js';
import { TeyaBlocksProvider, CheckoutElement } from '@teyaproduct/teya-blocks-react';

const App = () => {
  const teyaPromise = useMemo(() => initTeyaBlocks('your_session_token'), []);

  return (
    <TeyaBlocksProvider teya={teyaPromise}>
      <CheckoutForm />
    </TeyaBlocksProvider>
  );
};

const CheckoutForm = () => {
  return (
    <CheckoutElement
      onSuccess={(response, paymentMethod) => {
        console.log('Payment succeeded via', paymentMethod, response);
      }}
      onError={(error, paymentMethod) => {
        console.error('Payment failed via', paymentMethod, error);
      }}
    />
  );
};

Using hooks for custom layouts

For full control over your payment UI, use the hooks API.

import { useMemo } from 'react';
import { initTeyaBlocks } from '@teyaproduct/teya-blocks-js';
import { TeyaBlocksProvider, useCheckout } from '@teyaproduct/teya-blocks-react';

const App = () => {
  const teyaPromise = useMemo(() => initTeyaBlocks('your_session_token'), []);

  return (
    <TeyaBlocksProvider teya={teyaPromise}>
      <CheckoutForm />
    </TeyaBlocksProvider>
  );
};

const CheckoutForm = () => {
  const { checkoutRef, submitPayment } = useCheckout({
    onSuccess: (response, method) => {
      console.log('Paid via', method, response);
    },
    onError: (error, method) => {
      console.error('Failed via', method, error);
    },
  });

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        submitPayment();
      }}
    >
      <div ref={checkoutRef} />
      <button type="submit">Pay</button>
    </form>
  );
};

Documentation

API Reference

TeyaBlocksProvider

All components and hooks must be wrapped in a TeyaBlocksProvider. It accepts a TeyaBlocks instance or the Promise returned by initTeyaBlocks().

import { initTeyaBlocks } from '@teyaproduct/teya-blocks-js';
import { TeyaBlocksProvider } from '@teyaproduct/teya-blocks-react';

const teyaPromise = initTeyaBlocks('your_session_token');

<TeyaBlocksProvider teya={teyaPromise}>
  <App />
</TeyaBlocksProvider>;

| Prop | Type | Description | | ---------- | --------------------------------------------------- | ----------------------------------------------- | | teya | TeyaBlocks \| Promise<TeyaBlocks \| null> \| null | SDK instance or promise from initTeyaBlocks() | | children | ReactNode | Child components |

Components

CheckoutElement

Unified payment form with card and Apple Pay support. This is the recommended way to accept payments.

import { useRef } from 'react';
import { CheckoutElement } from '@teyaproduct/teya-blocks-react';

const PaymentForm = () => {
  const checkoutRef = useRef(null);

  return (
    <>
      <CheckoutElement
        ref={checkoutRef}
        options={{ hideSubmitButton: true }}
        onSuccess={(response, method) => console.log('Paid via', method)}
        onError={(error, method) => console.error(error)}
        onTokenRefresh={async () => {
          const res = await fetch('/api/refresh-session');
          const { sessionToken } = await res.json();
          return sessionToken;
        }}
        containerStyles={{
          card: { minHeight: '100px' },
          applePay: { marginTop: '16px' },
        }}
      />
      <button onClick={() => checkoutRef.current?.submitPayment()}>Pay Now</button>
    </>
  );
};

| Prop | Type | Description | | ------------------- | -------------------------------------------------- | ------------------------------------------- | | options | CheckoutElementOptions | SDK checkout configuration | | onReady | () => void | Called when element is ready | | onChange | (event: ElementChangeEvent) => void | Called on form state changes | | onSuccess | (response, paymentMethod) => void | Called on payment success | | onError | (error, paymentMethod) => void | Called on payment failure | | onTokenRefresh | () => Promise<string> | Called to refresh an expiring session token | | submitButtonProps | object | Submit button customization | | containerStyles | {card?: CSSProperties; applePay?: CSSProperties} | Container styles for child elements | | className | string | Container CSS class | | style | CSSProperties | Container inline styles |

Ref methods:

| Method | Returns | Description | | ----------------- | -------------------------------- | ----------------------------------- | | submitPayment() | Promise<PaymentSubmitResponse> | Programmatically submit the payment |


CardElement

Single card input collecting card number, expiry, and CVC.

import { useRef } from 'react';
import { CardElement } from '@teyaproduct/teya-blocks-react';

const CardForm = () => {
  const cardRef = useRef(null);

  return (
    <>
      <CardElement
        ref={cardRef}
        options={{ hidePostalCode: true }}
        onChange={(e) => console.log('Complete:', e.complete)}
        onSuccess={(response) => console.log('Paid:', response)}
        onError={(error) => console.error(error)}
      />
      <button onClick={() => cardRef.current?.submitPayment()}>Pay</button>
    </>
  );
};

| Prop | Type | Description | | ---------------- | ------------------------------------- | ------------------------------------------- | | options | CardElementOptions | Card element configuration | | onReady | (element) => void | Called when element is ready | | onChange | (event: ElementChangeEvent) => void | Called on field state changes | | onFocus | () => void | Called when element receives focus | | onBlur | () => void | Called when element loses focus | | onSuccess | (response) => void | Called on payment success | | onError | (error) => void | Called on payment failure | | onTokenRefresh | () => Promise<string> | Called to refresh an expiring session token | | className | string | Container CSS class | | style | CSSProperties | Container inline styles |

Ref methods:

| Method | Returns | Description | | ----------------- | -------------------------------- | ----------------------------------- | | submitPayment() | Promise<PaymentSubmitResponse> | Programmatically submit the payment |


ApplePayElement

Renders an Apple Pay button. Automatically hides when Apple Pay is unavailable.

import { ApplePayElement } from '@teyaproduct/teya-blocks-react';

const ApplePay = () => (
  <ApplePayElement
    options={{ buttonType: 'buy', buttonStyle: 'black' }}
    paymentRequest={{
      countryCode: 'US',
      currencyCode: 'USD',
      total: { label: 'My Store', amount: '10.00' },
    }}
    autoSubmit
    onPaymentCompleted={(result) => {
      if (result.status === 'SUCCESS') {
        console.log('Payment ID:', result.paymentId);
      }
    }}
    onError={(error) => console.error(error)}
  />
);

| Prop | Type | Description | | -------------------- | ------------------------ | ------------------------------------------------- | | options | ApplePayElementOptions | Button styling options | | paymentRequest | ApplePayPaymentRequest | Payment request configuration | | autoSubmit | boolean | Auto-initiate payment on click (default: false) | | onReady | (element) => void | Called when element is ready | | onClick | () => void | Called when button is clicked | | onPaymentCompleted | (result) => void | Called when payment completes | | onCancel | () => void | Called when user cancels | | onError | (error: Error) => void | Called when an error occurs | | onChange | (event) => void | Called when availability changes | | className | string | Container CSS class | | style | CSSProperties | Container inline styles |


Individual Card Fields

Separate components for custom card form layouts.

import {
  CardNumberElement,
  CardExpiryElement,
  CardCvcElement,
} from '@teyaproduct/teya-blocks-react';

const CustomCardForm = () => (
  <div>
    <label>Card Number</label>
    <CardNumberElement onChange={(e) => console.log(e)} />

    <div style={{ display: 'flex', gap: '12px' }}>
      <div>
        <label>Expiry</label>
        <CardExpiryElement />
      </div>
      <div>
        <label>CVC</label>
        <CardCvcElement />
      </div>
    </div>
  </div>
);

All three share the same props:

| Prop | Type | Description | | ----------- | ------------------------------------- | ---------------------------------- | | options | CardElementOptions | Element configuration | | onReady | () => void | Called when element is ready | | onChange | (event: ElementChangeEvent) => void | Called on field state changes | | onFocus | () => void | Called when element receives focus | | onBlur | () => void | Called when element loses focus | | className | string | Container CSS class | | style | CSSProperties | Container inline styles |


PaymentErrorBoundary

Error boundary that catches rendering errors in payment components.

import { PaymentErrorBoundary, CardElement } from '@teyaproduct/teya-blocks-react';

const SafePayment = () => (
  <PaymentErrorBoundary
    onError={(error) => console.error('Payment error:', error)}
    fallback={({ error, resetError }) => (
      <div>
        <p>Payment form failed to load: {error.message}</p>
        <button onClick={resetError}>Retry</button>
      </div>
    )}
  >
    <CardElement />
  </PaymentErrorBoundary>
);

| Prop | Type | Description | | ---------- | ------------------------------------------------- | -------------------------------- | | children | ReactNode | Child components to protect | | fallback | ReactNode \| ({error, resetError}) => ReactNode | Custom fallback UI | | onError | (error, errorInfo) => void | Called when an error is caught | | onReset | () => void | Called when error state is reset |


LoadingSkeleton

Placeholder component shown while payment elements load. Built-in to CardElement and CheckoutElement, but also available for custom usage.

import { LoadingSkeleton } from '@teyaproduct/teya-blocks-react';

<LoadingSkeleton height={40} width="100%" ariaLabel="Loading card input" />;

| Prop | Type | Default | Description | | ----------- | ------------------ | -------------- | ---------------------- | | height | number \| string | 40 | Skeleton height | | width | number \| string | '100%' | Skeleton width | | animate | boolean | true | Enable pulse animation | | ariaLabel | string | 'Loading...' | Screen reader label | | className | string | - | CSS class | | style | CSSProperties | - | Inline styles |

Hooks

Hooks provide a lower-level API for building custom payment UIs. Each hook returns a ref to attach to a container <div>.

useTeyaBlocks()

Returns the TeyaBlocks SDK instance. Throws if SDK is not yet loaded.

const teya = useTeyaBlocks();

useTeyaBlocksLoader()

Returns the SDK instance along with loading and error state.

const { teya, loading, error, isReady } = useTeyaBlocksLoader();

if (loading) return <Spinner />;
if (error) return <p>Failed to load: {error.message}</p>;

| Return Value | Type | Description | | ------------ | -------------------- | --------------------------- | | teya | TeyaBlocks \| null | SDK instance | | loading | boolean | Whether SDK is loading | | error | Error \| null | Error if SDK failed to load | | isReady | boolean | true when SDK is loaded |


useCheckout(options?)

Hook for programmatic control of the checkout element.

const { checkoutRef, submitPayment } = useCheckout({
  onSuccess: (response, method) => console.log('Paid via', method),
  onError: (error, method) => console.error('Failed via', method),
});

return (
  <div>
    <div ref={checkoutRef} />
    <button onClick={submitPayment}>Pay</button>
  </div>
);

useCardElement(options?)

Hook for programmatic control of the card element.

const { cardElementRef, submitPayment } = useCardElement({
  options: { hidePostalCode: true },
  onSuccess: (response) => console.log('Paid:', response),
  onError: (error) => console.error('Failed:', error),
});

return (
  <div>
    <div ref={cardElementRef} />
    <button onClick={submitPayment}>Pay</button>
  </div>
);

useApplePay(options?)

Hook for programmatic Apple Pay integration.

const { applePayElementRef, isAvailable, submit } = useApplePay({
  options: { buttonType: 'buy', buttonStyle: 'black' },
  onPaymentCompleted: (result) => console.log('Payment:', result),
  onError: (error) => console.error(error),
});

if (isAvailable === false) return null;

return <div ref={applePayElementRef} />;

| Return Value | Type | Description | | -------------------- | --------------------------------------------- | ------------------------------------------------------------ | | applePayElementRef | RefObject<HTMLDivElement> | Attach to container div | | isAvailable | boolean \| null | null = checking, true = available, false = unavailable | | submit | (request) => Promise<ApplePayPaymentResult> | Submit with payment request |


Individual Card Field Hooks

Hooks for individual card fields when building custom layouts.

import {
  useCardNumberElement,
  useCardExpiryElement,
  useCardCvcElement,
} from '@teyaproduct/teya-blocks-react';

const { cardNumberElementRef } = useCardNumberElement({
  onChange: (e) => console.log('Number changed:', e),
});
const { cardExpiryElementRef } = useCardExpiryElement();
const { cardCvcElementRef } = useCardCvcElement();

return (
  <div>
    <div ref={cardNumberElementRef} />
    <div ref={cardExpiryElementRef} />
    <div ref={cardCvcElementRef} />
  </div>
);

Examples

Token refresh

Handle session token expiration with the onTokenRefresh callback:

<CheckoutElement
  onTokenRefresh={async () => {
    const response = await fetch('/api/create-checkout-session');
    const { sessionToken } = await response.json();
    return sessionToken;
  }}
  onSuccess={(response) => console.log('Paid:', response)}
/>

Custom submit button

Use hideSubmitButton with a ref to trigger payment from your own button:

const checkoutRef = useRef(null);

<CheckoutElement
  ref={checkoutRef}
  options={{hideSubmitButton: true}}
  onSuccess={(response) => console.log('Paid:', response)}
/>
<button onClick={() => checkoutRef.current?.submitPayment()}>
  Complete Purchase
</button>

Error boundary with custom fallback

<PaymentErrorBoundary
  fallback={({ error, resetError }) => (
    <div className="error-container">
      <p>Something went wrong: {error.message}</p>
      <button onClick={resetError}>Try again</button>
    </div>
  )}
  onError={(error, errorInfo) => {
    // Report to your error tracking service
    myErrorTracker.capture(error, errorInfo);
  }}
>
  <CheckoutElement onSuccess={handleSuccess} />
</PaymentErrorBoundary>

TypeScript

This package includes TypeScript declarations. All types are exported:

import type {
  // SDK types
  TeyaBlocks,
  TeyaBlocksOptions,
  CardElementOptions,
  CheckoutElementOptions,
  ApplePayElementOptions,
  ApplePayPaymentRequest,
  ApplePayPaymentResult,
  ElementChangeEvent,
  PaymentSubmitResponse,
  PaymentSubmitError,
  CheckoutPaymentMethod,
  SubmitButtonProps,

  // Component props
  CardElementProps,
  CardElementRef,
  CheckoutElementProps,
  CheckoutElementRef,
  ApplePayElementProps,
  LoadingSkeletonProps,
  PaymentErrorBoundaryProps,
  PaymentErrorFallbackProps,

  // Hook types
  UseCardElementOptions,
  UseCardElementResult,
  UseCheckoutOptions,
  UseCheckoutResult,
  UseApplePayOptions,
  UseApplePayResult,
} from '@teyaproduct/teya-blocks-react';

Development

npm install        # Install dependencies
npm run build      # Build (CJS + ESM + type declarations)
npm run dev        # Watch mode
npm run type-check # TypeScript type checking
npm run test       # Run tests
npm run test:watch # Run tests in watch mode
npm run clean      # Remove dist/

Contributing

Contributions welcome. Please read CONTRIBUTING.md before submitting a pull request.

License

Apache 2.0