PaymentMethods component
Loop Connect's "Payment Methods" component renders a customizable UI for users to manage their saved payment methods, including viewing, editing authorization amounts, adding new methods, and setting default payment methods.
This document outlines the interface for adding a component to a React-based project. For those who wish to utilize a Javascript native web component for rendering into any project that supports them, like Vue or Svelte, use this page as a guide for usage and types, and use our Web component guide for assistance with native web component syntax.
Customer identification
The following properties ("props") are added to the LoopConnectPaymentMethods
component to identify which customer's payment methods to manage. At least one of these properties should be provided.
<LoopConnectPaymentMethods
customerId="cust_abc123"
// OR
customerRefId="usr_abc1234"
/>
Property name | Type or example | Description |
---|---|---|
customerId | string , eg. "cust_abc123" | The unique identifier for an existing customer record. Will be prioritized over customerRefId if both exist. |
customerRefId | string , eg. "usr_abc1234" | The unique identifier specified by you for an existing or new customer record. If a new customer is created, this value will be stored as the customerRefId . |
minimumAuthorizationUsdAmount | number , eg. 199 (for $1.99) | The minimum USD equivalent the user must authorize from their wallet in the selected token. If no value is set, authorization amounts can be set to any value. |
disabled | boolean (default is false ) | Disables UI components such that they can not be interacted with by the client. |
Payment Methods events
The LoopConnectPaymentMethods
component also accepts optional event callback handlers. The callback functions take the form (detail: EventType) => void
, where EventType
is a placeholder to represent the individually defined type for each event, specified below.
Event | Callback types | Description |
---|---|---|
onPaymentMethodsReady | PaymentMethodsReadyEvent | The component has received the necessary data and is ready for user interaction. |
onPaymentMethodsReadyFailed | PaymentMethodsReadyFailedEvent | The component failed to initialize. |
onPaymentMethodsStateChange | PaymentMethodsStateChangeEvent | Once a user initiates an action, this component calls back with each step to allow you to provide detailed notifications for your users. Details on the payment method states is provided below. |
onPaymentMethodsTokenChange | PaymentMethodsTokenChangeEvent | The user has changed the selected token they wish to use when adding a new payment method |
onPaymentMethodsAuthorizationUpdated | PaymentMethodsAuthorizationUpdatedEvent | The user has updated their wallet's authorization to transfer the selected token to the contract |
onPaymentMethodsCustomerCreated | PaymentMethodsCustomerCreatedEvent | A record was created for this customer |
onPaymentMethodsCreated | PaymentMethodsCreatedEvent | A new payment method was created and saved to the customer account |
onPaymentMethodsUpdated | PaymentMethodsUpdatedEvent | An existing payment method was updated (e.g., set as default) |
onPaymentMethodsDeleted | PaymentMethodsDeletedEvent | A payment method was deleted from the customer account |
onPaymentMethodsFailed | PaymentMethodsFailedEvent | An action failed to complete. Details on the failure types is provided below. |
Both
onWalletChange
andonNetworkChange
(defined above asinitLoopConnect
properties) can be provided in the same format to theLoopConnectPaymentMethods
component for your convenience. Just note that each individual component will trigger their own provided callback for the same event occurrence, as these events are tied to the user's wallet which is a single connection shared application wide.
Callback prop types
The PaymentMethods
event callback functions receive data about the event through a single property, where each event receives an object with a different type. The following types correspond to the types specified in the "Payment Methods events" table above.
interface PaymentMethodsReadyEvent {
merchantId: string;
}
interface PaymentMethodsReadyFailedEvent {
type: "paymentMethodsReadyFailed";
message: string;
data: Record<string, any>;
}
interface PaymentMethodsTokenChangeEvent {
address: string;
networkId: number;
name: string;
symbol: string;
decimals: number;
logoUrl: string;
exchange: ExchangeRateDetails;
}
interface PaymentMethodsStateChangeEvent {
state:
| "findingCustomer"
| "idle"
| "editingAuthorization"
| "selectingMethod"
| "updatingMethod"
| "deletingMethod"
| "addingMethod"
| "confirmingBalance"
| "confirmingAuthorization"
| "updatingAuthorization"
| "signingMessage"
| "creatingCustomer"
| "creatingPaymentMethod";
message: string;
data: /* see "onPaymentMethodsStateChange states" for types */;
}
interface PaymentMethodsAuthorizationUpdatedEvent {
authorizationAmount: string;
suggestedAuthorizationTokenAmount: string | undefined;
minimumAuthorizationTokenAmount: string | undefined;
tokenAddress: string;
tokenSymbol: string;
networkId: number;
walletAddress: string;
existingAuthorizationAmount: string | null;
}
interface PaymentMethodsCustomerCreatedEvent {
customerId: string;
customerRefIds: {
merchantId: string;
customerRefId: string;
}[];
paymentMethods: {
paymentMethodId: string;
paymentMethodName: string;
networkId: number;
walletAddress: string;
isDefault: boolean;
token: {
tokenId: string;
symbol: string;
address: string;
decimals: number;
exchangeRates: {
currency: string;
price: string;
timestamp: number;
}[];
};
preAuthorization: {
balance: string;
authorization: string;
};
}[];
dateCreated: number;
}
interface PaymentMethodsCreatedEvent {
paymentMethodId: string;
merchantId: string;
paymentMethodName: string;
networkId: number;
walletAddress: string;
isDefault: boolean;
token: {
tokenId: string;
symbol: string;
address: string;
decimals: number;
exchangeRates: {
currency: string;
price: string;
timestamp: number;
}[];
};
preAuthorization: {
balance: string;
authorization: string;
};
}
interface PaymentMethodsUpdatedEvent {
paymentMethodId: string;
merchantId: string;
paymentMethodName: string;
networkId: number;
walletAddress: string;
isDefault: boolean;
token: {
tokenId: string;
symbol: string;
address: string;
decimals: number;
exchangeRates: {
currency: string;
price: string;
timestamp: number;
}[];
};
preAuthorization: {
balance: string;
authorization: string;
};
}
interface PaymentMethodsDeletedEvent {
paymentMethodId: string;
merchantId: string;
paymentMethodName: string;
networkId: number;
walletAddress: string;
isDefault: boolean;
token: {
tokenId: string;
symbol: string;
address: string;
decimals: number;
exchangeRates: {
currency: string;
price: string;
timestamp: number;
}[];
};
preAuthorization: {
balance: string;
authorization: string;
};
}
interface PaymentMethodsFailedEvent {
type:
| "methodCreationFailed"
| "insufficientBalance"
| "authorizationFailed"
| "insufficientAuthorization"
| "signedMessageRequired"
| "customerCreationFailed"
| "selectMethodFailed"
| "deleteMethodFailed";
message: string;
data: {
error: Record<string, any> | undefined;
};
}
onPaymentMethodsStateChange
onPaymentMethodsStateChange
The onPaymentMethodsStateChange
event handler will receive an object which contains the state
property set to one of the following string
values indicating the component's current state.
<LoopConnectPaymentMethods
// other props
onPaymentMethodsStateChange={
({ state, message, data }) => console.log(`${state}: ${message}`, data);
}
/>
State | Event data object type | Description |
---|---|---|
findingCustomer | PaymentMethodsStateChangeEventFindingCustomer | Looking up existing payment methods for the provided customer ID or customer reference ID |
idle | PaymentMethodsStateChangeEventIdle | The default state showing the customer's default payment method |
editingAuthorization | PaymentMethodsStateChangeEventEditingAuthorization | The user is editing the authorization amount for the default payment method |
selectingMethod | PaymentMethodsStateChangeEventSelectingMethod | Showing all available payment methods for the customer to select from |
updatingMethod | PaymentMethodsStateChangeEventUpdatingMethod | A payment method is being updated (e.g., set as default) |
deletingMethod | PaymentMethodsStateChangeEventDeletingMethod | A payment method is being deleted |
addingMethod | PaymentMethodsStateChangeEventAddingMethod | The user is adding a new payment method |
confirmingBalance | PaymentMethodsStateChangeEventConfirmingBalance | Awaiting a response back from the blockchain to confirm the wallet's balance is sufficient in the selected token on the wallet's current network |
confirmingAuthorization | PaymentMethodsStateChangeEventConfirmingAuthorization | Awaiting a response back from the blockchain to confirm the wallet's authorization is sufficient in the selected token on the wallet's current network for the contract required |
updatingAuthorization | PaymentMethodsStateChangeEventUpdatingAuthorization | The wallet's authorization was insufficient and is now awaiting confirmation that the user has completed their wallet's prompt to update the amount |
signingMessage | PaymentMethodsStateChangeEventSigningMessage | Awaiting a signed message from the user's wallet which has prompted them to authorize Loop Crypto to process payments |
creatingCustomer | PaymentMethodsStateChangeEventCreatingCustomer | Awaiting confirmation that a customer record was created |
creatingPaymentMethod | PaymentMethodsStateChangeEventCreatingPaymentMethod | Awaiting confirmation that a payment method was created and saved |
State data
object types
data
object typesIn addition to supplying the state
and a human-readable message
describing the event, a unique data
object containing information about the state is provided. The following types correspond to the types specified in the "onPaymentMethodsStateChange states" table above.
interface PaymentMethodsStateChangeEventFindingCustomer {
customerId?: string;
customerRefId?: string;
merchantId: string;
}
interface PaymentMethodsStateChangeEventIdle {
/* no additional data is provided for the idle state */
}
interface PaymentMethodsStateChangeEventEditingAuthorization {
tokenAddress: string;
tokenSymbol: string;
currentAuthorizationAmount: string | undefined;
minimumAuthorization: string | undefined;
}
interface PaymentMethodsStateChangeEventSelectingMethod {
/* no additional data is provided for the selecting method state */
}
interface PaymentMethodsStateChangeEventUpdatingMethod {
paymentMethodId?: string;
}
interface PaymentMethodsStateChangeEventDeletingMethod {
paymentMethodId?: string;
}
interface PaymentMethodsStateChangeEventAddingMethod {
/* no additional data is provided for the adding method state */
}
interface PaymentMethodsStateChangeEventConfirmingBalance {
amount: string;
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
token: {
name: string;
logoUrl: string;
symbol: string;
decimals: number;
address: string;
networkId: number;
exchange: {
currency: string;
rate: number;
updated: number;
provider: string;
};
}
}
interface PaymentMethodsStateChangeEventConfirmingAuthorization {
minimumAuthorization: string | undefined;
contractAddress: string;
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
token: {
name: string;
logoUrl: string;
symbol: string;
decimals: number;
address: string;
networkId: number;
exchange: {
currency: string;
rate: number;
updated: number;
provider: string;
};
}
}
interface PaymentMethodsStateChangeEventUpdatingAuthorization {
suggestedAuthorization: string | undefined;
contractAddress: string;
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
existingAuthorization: string | null;
token: {
name: string;
logoUrl: string;
symbol: string;
decimals: number;
address: string;
networkId: number;
exchange: {
currency: string;
rate: number;
updated: number;
provider: string;
};
}
}
interface PaymentMethodsStateChangeEventSigningMessage {
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
networkId: number;
}
interface PaymentMethodsStateChangeEventCreatingCustomer {
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
token: {
name: string;
logoUrl: string;
symbol: string;
decimals: number;
address: string;
networkId: number;
exchange: {
currency: string;
rate: number;
updated: number;
provider: string;
};
}
}
interface PaymentMethodsStateChangeEventCreatingPaymentMethod {
walletAddress: string;
chain: BlockchainNetwork;
networkName: string;
customerId: string;
customerRefId?: string;
token: {
name: string;
logoUrl: string;
symbol: string;
decimals: number;
address: string;
networkId: number;
exchange: {
currency: string;
rate: number;
updated: number;
provider: string;
};
}
}
onPaymentMethodsFailed
onPaymentMethodsFailed
The onPaymentMethodsFailed
event handler will receive an object which contains the type
property set to one of the following string
values indicating the reason the action was not completed successfully.
<LoopConnectPaymentMethods
// other props
onPaymentMethodsFailed={
({ type, message, data }) => console.log(`${type}: ${message}`, data);
}
/>
Failure type | Description |
---|---|
methodCreationFailed | There was a problem creating the new payment method |
insufficientBalance | The wallet connected does not have the sufficient amount of token on the current network |
authorizationFailed | The wallet failed to update the authorization amount for the selected token |
insufficientAuthorization | The user has not granted sufficient authorization for this token to meet the minimum requirements on the wallet's current network |
signedMessageRequired | The wallet failed to sign a message to approve the creation or management of payment methods |
customerCreationFailed | There was a problem creating or updating the customer record |
selectMethodFailed | There was a problem updating the default payment method selection |
deleteMethodFailed | There was a problem deleting the payment method |
Failure data
object types
data
object typesFor onPaymentMethodsFailed
events, the data
object contains an error
object of the type Record<string, any>
, which returns details about the error, and in most cases is a native Javascript Event
object.
User interface
You can provide optional properties to allow for customization of the UI to more seamlessly match your application's look and feel.
Styling
The component's UI can be customized by providing a string of CSS custom properties and values. The values assigned to the property must be valid CSS for that type of property, which corresponds to a CSS declaration. In the table below, each custom property is linked to the corresponding CSS property it represents to ensure clarity.
<LoopConnectPaymentMethods
// other props
customStyles={`
--loop-connect-font: italic 700 1rem 'Poppins', sans-serif;
--loop-connect-widget-shadow: 0 0 0.5rem rgba(99,99,99,0.3);
`}
/>
Property | CSS property or type | Description |
---|---|---|
--loop-connect-color-primary | <color> | Used as an accent color, primarily for button background, but not exclusively backgrounds |
--loop-connect-color-on-primary | color | Used as the text or accent color when shown within subcomponents colored with the primary color |
--loop-connect-radius | border-radius | Defines the roundness of box corners. Also applies to the entire widget, unless ``--loop-connect-widget-radius` overrides it |
--loop-connect-color-text | color | Defines the color of text |
--loop-connect-font | font | Assigns the size, weight, style and family for the font used as the main copy within the component |
--loop-connect-widget-border | border | Defines the border around the entire widget |
--loop-connect-widget-radius | border-radius | Defines the roundness of the corners of the widget. Will override --loop-connect-radius if set |
--loop-connect-widget-padding | padding | Specifies the padding around the outside of the component |
--loop-connect-widget-shadow | box-shadow | Specifies the styling of the outer shadow around the component |
--loop-connect-widget-background | background | Sets the background color of the component |
--loop-connect-input-border | border | Overrides the default border style of input and select subcomponents |
--loop-connect-input-background | background | Assigns a background color to input and select subcomponents |
Note that the
customStyles
property can also be provided to theinitLoopConnect
as a property and will apply the styles to all Loop Connect components application-wide. Properties then applied to individual components will override those app-wide values, creating a cascade effect.
Quickstart example
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
// 1. Import the package
import { initLoopConnect, LoopConnectPaymentMethods } from "@loop-crypto/connect";
// 2. Initialize is outside of the application
initLoopConnect({
jwtToken: "your-jwt-token-here",
entityId: "your-entity-id-here",
merchantId: "your-merchant-id-here",
});
// 3. Add the PaymentMethods component to the React application
createRoot(document.getElementById("root")!).render(
<StrictMode>
<LoopConnectPaymentMethods
customerRefId="test-user-id"
/>
</StrictMode>
);
Updated 5 days ago