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

@clubessentialholdings/js-elements

v2.1.0

Published

OdinPay JavaScript Elements

Readme

OdinPay JavaScript Elements

The JS elements library provides OdinPay customers the means to collect sensitive data from users within their web applications, without the risk of managing such data. Currently the only supported data collection is Bank Account and Credit Card information but this data set will grow over time.


Getting Started

To instantiate OdinPay JS elements follow these steps:

  1. Generate a public token using the Generate Token endpoint and use the generated token to initialize the OdinPay JS elements library.

  2. Define the HTML elements where the JS Elements will be rendered. Each one of these elements needs to have a user defined unique ID that will be used for mapping and injecting the JS elements into your form, for example:

<div id="[user-defined-id-cardInfo]"></div>
<div id="[user-defined-id-postalcode]"></div>
<button id="[user-defined-id-button]">Save Payment Method</button>
  1. Include the library script in the page directly via a script tag (CDN), or via dependencies:
<script src="https://js.odinpay.net"></script>
const OdinPay = require("@clubessentialholdings/js-elements");
// or
import OdinPay from "@clubessentialholdings/js-elements";
  1. Then, add the following code to initialize the library. OdinPay will be defined as a global variable as well as accessible via window.OdinPay.
// CDN
window.addEventListener("load", async () => {
	const odinPayElements = OdinPay("public-token", {
		theme,
		country
	});
});

// via import
const odinPayElements = OdinPay("public-token", {
	theme,
	country
});
  1. Once the library has been initialized and the html elements haven defined, components can be rendered. Below is the example of how you’d render a credit card form with just the required fields:
odinPayElements.createCreditCardForm({
	submitButton: {
		selector: "[user-defined-id-button]",
		callback: (result) => {
			//... your goes code here
		}
	},
	fields: {
		cardInformation: {
			selector: "[user-defined-id-cardInfo]",
			ariaLabel: "testLabel"
		},
		postalCode: {
			selector: "[user-defined-id-postalcode]",
			placeholder: "Postal Code",
			ariaLabel: "testLabel"
		}
	},
	onChangeValidation: (fieldInformation) => {
		handleValidation(fieldInformation, "cardWithPostalCode-errors");
	}
});

API Documentation

INITIALIZER

OdinPay(token, config)

Initializes the OdinPay object

PARAMETERS:

| Name | Type | Attributes | Description | | :---------------- | :----- | :--------- | :------------------------------------------------------------------------------- | | token | string | | Token generated by using the generate public token endpoint from the OdinPay API | | config | object | optional | Configuration of the theme & country |


METHODS

| Methods | Explanation | | :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | createCardForm ({ submitButton, fields, onChangeValidation }) | Renders a credit card form based on the desired configuration. The cardInformation and postalCode fields are required to be able to render a credit card form. | | createBankAccountForm({ submitButton, fields, onChangeValidation }) | Defines the look and feel of the component(s) inputsRenders a bank account form based on the desired configuration. The accountNumber, bankAccountType, routingNumber and name (name on account) fields are required to be able to render a bank account card form. |

PARAMETERS:

| Property | Type | attributes | Explanation | | :------------------------------------ | :------- | :--------- | :----------------------------------------------------------------- | | submitButton | object | | Submit button configuration | | fields | object | | Defines the fields that will be rendered in the credit card form. | | onChangeValidation | function | optional | If desired, you can access the field validation object using this. |

Card Example

OdinPay.createCardForm({
	submitButton: {
		selector: "[user-defined-id-submitButton]",
		callback: (result) => {
			handleResponse(result);
		}
	},
	fields: {
		cardInformation: {
			selector: "[user-defined-id-cardInformation]",
			ariaLabel: "testLabel"
		},
		postalCode: {
			selector: "[user-defined-id-postalCode]",
			placeholder: "Postal Code",
			ariaLabel: "testLabel"
		}
	},
	onChangeValidation: (validation) => handleValidation(validation)
});

Bank Account Example

OdinPay(token).createBankAccountForm({
	submitButton: {
		selector: "[user-defined-id-submitButton]",
		callback: (result) => {
			handleResponse(result);
		}
	},
	fields: {
		accountNumber: {
			selector: "[user-defined-id-accountNumber]",
			ariaLabel: "testLabel",
			placeholder: "Account Number"
		},
		routingNumber: {
			selector: "[user-defined-id-routingNumber]",
			placeholder: "Routing Number"
		},
		bankAccountType: {
			selector: "[user-defined-id-bankAccountType]"
		},
		name: {
			selector: "[user-defined-id-nameOnAccount]",
			placeholder: "Name"
		}
	},
	onChangeValidation: (validation) => handleValidation(validation)
});

CONFIG

Is an optional property in OdinPay initialization, allowing additional configurations for theme and country

{
	"theme": {},
	"country": "US"
}

| Property | Type | Attributes | Explanation | | :-------------- | :-------- | :--------- | :------------------------------------------------------ | | theme | object | optional | Defines certain font-related styles and pseudo-elements | | country | "US","CA" | optional | defaults to US, used for bank account fields |

Currently Supported Countries

  • US
  • CA

THEME

An optional object to allow the user to define custom styles for background colors, padding, fonts and pseudo-elements. These will be applied through the theme object rather than through a CSS stylesheet.

Other styling for things such as borders to your container divs should be done in a CSS sheet.

Example theme object:

{
	"fontFamily": "Fira Sans,Droid Sans",
	"fontSize": "16px",
	"::placeholder": {
		"color": "rgb(117, 117, 117)",
		"fontSize": "16px"
	}
}

Allowed CSS Properties in the theme object

  • backgroundColor
  • color
  • fontFamily
  • fontSize
  • fontSmooth
  • fontStyle
  • fontVariant
  • fontWeight
  • lineHeight
  • letterSpacing
  • textAlign
  • padding
  • textDecoration
  • textShadow
  • textTransform

Allowed pseudo-elements in the theme object

  • :hover
  • :focus
  • :read-only
  • ::placeholder
  • ::selection
  • :disabled

ERROR HANDLING

There are two types of error handling: on change and on submit. Both return the same format of error object to provide a more uniform response for error handling.

On Change

An optional function in the configuration object when using createCardForm or createBankForm. Used to handle field validation errors.

It will return an error object during blur and change events.

Please see the static folder for a fully functional example of onChange validation.


const handleValidation = (fieldInformation) => {
    const {selector, errorCode, fieldName} = fieldInformation;
    //handle validation errors here
}

await op.createCardForm({
  submitButton: {...},
  fields: {...},
  onChangeValidation: (fieldInformation) => {
    handleValidation(fieldInformation);
  }
})

On Submit

This will only trigger when the user clicks the submit button. It returns the submit response.

If there are errors, it will return an array of the same error object as the onChange validation. However, onSubmit can also return backend errors unlike the onChange validation.

Please see static folder for fully functional examples of onSubmit error handling.

await op.createCardForm({
    onChangeValidation: {...},
    fields: {...},
    submitButton: {
        selector: "bankOnly-submit-CA",
        callback: (result) => {
            result?.errors?.forEach((fieldInformation) => {
                handleValidation(fieldInformation);
            });
        }
    }
});

TYPE DEFINITIONS

Submit Button

The configuration object for your form's submit button.

| Parameter | Type | Attributes | Explanation | | :-------- | :------- | :--------- | :--------------------------------------- | | selector | string | required | the id of the HTML button element | | callback | function | required | callback to handle response from OdinPay |

Field

Configuration object for an input field.

PROPERTIES:

| Parameter | Type | Attributes | Explanation | | :----------- | :----- | :------------------------------------ | :------------------------------------------- | | selector | string | | User defined id of the HTML element | | ariaLabel | string | optional | Aria label for the input | | placeholder | string | optional - n/a for card field | Placeholder for input | | initialValue | string | optional - n/a for card & bank fields | Pass initial values to the inputs if desired |

Fields Properties

These are the properties that are allowed in the fields list

PROPERTIES:

| Name | Type | Attributes | | :-------------- | :--------------- | :---------------- | | cardInformation | object | required for card | | accountNumber | object | required for bank | | routingNumber | object | required for bank | | bankAccountType | object | required for bank | | postalCode | object | required for card | | name | object | optional for bank | | addressLine1 | object | optional | | addressLine2 | object | optional | | city | object | optional | | state | object | optional | | country | object | optional | | emailAddress | object | optional | | phoneNumber | object | optional |

Submit Response

returned from the submit button's callback.

| Name | Type | Attributes | | :------------ | :-------------------------------- | :----------------------------------------- | | success | Boolean | | | errors | Error[] | an array of error objects, if errors exist | | paymentMethod | Payment Method | on success, you will receive this object |

Payment Method

The payment method object from the submit callback.

| Name | Type | Attributes | | :----------------- | :--------------------------------------------- | :------------------------------------------- | | id | String | | | createdAt | String | | | updatedAt | String | | | type | "CREDIT_CARD", "DEBIT_CARD", or "BANK_ACCOUNT" | | | billingInformation | Object | all billing information supplied by the user | | accountNumber | String | a masked version of the account number | | expirationDate | String | card only | | cardBrand | String | card only | | bankAccountType | "CHECKING" or "SAVINGS" | bank only | | accountNumber | String | bank only | | routingNumber | String | US bank only | | transitNumber | String | CA bank only | | institutionNumber | String | CA bank only | | country | String | bank only - 2 digit country code |

Error Object

Returned from both the onChange and onSubmit validation.

| Name | Type | Attributes | | :-------- | :------------------------ | :--------------------------------------------------- | | selector | String | the provided selector for the field's container div | | errorCode | ErrorCode | a code describing the error | | fieldName | String | name of the field | | type | ErrorType | either field validation or backend | | isValid | Boolean | will only return true onChange if the field is valid |

Error types:

| Error Code | Description | | :--------------- | :------------------------------ | | FIELD_VALIDATION | an error from schema validation | | BACKEND | an error from the Odin backend |

ERROR CODES:

| Error Code | Description | | :----------------------- | :------------------------------------- | | INVALID | generic invalidation against a schema | | INVALID_CARD_INFORMATION | invalid card field | | INVALID_BANK_INFORMATION | invalid bank field | | MAX_LENGTH_EXCEEDED | max length of schema has been exceeded | | REQUIRED | field is blank but required | | UNAUTHORIZED | API Unauthorized error | | TOKENIZATION_FAILED | API failure for tokenization | | VALIDATION_ERROR | API validation error |


Demo

Try out different CodePen examples for both card and bank forms:

https://codepen.io/collection/vOYpPa