Widget
npm install @specie/widget
import { SpecieCheckout } from "@specie/widget";
<SpecieCheckout
paymentId={payment.id}
baseUrl="https://your-deployment"
onSuccess={(p) => router.push(`/thanks?id=${p.id}`)}
/>
Why there is no amount prop
Creating a payment requires the secret API key. A widget that accepted an amount would need that key in the browser — where anyone could read it and issue payments against your account — or would let the payer choose what to pay.
So your server creates the payment with the SDK and passes the resulting id. The amount is fixed server-side and the payer cannot alter it. Same split as Stripe's PaymentIntent.
The payment id is safe to expose: it grants nothing but the ability to see and pay that one payment.
What it shows
The same checkout as the hosted page — merchant name and logo, the payer if you supplied one, the amount, your description, reference and any line items, then the two payment methods.
Set your business name and logo under Settings; they appear here automatically.
Props
| Prop | ||
|---|---|---|
paymentId | required | From payments.create |
baseUrl | Origin of your deployment | |
pollIntervalMs | 4000 | How often status refreshes |
onStatusChange | Every status transition | |
onSuccess | Once, when fully paid |
Styling
Renders inside a shadow root with its own stylesheet, so your CSS cannot break it and its CSS cannot leak into your page. Follows the system light or dark preference. No build step, CSS import, or bundler plugin.
Do not fulfil on onSuccess
onSuccess is a UI convenience. Fulfil orders from the payment.confirmed webhook, which is signed and arrives at your server. A browser callback can be forged by anyone with devtools.
Requirements
React 18 or 19. The customer needs no wallet — the widget shows a deposit address and QR they can pay from anywhere, with a link to the hosted checkout for wallet payment.