Solid

@biaspay/solid provides Solid components and reactive hooks for Bias Elements.

Install

npm install @biaspay/solid

Solid 1.9 or later is a peer dependency. @biaspay/elements and @biaspay/sdk are installed as runtime dependencies.

Basic checkout

import { BiasProvider, ContactElement, PaymentElement, SubmitButton } from "@biaspay/solid";

export function Checkout(props: { clientSecret: string }) {
    return (
        <BiasProvider
            clientSecret={props.clientSecret}
            appearance={{ variables: { colorPrimary: "#4f46e5" } }}
            onComplete={() => location.assign("/complete")}
        >
            <ContactElement />
            <PaymentElement paymentMethodLayout="tabs" />
            <SubmitButton label="Pay now" />
        </BiasProvider>
    );
}

Pass clientSecret as a string expression, not an accessor. Solid tracks changes to the prop expression normally. Create the checkout session on your server; the Elements quickstart shows the complete flow.

BiasProvider

type BiasProviderProps = {
    clientSecret: string;
    initialCheckoutSession?: CheckoutSession;
    appearance?: Appearance;
    onComplete?: () => void;
    children: JSX.Element;
};

initialCheckoutSession is a one-time hydration seed. Its client_secret must match clientSecret. The provider shows a matching seed after browser activation and refreshes it from the API; later seed changes for the same client secret are ignored.

Changing clientSecret starts a new session and resets session-owned state. Changes to appearance and onComplete apply in place.

Components

ComponentProps
PaymentElementpaymentMethodLayout?: "tabs" | "radio", appearance?: Appearance
CardElementappearance?: Appearance
USBankAccountElementappearance?: Appearance
ContactElementappearance?: Appearance
AddressElementscope?: "billing" | "shipping", collectPhone?: boolean, appearance?: Appearance
SubmitButtondisabled?: boolean, label?: string

Use exactly one of the three payment components under a provider. paymentMethodLayout defaults to "tabs"; AddressElement.scope defaults to "billing". SubmitButton inherits the provider appearance and derives its default label and amount from the checkout session.

See components and appearance for composition, address behavior, and theme variables.

useBias

useBias() must be called under BiasProvider. Changing state is exposed as Solid accessors; actions are plain functions.

const bias = useBias();

bias.sessionState();
bias.paymentMethod(); // "card" | "us_bank_account" | undefined
bias.status(); // "idle" | "submitting" | "succeeded" | "failed"
bias.canSubmit();
bias.submissionError();

bias.setPaymentMethod("card");
bias.submit();
bias.refreshSession();

submit() runs validation and creates the payment when validation passes; duplicate calls during submission or after success are ignored. setPaymentMethod() ignores a method that the checkout session does not enable.

useBiasField

useBiasField(name, options?) binds to a non-sensitive provider field. Its state is an accessor:

const email = useBiasField("email", {
    validate: (value) => ({
        isValid: value.includes("@"),
        error: value.includes("@") ? null : "Enter a valid email.",
    }),
});

email.state(); // { value, isFocused, isValid, error }
email.setValue("shopper@example.com");
email.validate();
email.onFocus();
email.onBlur();

The hook does not register a field for collection. Keep the matching ContactElement or AddressElement mounted when the field must be required, autosaved, and submitted. Sensitive card and bank account fields are never exposed. See custom controls and fields.

Errors and retries

BiasElementsError extends Error with a code and retryable boolean. Codes are:

  • authentication_failed
  • session_load_failed
  • session_update_failed
  • payment_failed
  • frame_failed
  • configuration_error

Submission errors remain in submissionError() and can be shown inline. A refresh error that retains a usable session appears in sessionState() with both error and session; call refreshSession() to retry. A terminal load or configuration error is thrown to the nearest Solid error boundary. Reset the boundary and remount the provider to retry.

Server rendering

The package has an inert Node export, so it can be imported during SSR without evaluating custom elements. Components render nothing on the server and during the first hydration pass. Hooks are browser-only and throw when called through the server export. Place a loading skeleton outside the provider if the checkout must reserve space before activation.

Exports

The package exports BiasProvider, useBias, useBiasField, and the six child components above. It also exports named prop types, UseBiasResult, and shared types for appearance, checkout state, errors, fields, and address metadata. CheckoutSession remains owned by @biaspay/sdk and is not re-exported.

Built by Bias in California