Embed SDK
One <script> gives you a global HashPay object and auto-wires any tagged button. The overlay renders in a Shadow DOM, so your CSS and HashPay's never collide.
The script tag
<script src="https://cdn.hashpay.dev/embed.js" data-pk="pk_live_8sd7Fk…"></script>
| Script attribute | Effect |
|---|---|
data-pk | Default publishable key for every button and checkout() call on the page. |
data-price · data-session · data-link | Auto-open checkout for that reference as soon as the script loads. |
The widget computes its API base from the script's own origin, so loading from app.hashpay.dev talks to the right API automatically — nothing else to configure.
Declarative buttons
Add one attribute to any element and it becomes a checkout trigger on click (the script wires these on load):
| Attribute | Opens checkout for… |
|---|---|
data-hashpay-price | a Price (price_…). |
data-hashpay-session | a Checkout Session (cs_…). |
data-hashpay-link | a Payment Link (plink_…). |
data-hashpay-pk | override the script-level key for this element. |
<button data-hashpay-price="price_123">Pay with crypto</button>
HashPay.checkout(options)
Open checkout from code — for SPAs, custom triggers, or session/cart flows.
| Option | Notes | |
|---|---|---|
priceId / sessionId / paymentLinkId | one required | What to charge. |
publishableKey | optional | Falls back to the script's data-pk. |
apiBase | optional | Override the API root; defaults to https://api.hashpay.dev/v1 (or the tag's data-api). |
onClose | optional | Called when the overlay is dismissed. |
onSuccess | optional | Called once when the payment reaches confirmed, with the payment object. A UX hook — fulfil from your webhook. |
onDetected | optional | Called once when funds are first seen on-chain (not yet confirmed). |
const overlay = HashPay.checkout({
priceId: 'price_123',
onClose: () => console.log('closed'),
})
overlay.close() // dismiss programmatically
checkout() throws if no key is resolvable, or if none of priceId/sessionId/paymentLinkId is given. It returns { close() }.
HashPay.wire(root?)
Re-scans root (default document) for declarative data-hashpay-* elements and wires any new ones. Call it after injecting buttons into the DOM — for example following a client-side route change.
What the widget calls
For the curious (and for debugging), the overlay talks to these public endpoints — all covered elsewhere in this reference:
POST /checkout/info— render amount, branding, optionsPOST /checkout— create the payment on chain/token selectGET /payments/{id}— poll statusPOST /payments/{id}/cancel— buyer cancelPOST /test/payments/{id}/simulate— the test-mode "mark as paid" button
onSuccess is a UX hook, not proof of payment — the browser isn't a trustworthy source of truth. Use it to update your page (show a thank-you, refresh a balance), but confirm fulfilment from your webhook, never from the widget.