Tokenize Payment Method
Overview
Component to render an entire form including a switch to use a credit card or bank account, a submit button and all fields required for proper use. This component can be used standalone or as part of the modular checkout system.
Props, Events & Methods
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
account-id | string | No | — | |
auth-token | string | No | — | |
disable-bank-account | boolean | No | — | |
disable-credit-card | boolean | No | — | |
hide-bank-account-billing-form | boolean | No | — | |
hide-card-billing-form | boolean | No | — | |
hide-submit-button | boolean | No | — | |
payment-method-group-id | string | No | — | |
save-payment-method-label | string | No | — | |
submit-button-text | string | No | 'Submit' |
Events
submit-event: fires when a payment token is created; payload includespayment_method_tokenand metadata.error-event: fires if tokenization fails; payload includescode,message, and validation hints.
Public methods
tokenizePaymentMethod()– programmatically trigger submission (returns a promise that resolves to a token payload).fillBillingForm(partialBillingDetails)– prefill customers' billing information from saved data.validate()– validate the form fields and return validation result.
Authorization
Authorization is performed by passing a web component token as
auth-token.
Web Component Token: These tokens are generated by your backend services using the Web Component Tokens API. Each token can be scoped to perform a set number of actions and is active for 60 minutes. When creating a web component token for this specific component you'll need to use the role:
write:tokenize:account_id. Make sure the value foraccount_idmatches the prop you also pass separately.
Security
The api endpoint associated with this component has the following security measures in place:
- Rate Limiting: POST requests to are limited to 2 requests per 10 seconds.
- Token-based Request Limiting: POST requests using web component token authentication are limited to 10 attempts per token.
These measures are in place to prevent abuse and ensure the security of the payment processing system.
Note: While client-id is still supported, we now recommend using web component tokens (auth-token) for enhanced security and flexibility.
Usage Patterns
Standalone Usage
When used standalone, the component provides its own submit button and handles all tokenization internally:
<justifi-tokenize-payment-method
account-id="acc_123"
auth-token="authToken"
payment-method-group-id="pmg_123"
/>
External Control
Hide the built-in submit button and control tokenization externally:
<justifi-tokenize-payment-method
account-id="acc_123"
auth-token="authToken"
hide-submit-button="true"
/>
<button id="external-submit">Submit Payment</button>
<script>
const tokenizer = document.querySelector('justifi-tokenize-payment-method');
const submitBtn = document.getElementById('external-submit');
submitBtn.addEventListener('click', async () => {
await tokenizer.tokenizePaymentMethod();
});
</script>
Pre-filling Billing Information
You can programmatically fill the billing form:
const tokenizer = document.querySelector('justifi-tokenize-payment-method');
tokenizer.fillBillingForm({
name: 'John Doe',
address_line1: '123 Main St',
address_city: 'Anytown',
address_state: 'NY',
address_postal_code: '12345',
});
Integration with Modular Checkout
When used within the justifi-modular-checkout wrapper component, this component automatically adapts its behavior:
- Auto-detection: The component automatically detects if it's slotted within a modular checkout
- Submit button hiding: The submit button is automatically hidden when inside modular checkout
- Shared authentication: Uses authentication tokens from the parent modular checkout component
- Coordinated validation: Validation is coordinated by the modular checkout wrapper
<justifi-modular-checkout
auth-token="authToken"
account-id="acc_123"
checkout-id="cho_123"
>
<justifi-tokenize-payment-method />
<!-- Other modular checkout components -->
</justifi-modular-checkout>
Example Usage
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
<title>justifi-tokenize-payment-method</title>
<script type="module" src="https://cdn.jsdelivr.net/npm/@justifi/webcomponents@6.7.3/dist/webcomponents/webcomponents.esm.js"></script>
<script
nomodule
src="https://cdn.jsdelivr.net/npm/@justifi/webcomponents@6.7.3/dist/webcomponents/webcomponents.js"
></script>
<style>
::part(font-family) {
font-family: georgia;
}
::part(color) {
color: darkslategray;
}
::part(background-color) {
background-color: transparent;
}
::part(button) {
padding: 0.375rem 0.75rem;
font-size: 16px;
box-shadow: none;
border-radius: 0px;
line-height: 1.5;
text-transform: none;
}
::part(button-disabled) {
opacity: 0.5;
}
::part(input) {
border-color: #555;
border-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-radius: 0;
border-style: solid;
box-shadow: none;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
padding: 0.375rem 0.75rem;
}
::part(input-focused) {
border-color: #333;
box-shadow: 0 0 0 0.25rem rgba(0, 0, 0, 0.25);
}
::part(input-invalid) {
border-color: #8a2a35;
box-shadow: 0 0 0 0.25rem rgba(244, 67, 54, 0.25);
}
::part(input-invalid-and-focused) {
box-shadow: 0 0 0 0.25rem rgba(244, 67, 54, 0.25);
border-color: #8a2a35;
}
::part(input-radio) {
background-color: #fff;
border-color: #333;
}
::part(input-checkbox) {
border-color: #333;
}
::part(input-checkbox-checked) {
background-color: #000;
border-color: #333;
}
::part(input-checkbox-checked-focused) {
background-color: #000;
box-shadow: 0 0 0 0.25rem rgba(0, 0, 0, 0.25);
}
::part(input-checkbox-focused) {
background-color: #fff;
box-shadow: 0 0 0 0.25rem rgba(0, 0, 0, 0.25);
}
::part(button-primary) {
color: #333;
background-color: transparent;
border-color: #333;
}
::part(button-primary):hover {
background-color: rgba(0, 0, 0, .05);
border-color: #333;
color: #333;
}
::part(radio-list-item) {
border-bottom: 1px solid #ddd;
}
::part(radio-list-item):hover {
background-color: #f9f9f9;
cursor: pointer;
}
</style>
</head>
<body>
<justifi-tokenize-payment-method
account-id="acc_123"
auth-token="authToken"
payment-method-group-id="pmg_123"
submit-button-text="Tokenize Payment Method"
/>
</body>
<script>
const justifiTokenizePaymentMethod = document.querySelector("justifi-tokenize-payment-method");
// Handle successful tokenization
justifiTokenizePaymentMethod.addEventListener("submit-event", (event) => {
const response = event.detail.response;
console.log("Tokenization successful:", response);
if (response.token) {
console.log("Payment method token:", response.token);
}
if (response.data) {
console.log("Full payment method data:", response.data);
}
});
// Handle errors
justifiTokenizePaymentMethod.addEventListener("error-event", (event) => {
console.error("Tokenization error:", event.detail);
});
// External tokenize button (when built-in submit button is hidden)
document.getElementById("tokenize-button").addEventListener("click", async () => {
try {
const result = await justifiTokenizePaymentMethod.tokenizePaymentMethod();
console.log("External tokenization result:", result);
} catch (error) {
console.error("External tokenization failed:", error);
}
});
// Fill billing form programmatically
document.getElementById("fill-billing-form").addEventListener("click", async () => {
await justifiTokenizePaymentMethod.fillBillingForm({
name: "John Doe",
address_line1: "123 Main St",
address_line2: "Apt 1",
address_city: "Anytown",
address_state: "NY", // Use 2-letter state code
address_postal_code: "12345",
});
console.log("Billing form filled");
});
// Validate form
document.getElementById("validate-form").addEventListener("click", async () => {
const validation = await justifiTokenizePaymentMethod.validate();
console.log("Validation result:", validation);
if (validation.isValid) {
console.log("Form is valid!");
} else {
console.log("Form has errors:", validation.errors);
}
});
</script>
</html>
Theming & Layout
| Part | Description | DOM target |
|---|---|---|
::part(radioListItem) | — | |
::part(billingForm) | — |