Payhook JS

CDN

JavaScript 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.

npm

@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.

npm

CDN URLs

PathContents
/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>