JSPM

@blaze-money/react

0.1.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 27
    • Score
      100M100P100Q78598F
    • License MIT

    React components for accepting payments with Blaze

    Package Exports

    • @blaze-money/react
    • @blaze-money/react/package.json

    Readme

    @blaze-money/react

    Drop-in React components for accepting payments with Blaze.

    npm version bundle size PCI DSS SAQ A-EP


    Quick Start

    1. Create a checkout session (server-side)

    // e.g. Next.js API route, Express handler, etc.
    const res = await fetch("https://api.blaze.money/v1/checkout/sessions", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.BLAZE_SECRET_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        amount: 2500, // cents
        currency: "USD",
        success_url: "https://yourapp.com/success",
        description: "Pro Plan — Annual",
        metadata: { user_id: "usr_abc123" },
      }),
    })
    
    const { id: sessionId } = await res.json()
    // Return sessionId to your frontend

    2. Embed the checkout (client-side)

    import { BlazeCheckout } from "@blaze-money/react"
    
    export function CheckoutPage({ sessionId }: { sessionId: string }) {
      return (
        <BlazeCheckout
          sessionId={sessionId}
          publishableKey={process.env.NEXT_PUBLIC_BLAZE_PUBLISHABLE_KEY!}
          evervaultTeamId={process.env.NEXT_PUBLIC_EVERVAULT_TEAM_ID!}
          evervaultAppId={process.env.NEXT_PUBLIC_EVERVAULT_APP_ID!}
          onComplete={(event) => {
            console.log("Payment succeeded:", event.sessionId)
            window.location.href = "/success"
          }}
          onCancel={() => window.history.back()}
          appearance={{
            theme: "night",
            variables: { colorPrimary: "#6366f1", borderRadius: "12px" },
          }}
        />
      )
    }

    That is a fully working integration. Everything else below is optional.


    Features

    • Stripe-like Appearance API — theme, variables, rules, label modes, input modes, animation toggle
    • 3 built-in themesdefault, night, flat
    • 30 appearance variables — colors, typography, spacing, border radii, shadows
    • 16 rule selectors with state variants (:focus, :hover, :disabled, :invalid, ::placeholder)
    • Floating labels mode — single toggle, no extra markup needed
    • Condensed input mode — compact layout for space-constrained UIs
    • Express checkout — Apple Pay / Google Pay with automatic device detection
    • Promo code input — apply, remove, success, and error states with async validation
    • Internationalization — 4 locales (en, es, fr, pt), 58 translated strings
    • Loading skeleton — graceful placeholder while the session loads
    • Animated success screen — confirms payment with configurable auto-redirect
    • 3DS authentication — modal overlay handled automatically
    • Card brand detection — real-time BIN matching for Visa, Mastercard, Amex, Discover
    • Analytics events — 7 event types via onEvent callback
    • onReady callback — know exactly when the form is interactive
    • Terms / consent text — configurable legal copy below the pay button
    • Full accessibility — ARIA attributes, keyboard navigation, focus trapping
    • CSS class hooks — every element has a blaze-* class for external styling
    • CDN / IIFE build — embed on Shopify, WordPress, or vanilla HTML without a bundler
    • PCI DSS SAQ A-EP compliant — card data encrypted by Evervault before touching any server
    • Output formats — CJS, ESM, IIFE, full TypeScript declarations

    Appearance API

    The appearance prop gives you full control over styling without writing CSS.

    <BlazeCheckout
      // ... required props
      appearance={{
        theme: "flat", // start from a built-in base
        variables: {
          colorPrimary: "#0066ff",
          colorBackground: "#fafafa",
          colorText: "#1a1a1a",
          fontFamily: "'Inter', sans-serif",
          borderRadius: "8px",
          spacingUnit: "14px",
        },
        rules: {
          ".Input": {
            border: "1px solid #e2e8f0",
            ":focus": { borderColor: "#0066ff", boxShadow: "0 0 0 2px rgba(0,102,255,0.15)" },
          },
          ".Button": {
            borderRadius: "8px",
            fontWeight: "600",
            textTransform: "uppercase",
          },
          ".Label": { fontSize: "13px", fontWeight: "500" },
          ".Error": { color: "#dc2626" },
        },
        labels: "floating", // "above" (default) | "floating"
        inputs: "condensed", // "default" | "condensed"
        disableAnimations: false,
      }}
    />

    See docs/themes.md for the full variable reference, all 16 rule selectors, state variants, and visual examples.


    Built-in Themes

    Theme Description
    default Clean white background, subtle borders, system font stack
    night Dark surface with light text, ideal for dark-mode apps
    flat Minimal borders, filled input backgrounds, modern flat aesthetic

    Apply a theme and override individual variables:

    appearance={{ theme: "night", variables: { colorPrimary: "#10b981" } }}

    Express Checkout

    Show Apple Pay and Google Pay buttons when available on the device:

    <BlazeCheckout
      // ... required props
      wallets={{ applePay: true, googlePay: true }}
      onWalletClick={(wallet) => {
        console.log(`User chose: ${wallet}`) // "applePay" | "googlePay"
      }}
    />

    Wallet buttons render only when the device/browser supports the payment method. No buttons appear on unsupported environments — no broken UI.


    Promo Codes

    Enable promo code entry with server-side validation:

    <BlazeCheckout
      // ... required props
      onApplyPromo={async (code) => {
        const res = await fetch(`/api/promo/validate?code=${code}`)
        const data = await res.json()
        return {
          valid: data.valid,
          discount: data.valid ? data.discount : undefined, // e.g. "20% off"
          error: data.valid ? undefined : "Invalid code",
        }
      }}
      onRemovePromo={() => {
        // User cleared the promo code
      }}
      appliedPromoCode="SUMMER20"
      appliedPromoDiscount="20% off"
    />

    Internationalization

    Pass a locale prop to render all UI strings in the target language:

    <BlazeCheckout
      // ... required props
      locale="es" // "en" | "es" | "fr" | "pt"
    />

    All 58 user-facing strings (labels, placeholders, errors, buttons, success messages) are translated. The default is "en".


    Events

    The onEvent callback fires for granular lifecycle and interaction events:

    Event Type Payload Description
    focus { field } User focused a form field
    blur { field } User left a form field
    validation_error { field, message } Client-side validation failed
    card_brand_detected { brand } Card brand identified from BIN
    submit_attempt User clicked the pay button
    form_ready Form is fully interactive
    wallet_click { wallet } User clicked a wallet button
    <BlazeCheckout
      // ... required props
      onEvent={(event) => {
        analytics.track("blaze_checkout", event)
      }}
      onReady={() => {
        console.log("Checkout form is interactive")
      }}
    />

    CDN / Non-React Usage

    For Shopify, WordPress, or any site without a React build step, use the IIFE bundle:

    <div id="blaze-checkout-root"></div>
    
    <script src="https://cdn.blaze.money/react/latest/index.iife.js"></script>
    <script>
      BlazeCheckout.render(document.getElementById("blaze-checkout-root"), {
        sessionId: "ses_abc123",
        publishableKey: "pk_live_xxx",
        evervaultTeamId: "team_xxx",
        evervaultAppId: "app_xxx",
        onComplete: function (event) {
          window.location.href = "/thank-you?session=" + event.sessionId
        },
        appearance: {
          theme: "flat",
          variables: { colorPrimary: "#e11d48" },
        },
      })
    </script>

    The IIFE build bundles React internally — no additional script tags needed.


    Advanced: Custom UI with Hooks

    For full control over markup, use the exported hooks and primitives:

    import {
      BlazeCheckoutProvider,
      useCheckoutSession,
      useCardPayment,
      CardSection,
      BillingAddressForm,
      SubmitButton,
    } from "@blaze-money/react"
    import { EvervaultProvider } from "@evervault/react"
    
    function CustomCheckout({ sessionId }: { sessionId: string }) {
      const { session, loading } = useCheckoutSession(sessionId, "https://api.blaze.money")
      const { submit, status, errorMessage } = useCardPayment({
        sessionId,
        apiUrl: "https://api.blaze.money",
        onComplete: (event) => console.log("Paid!", event.sessionId),
      })
    
      if (loading) return <p>Loading...</p>
    
      return (
        <EvervaultProvider teamId="team_xxx" appId="app_xxx">
          <form onSubmit={(e) => { e.preventDefault(); submit() }}>
            <CardSection />
            <BillingAddressForm />
            <SubmitButton status={status}>
              Pay {session?.formattedAmount}
            </SubmitButton>
            {errorMessage && <p className="error">{errorMessage}</p>}
          </form>
        </EvervaultProvider>
      )
    }

    Props Reference

    Prop Type Required Default Description
    sessionId string Yes Checkout session ID from your server
    publishableKey string Yes Blaze publishable key (pk_live_... / pk_test_...)
    evervaultTeamId string Yes Evervault team ID for card encryption
    evervaultAppId string Yes Evervault app ID for card encryption
    onComplete (event) => void Yes Called when payment succeeds
    onCancel () => void No Called when user cancels
    onError (error) => void No Called on unrecoverable error
    onEvent (event) => void No Granular lifecycle/interaction events
    onReady () => void No Called when form is fully interactive
    appearance Appearance No default theme Visual customization object
    locale "en" | "es" | "fr" | "pt" No "en" UI language
    collectAddress boolean No true Show billing address fields
    wallets { applePay?: boolean; googlePay?: boolean } No Enable express checkout buttons
    onWalletClick (wallet) => void No Called when a wallet button is clicked
    onApplyPromo (code) => Promise<{valid, discount?, error?}> No Server-side promo validation
    onRemovePromo () => void No Called when promo is cleared
    appliedPromoCode string | null No Currently applied promo code
    appliedPromoDiscount string | null No Discount description to display
    terms string | ReactNode No Legal/consent text below pay button
    apiUrl string No Production URL Override API base (for staging/dev)

    Documentation


    Security

    Card numbers and CVCs are encrypted by Evervault inside the browser before any network request leaves the page. Neither your server nor Blaze's API ever sees raw card data — only Evervault-encrypted ciphertext. This architecture qualifies you for PCI DSS SAQ A-EP, the lightest compliance level for merchants that embed payment forms.

    See docs/pci-compliance.md for the full compliance model and your responsibilities.


    License

    MIT