Browser SDK

The Titus Browser SDK (@titus/sdk) lets you embed Titus checkout, authorization, customer portal, add-card, and estimate flows directly into your site.

Loading the SDK

Add the script tag to your HTML:

<script src="https://assets.gotitus.com/sdk/v1/titus.js"></script>

Once loaded, the titus global is available and ready to use.

Calling methods before the script has fully loaded will trigger an error.

Staging: If you're developing against the staging environment, you override the sdk global to point to staging:

window.titus = new TitusSDK({ baseWebUrl: "https://www.gotitus.dev" });

checkout(options)

Opens a checkout flow in a popup window. The SDK opens the popup immediately on click, calls your getId function to create the checkout, then navigates to the checkout flow once the ID is returned.

Returns { close } if the popup opened, or null if it was blocked.

// Triggered on a user click
const handle = titus.checkout({
  getId: async () => {
    // Call your server to create a checkout via the Titus API
    // and return the checkout ID
    const id = await yourServer.createCheckout();
    return id;
  },
  onSuccess: ({ id }) => {
    console.log("Checkout completed:", id);
  },
  onClose: ({ id, loanDecision }) => {
    console.log("Popup closed by user:", id, loanDecision);
  },
  onError: ({ code }) => {
    console.error("Checkout error:", code);
  },
});

// Programmatically close the popup later if needed
handle?.close();

Options

Option Type Required Description
getId () => Promise<string> Yes Async function that returns the checkout ID. Called after the popup opens.
newSession boolean No When true, logs out any existing Titus user before showing the popup so the flow starts with a fresh session. Useful when a business owner is logged in but wants a client to go through the flow on the same device.
onSuccess (result: { id: string }) => void No Called when the customer completes the checkout flow.
onClose (result: { id: string, loanDecision: 'approved' | 'denied' | 'awaiting-approval' | null }) => void No Called when the popup is closed — by the customer or by your code. loanDecision is null if no decision was made.
onError (error: { code: string }) => void No Called when an error occurs. See error codes below.
overlayText string No Overrides the default message shown on the overlay behind the popup.
overlayCancelButtonLabel string No Deprecated and ignored. The overlay has no cancel button — only a Continue button that refocuses the popup.

Return value

  • { close } — call close() to programmatically dismiss the popup and trigger onClose.
  • null — the popup was blocked by the browser. The onError callback fires with code popup_blocked.

authorize(options)

Opens a pre-authorization flow in a popup window. Same signature and behavior as checkout().

// Triggered on a user click
const handle = titus.authorize({
  getId: async () => {
    // Call your server to create an authorization via the Titus API
    // and return the authorization ID
    const id = await yourServer.createAuthorization();
    return id;
  },
  onSuccess: ({ id }) => {
    console.log("Authorization completed:", id);
  },
  onClose: ({ id, loanDecision }) => {
    console.log("Popup closed by user:", id, loanDecision);
  },
  onError: ({ code }) => {
    console.error("Authorization error:", code);
  },
});

portal(options)

Opens the customer portal in a popup window, where a customer can add a card, manage saved payment methods, and grant or revoke charging permission — without leaving your page.

Provide a getUrl function that returns a signed session URL from POST /v1/customers/{id}/portal-session. When the customer exits, onClose fires — re-fetch the customer's payment methods to pick up any changes.

// Triggered on a user click
const handle = titus.portal({
  getUrl: async () => {
    // Call your server to create a portal session via the Titus API
    // and return the session URL
    const url = await yourServer.createPortalSession();
    return url;
  },
  onClose: () => {
    console.log("Portal closed — refresh saved payment methods");
  },
  onError: ({ code }) => {
    console.error("Portal error:", code);
  },
});

Options

Option Type Required Description
getUrl () => Promise<string> Yes Async function returning a Titus-hosted portal session URL. Called after the popup opens.
onClose () => void No Called when the customer exits — via the portal's Exit button or by closing the window.
onError (error: { code: string }) => void No Called when an error occurs. See error codes below.
overlayText string No Overrides the default message shown on the overlay behind the popup.
overlayCancelButtonLabel string No Deprecated and ignored. The overlay has no cancel button — only a Continue button that refocuses the popup.

addPaymentMethod(options)

Opens a popup window where a customer adds a single card. Use it when you want to collect a card inline, for example next to a list of saved cards in your cart, rather than sending the customer to the full customer portal.

Provide a getUrl function that returns a signed session URL from POST /v1/customers/{id}/payment-method-session. When the customer saves the card, onSuccess receives it. The card is saved to the customer right away and can be charged by confirming a checkout with offSession: false.

// Triggered on a user click
const handle = titus.addPaymentMethod({
  getUrl: async () => {
    // Call your server to create a payment method session via the Titus API
    // and return the session URL
    const url = await yourServer.createPaymentMethodSession();
    return url;
  },
  onSuccess: ({ id, label, authorizedForOffSession }) => {
    console.log("Card added:", id, label, authorizedForOffSession);
  },
  onClose: () => {
    console.log("Popup closed without adding a card");
  },
  onError: ({ code }) => {
    console.error("Add payment method error:", code);
  },
});

Options

Option Type Required Description
getUrl () => Promise<string> Yes Async function returning a Titus-hosted payment method session URL. Called after the popup opens.
onSuccess (paymentMethod: { id: string, label: string, authorizedForOffSession: boolean }) => void No Called with the new card once the customer adds it. See the result below.
onClose () => void No Called when the popup is closed without a card being added — by the customer or by your code.
onError (error: { code: string }) => void No Called when an error occurs. See error codes below.
overlayText string No Overrides the default message shown on the overlay behind the popup.
overlayCancelButtonLabel string No Deprecated and ignored. The overlay has no cancel button — only a Continue button that refocuses the popup.

The added payment method

Field Type Description
id string ID of the saved payment method.
label string A display label for the card.
authorizedForOffSession boolean Whether the business is authorized to charge this card off-session (when the customer isn't present).

Whether the customer can authorize off-session charges depends on the authorizeOffSession value you pass when creating the session:

  • Omitted: the popup offers the customer an authorization checkbox, but only when a business is in scope (a business API key, or a platform key with externalId).
  • true: you've already collected consent on your own page. The popup shows the Stored Payment Authorization text instead of the checkbox, and the card is authorized for the business. Requires a business in scope.
  • false: the card is never authorized for off-session charges.

Return value

  • { close }: call close() to dismiss the popup and trigger onClose.
  • null: the browser blocked the popup. The onError callback fires with code popup_blocked.

showEstimateModal(options?)

Opens a full-screen modal with the Titus estimate page, where customers can check if they qualify and see their rate. Unlike checkout() and authorize(), this uses an iframe rather than a popup.

titus.showEstimateModal({
  platformId: "741474f1-960e-481a-b202-f0423fcabe75",
  externalId: "12345",
  amount: 1500.00,
});

All parameters are optional:

Option Type Description
businessShortCode string Short code identifying the business.
businessId string ID of the business.
platformId string ID of the platform.
externalId string Your external identifier for the business.
amount number The order total in dollars, e.g. 1500.00.

Passing platformId and externalId is recommended so the estimate modal can show personalized rates for the current business context.

amount changes what the modal is for. Without it the customer sees a rate estimate only. With it, the estimate is calculated against that order total and the customer can continue into an application for that amount. Pass it wherever you know the price, such as a package page or a cart.

Error codes

These error codes are passed to the onError callback in checkout(), authorize(), portal(), and addPaymentMethod():

Code When
popup_blocked The browser blocked the popup window. This usually means the call wasn't triggered by a direct user interaction (click).
get_id_failed (checkout() / authorize()) The getId function threw an error or its promise rejected.
invalid_id (checkout() / authorize()) The getId function returned an invalid ID.
get_url_failed (portal() / addPaymentMethod()) The getUrl function threw an error or its promise rejected.
invalid_url (portal() / addPaymentMethod()) The getUrl function returned a URL that isn't a valid Titus-hosted link.
invalid_result (addPaymentMethod()) The popup finished but didn't return a valid payment method.

Avoiding popup blocking

Browsers block popups that aren't triggered by a direct user action (like a click). The SDK is designed around this constraint — checkout(), authorize(), portal(), and addPaymentMethod() open the popup immediately when called, then use getId / getUrl to resolve the destination in the background while the popup is already open.

This means you must call these methods directly inside a click handler:

// Good — called directly from click handler
button.addEventListener('click', () => {
  titus.checkout({ ... });
});

// Bad — async gap before calling checkout, popup will be blocked
button.addEventListener('click', async () => {
  const data = await fetchSomeData();
  titus.checkout({ ... });
});

If the popup is blocked, onError fires with code popup_blocked and the method returns null.