JamiDev

Storefront

Sell your JamiDev products from your own website — no secret in the browser, money straight into your Jami wallet.

The storefront SDK (jami-sdk ≥ 0.4.0) lets you sell your published products from your own site, settling money into your Jami wallet — with no API secret in the browser and no server in the middle for card checkout.

It ships two ways:

  • a drop-in <script> that exposes a JamiStore global, and
  • an importable module: import { JamiStorefront, mountStorefront } from 'jami-sdk/storefront'.

How it works

  • Hosted checkout (card): the SDK redirects the buyer to Jami's hosted checkout page for a public product token (p_…) or checkout-link token (cl_…). Nothing secret is needed, so this runs entirely in the browser.
  • Pay with Jami wallet: the SDK redirects to a small confidential server you host (walletPay) that runs the buyer's Sign in with Jami and a wallet:send. wallet:send is a confidential-client scope, so a browser can never hold it — that step needs a server.

Drop-in script

<script src="https://cdn.jsdelivr.net/npm/jami-sdk@0.4.0/dist/jami-storefront.global.js"></script>
<div id="shop"></div>
<script>
  const { JamiStorefront, mountStorefront } = window.JamiStore;

  const store = new JamiStorefront({
    // Omit walletPay to offer hosted card checkout only.
    walletPay: { endpoint: 'https://your-server.com/pay/wallet', recipient: 'yourhandle' },
  });

  // Built-in, dependency-free product grid…
  mountStorefront('#shop', {
    storefront: store,
    returnUrl: location.origin + '/thanks',
    products: [
      { token: 'p_AbC123', title: 'Leather Bag', priceEtb: 2500, image: 'https://…' },
      { token: 'p_XyZ789', title: 'Canvas Tote', priceEtb: 900,  image: 'https://…' },
    ],
  });
</script>

Get each product's public p_… token from Developer → Products (publish the product first — only published products resolve at checkout). Products are yours to supply; the storefront never calls a product-list API and never needs your token.

Your own UI

Skip mountStorefront and drive the redirects yourself:

import { JamiStorefront } from 'jami-sdk/storefront';

const store = new JamiStorefront({
  walletPay: { endpoint: 'https://your-server.com/pay/wallet', recipient: 'yourhandle' },
});

store.checkout('p_AbC123');                                   // → hosted checkout
store.payWithWallet({ amountMinor: 250000, reference: 'p_AbC123' }); // → wallet server

// Or build URLs without redirecting (e.g. for an <a href>):
store.getCheckoutUrl('cl_LinkToken', { returnUrl: 'https://shop.example/thanks' });

Amounts are integer ETB minor units (santim): 250000 = 2,500.00 ETB.

Options

new JamiStorefront({
  issuer?: string,          // default 'https://jami.bio'
  walletPay?: {
    endpoint: string,       // your confidential wallet-pay server (absolute URL)
    recipient: string,      // the receiving Jami handle or user id
  },
});

store.walletEnabled reflects whether walletPay was configured; the built-in grid only renders a wallet button when it is (and the product has a price).

Wallet-pay endpoint contract

When walletPay is set, the wallet button sends the buyer to:

GET {endpoint}?recipient=<handle>&amountMinor=<santim>&reference=<token>&return_url=<url>

Your server (a confidential OAuth client) must:

  1. Start Sign in with Jami with scope wallet:send, persisting state + the PKCE code_verifier.
  2. On the callback, exchange the code and call wallet.send to recipient for amountMinor (idempotency key advised).
  3. Record the order and redirect the buyer back to return_url (e.g. with ?status=paid).

Card checkout needs no such server — only the wallet button does.

Notes

  • Only public tokens are accepted (p_…, cl_…); raw product ObjectIds are rejected so real ids never appear in shareable URLs.
  • Redirect helpers (checkout, payWithWallet) require a browser; the URL builders (getCheckoutUrl, getWalletPayUrl) work anywhere.
  • For order fulfilment, subscribe to order.completed webhooks — hosted checkouts create JamiDev orders; wallet transfers are recorded by your wallet-pay server.

On this page