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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@eonx/payment-elements

v1.27.2

Published

- [Configuration](#configuration) - [Create payment card](#create-payment-card) - [Capture payment](#capture-payment) - [Pay now](#pay-now) - [Void payment](#void-payment) - [Types](#types) - [Error handling](#error-handling)

Downloads

2,075

Readme

Payment Elements SDK

Getting started

npm install @eonx/payment-elements
yarn add @eonx/payment-elements

Configuration

import { configurePaymentElements } from '@eonx/payment-elements';

configurePaymentElements({
  /**
   * Set it as true if you are working in a test environment
   **/
  test: true,
  /**
   * Change input behavior to floating label
   **/
  inputFloatLabel: true,
  /**
   * If true the expiry date will be in MM/YYYY, else MM/YY
   **/
  expiryFullYear: true,
  themes: {
    /**
     * Global settings for all themes
     */
    base: {
      fonts: [
        {
          css: 'https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Roboto&display=swap',
        },
      ],
      styles: {
        fontFamily: 'Lato',
        fontSizeBase: '12px',
        fontSizeSmall: '15px',
        colorPrimary: '#6366f1',
        colorBorder: '#e0e0e0',
        colorDanger: '#e53935',
        colorSuccess: '#22c55e',
        colorText: '#37474f',
        colorPlaceholder: '#78909c',
        colorDivider: '#e5e7eb',
        colorInputLabel: '#455a64',
        colorInputBackground: '#fff',
        colorTextLight: 'gray',
        borderRadius: '6px',
        spacing: '10px',
        spacingLabel: '2px',
        inputHeight: '44px',
        buttonHeight: '46px',
      },
    },
    /**
     * Global settings will be inherited and overrode here
     */
    custom: {
      fonts: [
        {
          family: 'Poppins',
          weight: '400',
          display: 'swap',
          src: `url(${window.location.origin}/fonts/poppins-regular.woff2)`,
        },
      ],
      styles: {
        fontFamily: 'Poppins',
        fontSizeBase: '16px',
      },
    },
  },
});

You may update the configuration at the runtime.

configurePaymentElements({
  theme: 'dark',
});

Create payment card

import {
  createPaymentCard,
  ApiError,
  FrameError,
  CreateCardError,
  PaymentCardTokenizeResult,
} from '@eonx/payment-elements';

const element = createPaymentCard({
  /**
   * Predefined values: 'light' or 'dark'.
   * You can pass custom theme created by `createTheme` method.
   */
  theme: 'light',
  /**
   * API key with access to the payment API.
   */
  apiKey: '-api-key-',
  /**
   * HTML container where the payment element will be mounted.
   */
  container: 'container-id',
  /**
   * Initial value for the cardholder field
   */
  cardholder: 'Joe Black',
  onSuccess(response: PaymentCardTokenizeResult) {
    // Callback when credit card created
  },
  onError(error: Error<CreateCardError | FrameError | ApiError>) {
    // Callback when any errors occurring with element
  },
  onProcess() {
    // Callback when form submitting.
  },
  onChange(event: {
    data: CardDetails;
    isValid: boolean;
    isReadyToSubmit: boolean;
  }) {
    // Form values changed
  },
  onMounted() {
    // The form is ready to display
  },
});

/**
 * Element will be automatically disposed when container will be removed from DOM.
 * Use dispose method if you need to cancel element manually.
 */
element.dispose();

/**
 * Send submit event to form
 */
element.submit();

/**
 * Pre-fill form. Partial values is allowed.
 */
element.prefill({
  cardholder: 'Test User',
  number: '5123450000000008',
  cvc: '100',
  expiryMonth: 1,
  expiryYear: 2039,
});

element.prefill({
  cardholder: 'Test User',
});

/**
 * Submit on the form will not be triggered
 */
element.disableSubmit();

/**
 * Cancel form disabling by previous method.
 */
element.enableSubmit();

/**
 * Change theme after the element has been created.
 */
element.changeTheme('dark');

Types

interface CardDetails {
  cardholder: string;
  number: string;
  cvc: string;
  expiryMonth: number;
  expiryYear: number;
}

Result

interface PaymentCardTokenizeResult {
  cardholder: string;
  createdAt: string;
  currency: {
    id: string;
    name: string;
    createdAt: string;
    updatedAt: string;
  };
  customer: {
    createdAt: string;
    fullName: string;
    id: string;
    updatedAt: string;
  };
  description: string;
  expiryMonth: number;
  expiryYear: number;
  hash: string;
  id: string;
  pan: string;
  paymentMethodType: PaymentMethodType;
  provider: {
    name: string;
    id: string;
    createdAt: string;
    updatedAt: string;
  };
  reference: string;
  status: 'inactive' | 'active';
  updatedAt: string;
  verified: boolean;
}

Error Codes

| Code | Description | | ---- | ----------------------------- | | 10 | API key required | | 11 | Payment API URL not found | | 12 | Unhandled API error | | 20 | HTML container required | | 21 | Failed to render payment UI | | 22 | Incorrect UI URL | | 60 | Failed to create payment card |

Capture payment

import {
  capturePayment,
  FrameError,
  ApiError,
  CapturePaymentError,
} from '@eonx/payment-elements';

const element = capturePayment({
  /**
   * API key with access to the payment API.
   */
  apiKey: '-api-key-',
  /**
   * Order intent ID
   */
  orderIntentId: '-intent-id',
  /**
   * Manage to display CVV input in the payment process.
   * Not required.
   */
  isVerificationCodeRequired: true,
  /**
   * Include verification code to capture request
   * Not required.
   */
  verificationCode: '000',
  /**
   * Attach card to order intent before capture
   * Not required.
   */
  attachCard: {
    reference: 'HP6C8X3H97',
    type: 'MastercardCredit',
    amount: '10000'
    consumerOwningEntity: 'someOwningEntity',
    paymentConfig: 'TEST'
  },
  onError(error: Error<CapturePaymentError | FrameError | ApiError>) {
    // Callback when any errors occurring with element
  },
  onSuccess(result: OrderIntent) {
    // Callback when the payment is captured
  },
  onVerify({ mount }) {
    // Callback when we need to mount the UI to handle 3DS.
    // See MountContainer type
    mount('#container');
  },
});

/**
 * Element will be automatically disposed when container will be removed from DOM.
 * Use dispose method if you need to cancel element manually.
 */
element.dispose();

Error Codes

| Code | Description | | ---- | -------------------------------------------------------- | | 10 | API key required | | 11 | Payment API URL not found | | 12 | Unhandled API error | | 20 | HTML container required | | 21 | Failed to render payment UI | | 40 | Failed to complete payment | | 41 | Order intent ID has required for capture | | 42 | Failed to retrieve order intent | | 43 | Payment source required | | 44 | Multiple cards are not supported | | 45 | Payment gateway has not supported | | 46 | Failed to load third-party SDK | | 47 | 3D Secure verification failed. Please contact your bank. | | 48 | Unable to apply payment for your order |

Pay now

import { payNow } from '@eonx/payment-elements';

const element = payNow({
  /**
   * Predefined values: 'light' or 'dark'.
   * You can pass custom theme created by `createTheme` method.
   * Non-required field.
   */
  theme: 'light',
  /**
   * API key with access to the payment API.
   */
  apiKey: '-api-key-',
  /**
   * HTML container where the payment element will be mounted.
   */
  container: 'container-id',
  /**
   * IntentId of the order to finalize the payment
   */
  orderIndentId: 'xxxxxxx-f6a3-4524-8f5f-df2a7188xxxx',
  /**
   * Payment card to capture order intent.
   * Non-required field.
   */
  card: {
    cardholder: 'Joe Black',
    number: '4242 4242 4242 4242',
    expiryMonth: 1,
    expiryYear: 2039,
  },
  /**
   * Manage to display CVV input in the payment process.
   * Non-required field.
   */
  isVerificationCodeRequired: true,
  onError(error: Error<CreateCardError | FrameError | ApiError>) {
    // Callback when any errors occurring with element
  },
  onProcess() {
    // Callback when form submitting.
  },
  onMounted() {
    // The form is ready to display
  },
});

/**
 * Element will be automatically disposed when container will be removed from DOM.
 * Use dispose method if you need to cancel element manually.
 */
element.dispose();

Error Codes

| Code | Description | | ---- | -------------------------------------------------------- | | 10 | API key required | | 11 | Payment API URL not found | | 12 | Unhandled API error | | 20 | HTML container required | | 21 | Failed to render payment UI | | 40 | Failed to complete payment | | 41 | Order intent ID has required for capture | | 42 | Failed to retrieve order intent | | 43 | Payment source required | | 44 | Multiple cards are not supported | | 45 | Payment gateway has not supported | | 46 | Failed to load third-party SDK | | 47 | 3D Secure verification failed. Please contact your bank. | | 48 | Unable to apply payment for your order |

Void payment

import {
  voidPayment,
  Error,
  VoidPaymentError,
  ApiError,
} from '@eonx/payment-elements';

try {
  const result: OrderIntent = await voidPayment({
    /**
     * API key with access to the payment API.
     */
    apiKey: '-your-key-',
    /**
     * Order intent ID
     */
    orderIntentId: '-intent-id-',
  });
} catch (e) {
  const error: Error<VoidPaymentError | ApiError> = e;
  // use error
}

Error Codes

| Code | Description | | ---- | ------------------------------------- | | 10 | API key required | | 11 | Payment API URL not found | | 12 | Unhandled API error | | 50 | Order intent ID has required for void |

Types

type MountContainer = string | HTMLElement;
export interface OrderIntent {
  id: string;
  status: 'pending' | 'voided' | 'captured';
  order: {
    id: string;
    generalStatus: 'completed' | 'failed' | 'processing' | 'refunded';
    createdAt: string;
    updatedAt: string;
  };
  provider: {
    id: string;
    name: string;
    createdAt: string;
    updatedAt: string;
  };
  destinations: PaymentDestination[];
  securityTokenRequired: boolean;
  sources: PaymentSource[];
  tags: string[];
  createdAt: string;
  updatedAt: string;
  expiresAt: string;
  feeType: 'provider' | 'source';
  customer?: {
    createdAt: string;
    id: string;
    updatedAt: string;
    fullName: string;
  };
  description?: string;
  dueFeeAmount?: string;
  dueFinalAmount?: string;
  externalId?: string;
  statementDescriptor?: string;
}

export interface PaymentDestination {
  id: string;
  amount: string;
  reference: string;
  type:
    | 'BankAccountReceiver'
    | 'BpayReceiver'
    | 'Ewallet'
    | 'ProviderFloat'
    | 'UnattachedReceiver';
  createdAt: string;
  updatedAt: string;
  description?: string;
  fixedFeeRate?: string;
  paymentConfig?: string;
  percentageFeeRate?: number;
  statementDescriptor?: string;
}

export interface PaymentSource {
  /**
   * Amount to come from the order source, expressed in the smallest unit of the currency of the order source,
   * e.g. 500 for AUD 5.00. The amount is exclusive of fees.
   */
  id: string;
  reference: string;
  type: PaymentMethodType;
  createdAt: string;
  updatedAt: string;
  amount: string;
  creditLimitAllowed: boolean;
  feePayer: boolean;
  gateway: string;
  consumerOwningEntity?: string;
  description?: string;
  percentageFeeRate?: number;
  paymentConfig?: string;
  paymentRate?: number;
  recurringPaymentExternalId?: string;
  statementDescriptor?: string;
}

export type PaymentMethodType =
  | 'AmericanExpressCredit'
  | 'MastercardCredit'
  | 'MastercardDebit'
  | 'MastercardPrepaid'
  | 'VisaCredit'
  | 'VisaDebit'
  | 'VisaPrepaid';

Errors

interface Error<T> {
  code: T;
  message: string;
  description: string;
  violations: Record<string, string[]>;
  data: any;
  isCritical: boolean;
  responseStatus?: number;
}
export enum ApiError {
  KeyRequired = 10,
  UrlRequired = 11,
  UnhandledError = 12,
  KeyExpired = 13,
}
export enum FrameError {
  ContainerRequired = 20,
  MountFailed = 21,
}
export enum CapturePaymentError {
  CaptureFailed = 40,
  IntentIdRequired = 41,
  IntentFailed = 42,
  CardRequired = 43,
  MultipleCards = 44,
  UnknownGateway = 45,
  SdkFailed = 46,
  SecureFailed = 47,
  OrderFailed = 48,
}
export enum VoidPaymentError {
  IntentIdRequired = 50,
}
export enum CreateCardError {
  Failed = 60,
}

Error handling

import { createPaymentCard, ApiError } from '@eonx/payment-elements';

const element = createPaymentCard({
  // ...
  onError(e: Error) {
    if (e.code === ApiError.KeyExpired) {
      // For example, reload UI and display notify when API key is expired
    } else {
      // handle error
    }
  },
});