Quiko
Peer-to-peer package delivery. Send packages with travelers already going your route — faster, cheaper, greener.
翻譯準備中
尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
One line of HTML that sells a Loom21 product on any website: Lightning, on-chain Bitcoin and card checkout. MIT.
翻譯準備中
正在載入完整 README。
檢視完整 README ↗One line of HTML that sells a Loom21 product on any website: WordPress, Webflow, Squarespace, Ghost, a plain HTML page. Buyers pay with Lightning right on the page, or with on-chain Bitcoin or a card. The order and the stock update in Loom21 the moment it's paid.
<script src="https://app.loom21.com/embed/buy-button/v1/buy-button.js" defer></script>
<loom21-buy-button
key="l21_pk_live_7Hq2..."
product="raw-honey-500g">
</loom21-buy-button>
https://shop.example.com) to Allowed websites and copy the publishable key.The Embed dialog in Loom21 (a product's Embed button) builds the snippet for you, with a live preview.
| Attribute | Required | Default | Notes |
|---|---|---|---|
key | yes | Publishable key, l21_pk_live_… | |
product | yes | Product slug or id | |
label | no | "Buy now" / "Купи" | Button text |
quantity | no | 1 | Starting quantity |
show-quantity | no | true | Quantity stepper in the checkout, up to what one order may take |
show-price | no | true | Price under the button |
price-display | no | both | fiat, sats or both. A shop that shows only Bitcoin prices always gets sats; one that hides them always gets fiat. |
theme | no | auto | light, dark or auto (follows prefers-color-scheme) |
accent | no | Loom21 purple | Any CSS colour, for the button and highlights. The text on it is black or white, whichever is readable. |
locale | no | page language, else en | en or bg |
api-base | no | https://app.loom21.com/storefront/v1 | For a self-hosted Loom21 or staging |
Prices are shown with VAT when the shop charges it. Bitcoin amounts are indicative until the payment is opened.
Dispatched on the element (bubbles: true, composed: true), so you can listen on document:
| Event | detail |
|---|---|
loom21:open | { product } |
loom21:checkout-created | { orderNumber, total, currency } (orderNumber is null until paid) |
loom21:paid | { orderNumber, method, total, currency } |
loom21:expired | {} |
loom21:closed | { orderNumber? } |
The buyer's details are never in an event.
document.addEventListener('loom21:paid', e => {
window.location.href = '/thank-you?order=' + e.detail.orderNumber;
});
The button lives in a Shadow DOM: your page's CSS can't break it, and it can't break your page. Change it with:
loom21-buy-button {
--l21-accent: #0b7a3e; /* same as the accent attribute */
--l21-radius: 999px; /* corner radius */
--l21-font: "Inter", sans-serif;
}
loom21-buy-button::part(button) { font-size: 18px; padding: 14px 28px; }
loom21-buy-button::part(modal) { max-width: 520px; }
Parts: button (the Buy button) and modal (the checkout dialog).
GET /store, once per key per page) and the product. Out of stock shows "Sold out"; a shop that isn't taking orders shows "Currently unavailable".POST /quotes).POST /checkouts) and opens the payment:
Closing the checkout while a payment is open asks whether to cancel the order (which releases the stock) or keep it.
npm install @loom21/buy-button, then import '@loom21/buy-button' in your bundle. It defines <loom21-buy-button>.https://cdn.jsdelivr.net/npm/@loom21/buy-button@1/dist/buy-button.js.dist/buy-button.js from a release.To pin an exact version with Subresource Integrity, use the release's buy-button.js.sri:
<script src="https://app.loom21.com/embed/buy-button/v1.0.0/buy-button.js"
integrity="sha384-…" crossorigin="anonymous" defer></script>
Why does my button say "Checkout is not available on this site"?
Almost always, your website isn't in the storefront's Allowed websites list (Settings → Storefronts → Developer). Open the browser console: it says exactly which address to add, e.g. Loom21: add https://shop.example.com to Allowed websites in Settings → Storefronts → Developer. The address must match exactly, including https:// and www. if you use it. The other cause is a key that was rolled or revoked: copy the current one from the same tab.
Does it work without JavaScript? No. It's a Web Component.
Which browsers? Current Chrome, Edge, Firefox and Safari (iOS 15.4 and up).
Test mode? Not yet. Use a real product at a tiny price.
npm install
npm run demo # http://localhost:5173/demo/ with a mock API
npm test # unit tests (vitest)
npx playwright install chromium
npm run test:e2e # end-to-end tests against the mock API
npm run build # dist/, fails over 15 KB gzipped
The QR code encoder is our own (src/qr.ts), to stay within the size budget. Its tests decode every version with an independent reader (jsQR).
Storefront API reference: OpenAPI.
MIT