Skip to main content

checkout.js

checkout.js (v2.1.0) is a small browser helper that connects your payment buttons to Lightning Enable's hosted checkout page. It handles the redirect UX — loading states, error callbacks, and sending the customer to the checkout URL your backend creates.

Security model
  • Prices are never passed from the client — that would let anyone edit the amount.
  • Your API key never reaches the browser. Your backend creates the payment with X-API-Key; the script only receives a checkout URL.
  • The script does not create invoices, render QR codes, or poll payment status — the hosted checkout page does that.

Architecture

Customer clicks button
→ checkout.js calls YOUR backend endpoint
→ your backend calls POST /api/payments (with your API key)
→ your backend returns { "checkoutUrl": "https://api.lightningenable.com/pay/1042" }
→ checkout.js redirects the customer to the hosted checkout page

Lightning Enable never holds funds — your payment provider (Strike or OpenNode) facilitates custody and settlement.

Quick Start

1. Include the script

<script src="https://api.lightningenable.com/checkout/v1/checkout.js"></script>

2. Create a checkout endpoint on your backend

Your endpoint creates the payment and returns the checkout URL. The hosted checkout page lives at https://api.lightningenable.com/pay/{invoiceId}.

// Node/Express example
app.post('/api/create-checkout', async (req, res) => {
const response = await fetch('https://api.lightningenable.com/api/payments', {
method: 'POST',
headers: {
'X-API-Key': process.env.LIGHTNING_ENABLE_API_KEY, // server-side only
'Content-Type': 'application/json'
},
body: JSON.stringify({
orderId: 'order-' + Date.now(),
amount: 25.00, // price from YOUR catalog — never from the client
currency: 'USD',
description: 'Premium Widget'
})
});

if (!response.ok) {
return res.status(502).json({ error: 'Could not create checkout' });
}

const payment = await response.json();
res.json({ checkoutUrl: 'https://api.lightningenable.com/pay/' + payment.invoiceId });
});

3. Add a payment button

Option A — dynamic session creation (SPAs / dynamic sites). The button calls your endpoint, then redirects:

<button data-checkout-endpoint="/api/create-checkout">Pay with Lightning</button>

Option B — pre-created checkout URL (static sites). Create the session ahead of time and link straight to it:

<button data-checkout-url="https://api.lightningenable.com/pay/1042">Pay with Lightning</button>
<!-- or skip the script entirely: -->
<a href="https://api.lightningenable.com/pay/1042">Pay with Lightning</a>

Buttons are wired up automatically when the DOM is ready — no initialization call required.

Configuration

LightningCheckout.init() is optional. Call it only to customize error handling or the redirect:

LightningCheckout.init({
onError: function (error) {
// error.message describes what failed (endpoint unreachable, missing checkoutUrl, ...)
showToast('Payment failed to start: ' + error.message);
},
onRedirect: function (url) {
// Default is window.location.href = url. Override to open in a new tab, log, etc.
window.open(url, '_blank');
}
});
OptionTypeDefaultDescription
onErrorfunction(error)console.errorCalled when session creation fails or a button is misconfigured
onRedirectfunction(url)window.location.href = urlCalled with the checkout URL to navigate to

Button attributes

AttributeApplies toDescription
data-checkout-endpointOption AYour backend endpoint that returns { "checkoutUrl": "..." }
data-checkout-methodOption AHTTP method for the endpoint call (default POST)
data-checkout-urlOption BPre-created checkout URL to redirect to
any other data-*Option ASent to your endpoint as the JSON request body — e.g. data-product-id="42" posts { "productId": "42" }

While a session is being created the button is disabled and gets the lightning-checkout-loading CSS class (dimmed, cursor: wait) — style it further if you like.

JavaScript API

LightningCheckout.init(options);                 // optional — configure callbacks
LightningCheckout.redirectToCheckout(checkoutUrl); // programmatic redirect
LightningCheckout.version; // "2.1.0"

Programmatic flow example:

async function buy(productId) {
const res = await fetch('/api/create-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ productId })
});
const { checkoutUrl } = await res.json();
LightningCheckout.redirectToCheckout(checkoutUrl);
}

Confirming payment

The hosted checkout page shows the invoice and updates when payment lands. To fulfill the order, use one of the server-side paths:

  • Webhooks (recommended): configure your callback URL and verify the X-LightningEnable-Signature header — see Webhooks.
  • Polling from your backend: GET /api/payments/{invoiceId} with your API key.
  • Browser-side UX only: the public GET /api/payments/{invoiceId}/status endpoint returns { "status": "..." } without an API key.

Included in plans

checkout.js and the hosted checkout page are available on both Agentic Commerce plans — Individual ($99/mo) and Business ($299/mo). See pricing.

Next Steps