Widget

ICPay Widget is a set of framework-agnostic Web Components for payments. Drop in icpay-premium-content, icpay-tip-jar, icpay-article-paywall, icpay-coffee-shop, icpay-donation-thermometer, icpay-pay-button or icpay-amount-input to accept payments instantly. For React, wrappers are provided to use idiomatic props (e.g., onSuccess).

Intro

  • Built-in wallet flow with optional Plug N Play.
  • Uses the SDK under the hood; you can pass SDK options through the widget config.
  • Emits global events so your app can react to progress and results.

Quickstart

Usage examples

'use client'
import { IcpayTipJar, IcpaySuccess } from '@ic-pay/icpay-widget/react'

export default function Page() {
  const config = {
    publishableKey: process.env.NEXT_PUBLIC_ICPAY_PK,
    amountsUsd: [1,5,10],
    defaultAmountUsd: 5,
  }
  return (
    <IcpayTipJar
      config={config}
      onSuccess={(detail: IcpaySuccess) => console.log('Tip completed', detail)}
    />
  )
}

Create a payment

Each component exposes a config property. The widget internally creates an SDK instance and can convert USD to token amounts automatically.

Premium content examples

'use client'
import { IcpayPremiumContent, IcpaySuccess } from '@ic-pay/icpay-widget/react'

export default function Page() {
  const config = {
    publishableKey: process.env.NEXT_PUBLIC_ICPAY_PK,
    priceUsd: 5,
  }
  return (
    <IcpayPremiumContent
      config={config}
      onSuccess={(detail: IcpaySuccess) => console.log('Unlocked', detail)}
    />
  )
}

Advanced configuration

  • useOwnWallet: set to true to manage wallet connection yourself; provide actorProvider + connectedWallet.
  • plugNPlay: theme and provider toggles for built-in wallet UX.
  • progressBar: choose modal | horizontal | vertical | inline progress UI.
  • derivationOrigin: optional override for wallet derivation origin (used by Internet Identity). If omitted, the widget derives it from the current site origin and collapses subdomains to the apex domain (e.g., demo.example.comhttps://example.com).
  • showLedgerDropdown: global token selector control across widgets — 'buttons' | 'dropdown' | 'none'.
  • debug: enable verbose console logging in widget and SDK.
  • disablePaymentButton / disableAfterSuccess: disable the pay button immediately, or after a success.

Advanced configuration examples

'use client'
import { useEffect, useRef } from 'react'
import '@ic-pay/icpay-widget'

export default function Page() {
  const ref = useRef<any>(null)
  useEffect(() => {
    if (!ref.current) return
    ref.current.config = {
      publishableKey: process.env.NEXT_PUBLIC_ICPAY_PK,
      useOwnWallet: true,
      connectedWallet: { owner: '<principal>' },
      actorProvider: () => (window as any).pnp.getActor(),
      plugNPlay: { enabled: false },
      progressBar: { enabled: true, mode: 'modal' },
      theme: { primaryColor: '#0ea5e9' },
      // Optional: override derivation origin used by Internet Identity
      // By default, the widget will derive and use the apex of the current domain
      derivationOrigin: 'https://example.com',
    }
  }, [])
  return <icpay-tip-jar ref={ref as any} />
}

SDK config via widget

The widget passes a subset of options directly to the SDK:

  • publishableKey, apiUrl, icHost, actorProvider, connectedWallet.

See all SDK options in the SDK configuration.

Secret key access via server

Secret keys are never used in the widget. If you need server-only data (history, invoices, etc.), call your backend that uses the SDK with secretKey. See SDK: Secret key access.

Options reference

Common widget config (full):

  • publishableKey (string) — required
  • apiUrl?, icHost?, derivationOrigin?
  • actorProvider?, connectedWallet?, useOwnWallet?
  • plugNPlay?
    • enabled?
    • providers? { internetIdentity?: boolean; oisy?: boolean; plug?: boolean }
    • theme? { modalBackground?, modalBorderRadius?, buttonBackground?, buttonHoverBackground?, textColor?, primaryColor? }
  • theme?
    • { primaryColor?, secondaryColor?, accentColor?, textColor?, mutedTextColor?, surfaceColor?, surfaceAltColor?, borderColor?, fontFamily? }
  • debug? (boolean)
  • progressBar? { enabled?: boolean, mode?: 'modal' | 'horizontal' | 'vertical' | 'inline' }
  • disablePaymentButton? (boolean)
  • disableAfterSuccess? (boolean)
  • showLedgerDropdown? 'buttons' | 'dropdown' | 'none' — global token selector behavior
  • onrampDisabled? (boolean) — global kill switch to hide Transak card option (default: true)
  • onramp? { environment?: 'STAGING' | 'PRODUCTION'; apiKey?: string | null; width?: number|string; height?: number|string; autoOpen?: boolean; creditCardLabel?: string; enabled?: boolean } Currently disabled

Component-specific (highlights):

  • premium-content: priceUsd, imageUrl?, cryptoOptions?, defaultSymbol?, buttonLabel?, onSuccess(tx)
  • tip-jar: amountsUsd?, defaultAmountUsd?, cryptoOptions?, defaultSymbol?, buttonLabel?, onSuccess(tx)
  • article-paywall: priceUsd, title?, preview?, lockedContent?, cryptoOptions?, defaultSymbol?, buttonLabel?, onSuccess(tx)
  • coffee-shop: items[{ name, priceUsd }], defaultItemIndex?, cryptoOptions?, defaultSymbol?, buttonLabel?, onSuccess(tx)
  • donation-thermometer: goalUsd, defaultAmountUsd?, amountsUsd?, cryptoOptions?, defaultSymbol?, buttonLabel?, onSuccess(tx)

Link SDK options that also apply: SDK configuration.

Widget errors

Widgets surface SDK errors to the UI and dispatch an icpay-error event. The widget includes helpers to classify and display errors.

window.addEventListener('icpay-error', (e) => {
  console.log('Widget error', e.detail)
})

Helpers available in the widget package:

import { handleWidgetError, getErrorMessage, getErrorSeverity, getErrorAction } from '@ic-pay/icpay-widget'

Events

Widgets forward SDK events to window via CustomEvent. Subscribe globally:

window.addEventListener('icpay-sdk-transaction-created', (e) => { /* ... */ })
window.addEventListener('icpay-sdk-transaction-completed', (e) => { /* ... */ })

For the full list of event names and payloads, see SDK events.

Onramp (Transak)

All widgets expose a “Pay with credit card” action when config.onramp is set. The onramp flow:

  1. Creates an ICPay payment intent flagged as onramp_ic and returns Transak sessionId.
  2. Opens Transak and listens for TRANSAK_ORDER_SUCCESSFUL from the iframe.
  3. Closes the Transak modal on success and begins notifying ICPay until completion.

The progress bar updates the first step label to “Transak Started” with tooltip “Awaiting Transak information” during onramp.

Was this page helpful?