Add a Pay-with-U.CASH button to Kajabi pages via Code Injection. Non-custodial: U.CASH never holds your funds, and the store Cloud token used here is publishable, so it is safe to embed directly in the browser.
Kajabi's own checkout is untouched. This snippet is for external offers, pay-what-you-want, tips, invoices, and any page where you want a standalone crypto payment button rendered from a <script> tag.
The snippet (ucashpay-button.js) renders a button that opens the hosted U.CASH pay link (https://pay.u.cash/embed.php) for an offer price. The merchant configures the store Cloud token, amount, currency, title, and optional redirect/external reference. No server is required; everything runs client-side.
For cases where you want the checkout pre-created and tracked on the U.CASH side (for example from a server route that records the order in Kajabi first), a documented server endpoint is provided below. It is optional.
ucashpay-button.js- the drop-in script. Self-initializing; readsdata-*attributes.ucashpay-button.css- optional styles. The button works without it.
-
Copy the two files (
ucashpay-button.js,ucashpay-button.css) onto a public URL (Kajabi File Library, a CDN, your own host, or this repo's raw URL). -
In Kajabi, open Settings -> Site -> Code Injection (or per-page Code Injection under Pages -> [page] -> Settings).
-
In the Header area, add:
<link rel="stylesheet" href="https://YOUR_HOST/ucashpay-button.css"> <script src="https://YOUR_HOST/ucashpay-button.js" defer></script>
-
In the Body / Footer area (or anywhere in the page body), add a button container. The simplest, declarative form uses
data-*attributes:<div data-ucashpay="st_YOUR_STORE_CLOUD_TOKEN" data-amount="25" data-currency="USD" data-title="Coaching tip" data-label="Pay with U.CASH"> </div>
On page load the snippet finds every element with a
data-ucashpayattribute and mounts a button inside it. One attribute per offer, no JavaScript required. -
Publish the page. Clicking the button opens the hosted U.CASH pay link for the configured amount and currency.
| Attribute | Required | Default | Description |
|---|---|---|---|
data-ucashpay |
yes | - | The store Cloud Token (starts with st_). Use the store-level token. |
data-amount |
no | (none) | Numeric amount. If omitted, the buyer picks an amount on the pay link. |
data-currency |
no | USD |
ISO 4217 currency code (USD, EUR, etc.). |
data-title |
no | Pay with U.CASH |
Title shown on the pay link and the U.CASH record. |
data-label |
no | Pay with U.CASH |
Visible text on the button. |
data-external-reference |
no | auto-generated | Your order/invoice ID. Reused only if you supply it. |
data-redirect |
no | current page | URL the buyer lands on after paying. |
data-target |
no | _blank |
_blank opens a new tab; _self navigates the same tab. |
data-class |
no | ucashpay-button |
CSS class for the rendered <button>. |
If you prefer JavaScript, the snippet exposes a global UcashPay object after it loads:
<script src="https://YOUR_HOST/ucashpay-button.js" defer></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
var btn = UcashPay.createButton({
cloud: 'st_YOUR_STORE_CLOUD_TOKEN',
amount: 25,
currency: 'USD',
title: 'Coaching tip',
label: 'Tip 25 USD',
external_reference: 'KAJ-OFFER-1042'
});
document.getElementById('my-tip-host').appendChild(btn);
});
</script>You can also build just the embed URL (for example to wire it into your own link):
var url = UcashPay.buildEmbedUrl({
cloud: 'st_YOUR_STORE_CLOUD_TOKEN',
amount: 25,
currency: 'USD',
title: 'Coaching tip',
external_reference: 'KAJ-OFFER-1042',
redirect: 'https://yoursite.com/thanks'
});
// url -> https://pay.u.cash/embed.php?cloud=st_...&amount=25¤cy=USD&...The button builds and opens:
GET https://pay.u.cash/embed.php
?cloud=<store Cloud Token>
&amount=<amount>
¤cy=<USD>
&title=<title>
&external_reference=<your id>
&redirect=<return url>
This uses the publishable store Cloud token, which is safe in the browser. There is no server secret involved.
For invoices or order flows where you want the checkout recorded on the U.CASH side before the buyer clicks, call the server endpoint from your own backend (never expose this from the browser if you later add account-wide secrets, though the publishable store token is safe to call with too):
POST https://pay.u.cash/payment/ajax.php
Content-Type: application/x-www-form-urlencoded
function=create-transaction
&amount=<amount>
¤cy_code=<USD>
&cryptocurrency_code=
&external_reference=<your unique order id>
&title=<title>
&redirect=<return url>
&cloud=<store Cloud Token>
&idempotent=1
The response is JSON. The payment URL is the array element that starts with http:// or https://:
{ "success": true, "response": [ "https://pay.u.cash/.../checkout", "txn_..." ] }Because idempotent=1 is set and the call is keyed on external_reference, repeated calls for the same order return the same checkout instead of creating duplicates. Redirect the buyer to that URL.
const https = require('https');
function createCheckout(opts) {
const body = new URLSearchParams({
function: 'create-transaction',
amount: String(opts.amount),
currency_code: opts.currency || 'USD',
cryptocurrency_code: '',
external_reference: opts.external_reference,
title: opts.title || 'Pay with U.CASH',
redirect: opts.redirect || '',
cloud: opts.cloud,
idempotent: '1'
}).toString();
return new Promise((resolve, reject) => {
const req = https.request({
method: 'POST',
hostname: 'pay.u.cash',
path: '/payment/ajax.php',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(body)
}
}, (res) => {
let data = '';
res.on('data', (c) => { data += c; });
res.on('end', () => {
try {
const json = JSON.parse(data);
if (!json.success) return reject(new Error('U.CASH create-transaction failed'));
const paymentUrl = (json.response || []).find((x) => /^https?:\/\//.test(x));
resolve({ paymentUrl, response: json.response });
} catch (e) { reject(e); }
});
});
req.on('error', reject);
req.write(body);
req.end();
});
}<?php
function ucashpay_create_checkout($opts) {
$payload = http_build_query([
'function' => 'create-transaction',
'amount' => $opts['amount'],
'currency_code' => $opts['currency'] ?? 'USD',
'cryptocurrency_code'=> '',
'external_reference' => $opts['external_reference'],
'title' => $opts['title'] ?? 'Pay with U.CASH',
'redirect' => $opts['redirect'] ?? '',
'cloud' => $opts['cloud'],
'idempotent' => '1',
]);
$ctx = stream_context_create(['http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $payload,
]]);
$raw = file_get_contents('https://pay.u.cash/payment/ajax.php', false, $ctx);
$json = json_decode($raw, true);
if (empty($json['success'])) {
throw new RuntimeException('U.CASH create-transaction failed');
}
$url = null;
foreach ($json['response'] as $item) {
if (is_string($item) && preg_match('#^https?://#', $item)) { $url = $item; break; }
}
return ['paymentUrl' => $url, 'response' => $json['response']];
}- Sign up at pay.u.cash, then click the verification link in the email.
- Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
- Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
- For fiat cards, connect your own Stripe under Settings -> Payment processors.
U.CASH is non-custodial: the buyer pays directly to the address you configured in your pay.u.cash store. U.CASH does not escrow or hold funds for these checkouts. The store Cloud token used by this button is publishable and intended for the browser; it can create checkouts for your store but cannot move funds or read balances.
- Kajabi's native checkout is not replaced. This snippet adds a standalone button for external offers/tips/invoices; Kajabi's product checkout flow is untouched.
- Recurring crypto billing is not supported by this integration (Kajabi handles subscriptions in its own checkout). The button is for one-time payments.
- Pricing is passed by you (
data-amount). For fully variable "pay what you want", omitdata-amountand the buyer enters an amount on the U.CASH pay link. - Browser-only is fine because the store Cloud token is publishable. The server
create-transactionendpoint is optional and only needed if you want server-side tracking/idempotency per order.
This is plain, dependency-free JavaScript. To test locally:
# serve the directory on http://localhost:8000
python3 -m http.server 8000
# then open test/preview.html in a browserThere is no build step. Minify for production if you like; the file is small.
This repo ships a package.json so the snippet can be distributed on npm. To publish a new version:
npm version patch
npm publishDo not publish automatically from CI; publish manually after testing the snippet against a real Kajabi Code Injection slot.
MIT. See LICENSE.