FloPayFloPay
API Reference@flopay/shared

Helpers

Configuration, display, validation, and currency helper functions exported by @flopay/shared.

configureFlopay

Configure the FloPay SDK globally. Call once at app startup to set the environment.

function configureFlopay(config: { environment: FloPayEnvironment }): void
ParameterTypeRequiredDescription
config.environment'staging' | 'production'YesThe environment to use.
import { configureFlopay } from '@flopay/shared';
 
// In production
configureFlopay({ environment: 'production' });
 
// In staging/development
configureFlopay({ environment: 'staging' });

resolveBillingApiUrl

Resolves the billing API URL from available configuration.

function resolveBillingApiUrl(billingApiUrl?: string): string
ParameterTypeRequiredDescription
billingApiUrlstringNoExplicit override (highest priority).

Resolution priority:

  1. Explicit billingApiUrl parameter
  2. configureFlopay() global environment
  3. Fallback: staging
import { resolveBillingApiUrl } from '@flopay/shared';
 
// No args — reads from configureFlopay() or falls back to staging
const url = resolveBillingApiUrl();
 
// Explicit override
const url = resolveBillingApiUrl('https://custom.example.com');

buildCheckoutDisplayData

Builds display data from a CheckoutSession for rendering an order summary. Matches the display logic used in checkout/CheckoutModal.

function buildCheckoutDisplayData(session: CheckoutSession): CheckoutDisplayData
ParameterTypeRequiredDescription
sessionCheckoutSessionYesThe checkout session (from useCheckout() or PaymentAPI).

Returns: CheckoutDisplayData with computed items, totals, discounts, and currency.

import { buildCheckoutDisplayData } from '@flopay/shared';
 
const display = buildCheckoutDisplayData(session);
 
display.items;          // [{ name: 'Starter', price: 24.95, originalPrice: 24.95, quantity: 1 }]
display.currency;       // 'EUR'
display.total;          // 24.95
display.originalTotal;  // 24.95
display.totalSave;      // 0
display.discountPercent; // 0

How prices are resolved

  • totalAmount is the original/base price
  • overrideAmount (when > 0) is the discounted price
  • overrideAmount of 0 or null falls through to totalAmount (e.g., a $1 trial with overrideAmount: 0 shows $1, not $0)

All amounts are in major currency units (dollars, not cents).

CheckoutDisplayData

FieldTypeDescription
itemsDisplayLineItem[]Individual items/subscriptions with names, prices, and quantities.
currencystringISO 4217 currency code (uppercase).
totalnumberTotal amount due after discounts (major units).
originalTotalnumberSum of original prices before discounts (major units).
totalSavenumberTotal savings (originalTotal - total), clamped to >= 0.
discountPercentnumberDiscount percentage (0--100).

DisplayLineItem

FieldTypeDescription
namestringItem or subscription name.
quantitynumberQuantity purchased.
pricenumberPrice per unit after discount (major units).
originalPricenumberOriginal price per unit before discount (major units).

Example: order summary

import { buildCheckoutDisplayData } from '@flopay/shared';
import { useCheckout } from '@flopay/react';
 
function OrderSummary() {
  const { session } = useCheckout();
  if (!session) return null;
 
  const { items, currency, total, totalSave, discountPercent } = buildCheckoutDisplayData(session);
  const fmt = (n: number) =>
    new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(n);
 
  return (
    <div>
      {items.map((item, i) => (
        <div key={i}>
          <span>{item.name} (x{item.quantity})</span>
          <span>{fmt(item.originalPrice)}</span>
        </div>
      ))}
      {totalSave > 0 && <div>{discountPercent}% OFF — you save {fmt(totalSave)}</div>}
      <div>Total: {fmt(total)}</div>
    </div>
  );
}

getCurrencyByCountry

Look up currency information by ISO 3166-1 alpha-2 country code. Falls back to USD when the country is not in the map.

function getCurrencyByCountry(countryCode: string): CurrencyInfo
ParameterTypeRequiredDescription
countryCodestringYesISO 3166-1 alpha-2 country code (case-insensitive).

Returns: CurrencyInfo -- the currency info for the given country, or DEFAULT_CURRENCY (USD) if not found.

import { getCurrencyByCountry } from '@flopay/shared';
 
getCurrencyByCountry('DE');
// { currency: 'EUR', symbol: '\u20ac', country: 'Germany', countryCode: 'DE', tax: 1 }
 
getCurrencyByCountry('US');
// { currency: 'USD', symbol: '$', country: 'United States', countryCode: 'US', tax: 0 }
 
getCurrencyByCountry('XX');
// Falls back to DEFAULT_CURRENCY (USD)

AVS Helpers

resolveAVSConfig

Normalizes the enableAVS prop value into a concrete AVSFieldConfig object (or null when AVS is disabled).

function resolveAVSConfig(enableAVS?: boolean | AVSFieldConfig): AVSFieldConfig | null
InputOutput
false / undefinednull
true{ country: true, postal_code: true } (the legacy default)
AVSFieldConfigThe same object, returned as-is
import { resolveAVSConfig } from '@flopay/shared';
 
resolveAVSConfig(true);                 // { country: true, postal_code: true }
resolveAVSConfig(false);                // null
resolveAVSConfig({ country: true });    // { country: true }

isAVSFieldVisible

Returns true if a given field should be visible for the given country, given a per-field rule.

function isAVSFieldVisible(
  field: boolean | string[] | undefined,
  country: string,
): boolean

Country codes are normalized (case- and whitespace-insensitive), so ['us', ' ca '] matches 'US', 'CA', 'us', etc.

import { isAVSFieldVisible } from '@flopay/shared';
 
isAVSFieldVisible(true, 'XX');              // true (always visible)
isAVSFieldVisible(false, 'US');             // false
isAVSFieldVisible(undefined, 'US');         // false
isAVSFieldVisible(['US', 'CA'], 'us');      // true
isAVSFieldVisible(['US', 'CA'], 'GB');      // false

isAVSEnabled

Returns true if any AVS field is meaningfully configured. Use this to derive the avsCheck analytics boolean from a raw enableAVS prop value.

function isAVSEnabled(enableAVS?: boolean | AVSFieldConfig): boolean
import { isAVSEnabled } from '@flopay/shared';
 
isAVSEnabled(true);                  // true
isAVSEnabled(false);                 // false
isAVSEnabled(undefined);             // false
isAVSEnabled({});                    // false  (no fields configured)
isAVSEnabled({ country: true });     // true
isAVSEnabled({ city: ['US'] });      // true

getStateOptions

Returns the list of states/provinces for a country, or null for countries that should fall back to a free-text input.

function getStateOptions(country: string): StateOption[] | null

StateOption is { code: string; name: string }. Currently returns US_STATES for 'US' and CA_PROVINCES for 'CA'; all other country codes return null.

import { getStateOptions } from '@flopay/shared';
 
getStateOptions('US');   // [{ code: 'AL', name: 'Alabama' }, …]  (51 entries incl. DC)
getStateOptions('CA');   // [{ code: 'AB', name: 'Alberta' }, …]   (13 entries)
getStateOptions('GB');   // null

getStateLabel

Returns the user-facing label for the state/province field based on country.

function getStateLabel(countryCode: string): string
CountryLabel
US'State'
CA'Province'
GB'County'
AU'State / Territory'
All others'State / Province / Region'

getStateFromPostalCode

Resolves a state / province code from a postal code for the given country.

function getStateFromPostalCode(
  country: string,
  postalCode: string,
): string | null
CountryResolution
US5-digit ZIP → 2-letter USPS state code via the 3-digit SCF prefix table. Handles ZIP+4 format.
CAA1A 1A1 → 2-letter ISO 3166-2:CA province code via the FSA first letter. X resolves to NT (shared with NU).
OthersReturns null

Used by SplitCardForm to populate billing_details.address.state when the form collects address_line_1 and postal_code but hides the state input. See the AVS guide for the trigger condition.

import { getStateFromPostalCode } from '@flopay/shared';
 
getStateFromPostalCode('US', '90210');      // 'CA'
getStateFromPostalCode('US', '10001-9999'); // 'NY' (ZIP+4)
getStateFromPostalCode('CA', 'M5V 2T6');    // 'ON'
getStateFromPostalCode('CA', 'm5v2t6');     // 'ON' (case-insensitive, compact)
getStateFromPostalCode('GB', 'SW1A 1AA');   // null
getStateFromPostalCode('US', '71500');      // null (unmapped 3-digit prefix)

getPostalCodeLabel

Returns the user-facing label for the postal code field based on country.

function getPostalCodeLabel(countryCode: string): string
CountryLabel
US'ZIP Code'
GB, AU, NZ'Postcode'
CA'Postal Code'
IE'Eircode'
All others'Postal Code'

getCountryByCode

Look up a country option by ISO 3166-1 alpha-2 code. Returns undefined if not found.

function getCountryByCode(code: string): CountryOption | undefined
import { getCountryByCode } from '@flopay/shared';
 
getCountryByCode('DE'); // { code: 'DE', name: 'Germany', flag: '🇩🇪' }
getCountryByCode('XX'); // undefined

isValidPublishableKey

Returns true if the string matches the format of a Stripe publishable key.

function isValidPublishableKey(key: string): boolean
ParameterTypeRequiredDescription
keystringYesThe key to validate.

Returns: boolean -- true if the key matches /^pk_(test|live)_[A-Za-z0-9]+$/.

import { isValidPublishableKey } from '@flopay/shared';
 
isValidPublishableKey('pk_test_abc123');  // true
isValidPublishableKey('pk_live_XYZ789'); // true
isValidPublishableKey('sk_test_abc123'); // false
isValidPublishableKey('invalid');        // false

isValidSecretKey

Returns true if the string matches the format of a Stripe secret key.

function isValidSecretKey(key: string): boolean
ParameterTypeRequiredDescription
keystringYesThe key to validate.

Returns: boolean -- true if the key matches /^sk_(test|live)_[A-Za-z0-9]+$/.

import { isValidSecretKey } from '@flopay/shared';
 
isValidSecretKey('sk_test_abc123');  // true
isValidSecretKey('sk_live_XYZ789'); // true
isValidSecretKey('pk_test_abc123'); // false