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; provideactorProvider
+connectedWallet
.plugNPlay
: theme and provider toggles for built-in wallet UX.progressBar
: choosemodal | 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.com
→https://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) — requiredapiUrl?
,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:
- Creates an ICPay payment intent flagged as
onramp_ic
and returns TransaksessionId
. - Opens Transak and listens for
TRANSAK_ORDER_SUCCESSFUL
from the iframe. - 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.