Payhook JS
CDNJavaScript libraries for integrating Payhook — client-only Stripe payments for in-app feature unlocks, no license keys.
Packages
@payhook/extension
Chrome extension client. PayhookClient for hook lifecycle and entitlements, plus UpgradeButton that opens the hosted unlock page in a popup.
@payhook/unlock-button
Embeddable Stripe handoff widget for the web. Used by the hosted unlock page; can be embedded directly in any site.
CDN only@payhook/core
Shared low-level API + entitlement helpers. Pulled in transitively — clients don't install it directly.
npmCDN URLs
| Path | Contents |
|---|---|
| /extension/index.js | IIFE bundle of @payhook/extension — exposes Payhook.PayhookClient, Payhook.UpgradeButton, Payhook.createChromeAdapters. |
| /extension/styles.css | Default styles for UpgradeButton. |
| /unlock-button/index.js | IIFE bundle of @payhook/unlock-button — exposes Payhook.UnlockButton. |
Bundles are immutable per Payhook deploy; the URL above always points at the latest published version.
@payhook/extension — Chrome extension
In v0.10.0+ the upgrade UI is hosted at unlock.payhook.link. The button just opens it in a popup; plan catalog and branding come from the Payhook dashboard per Stripe-connected account.
1. manifest.json
{
"permissions": ["storage", "identity", "identity.email"],
"host_permissions": ["https://api.payhook.link/*"],
"externally_connectable": {
"matches": ["https://*.payhook.link/*"]
}
}
2. Install (npm)
npm install @payhook/extension
3. Background — init the client
import { PayhookClient, createChromeAdapters } from '@payhook/extension'
const adapters = createChromeAdapters()
export const payhook = new PayhookClient({
accountId: 'acct_xxx',
productIds: ['prod_xxx'],
...adapters
})
await payhook.init()
payhook.onEntitlementChange(({ active }) => {
// Gate premium features when active === true
})
4. Popup — mount the upgrade button
import { PayhookClient, createChromeAdapters, UpgradeButton } from '@payhook/extension'
import '@payhook/extension/upgrade-button.css'
const client = new PayhookClient({
accountId: 'acct_xxx',
productIds: ['prod_xxx'],
...createChromeAdapters()
})
await client.init()
new UpgradeButton(client, {
version: chrome.runtime.getManifest().version,
billing: { returnUrl: 'https://your.app' }
}).mount('#payhook-button')
CDN alternative (no bundler)
<link rel="stylesheet" href="https://js.payhook.link/extension/styles.css">
<div id="payhook-button"></div>
<script src="https://js.payhook.link/extension/index.js"></script>
<script>
const client = new Payhook.PayhookClient({
accountId: 'acct_xxx',
productIds: ['prod_xxx'],
...Payhook.createChromeAdapters()
})
client.init().then(() => {
new Payhook.UpgradeButton(client, {
version: chrome.runtime.getManifest().version,
billing: { returnUrl: 'https://your.app' }
}).mount('#payhook-button')
})
</script>
@payhook/unlock-button — Web embed
For non-extension web pages where you want a single-click Stripe Checkout handoff against an existing payment hook.
<div id="payhook-button"></div>
<script src="https://js.payhook.link/unlock-button/index.js"></script>
<script>
const unlock = new Payhook.UnlockButton({
paymentHookId: 'hook_xxx',
productId: 'prod_xxx',
priceId: 'price_xxx',
accountId: 'acct_xxx',
cancelUrl: location.href,
successUrl: 'https://your.app/done'
})
unlock.init('payhook-button', { email: 'user@example.com' })
</script>