Auf dieser Seite
JavaScript Low-Code SDK
Einen einstellbaren Bezahl-Button auf jede Webseite bringen, Betragsquelle und Thema wählen und den Paymos-Checkout öffnen, ohne ein Backend-Formular zu bauen.
Mit dem Low-Code SDK betten Sie einen Bezahl-Button direkt auf Ihrer Website ein. Klickt die Kundschaft darauf, löst das SDK den Betrag auf, legt über Ihren öffentlichen SDK-Schlüssel (pk_...) eine Rechnung an und öffnet das Checkout-Formular — entweder als iframe-Modal oder als Weiterleitung auf eine eigene Seite.
Das Low-Code SDK ist eine bequeme Hülle um dieselbe gehostete Checkout-Seite, die POST /v1/invoices als payment_url liefert; im iframe-Modus öffnet es diesen Checkout mit ?embed=true. Den reinen Weiterleitungs- und den manuellen iframe-Vertrag beschreibt Gehosteter Checkout.
Unter der Haube sendet das SDK an https://paymos.io/public/v1/sdk — denselben Origin, der auch paymos-widget.js ausliefert — mit Ihrem Schlüssel im Header X-Sdk-Key.
Ist kein Betrag verfügbar und haben Sie eine pos_url übergeben, öffnet der Button stattdessen jene Terminal-Seite — einen Ziffernblock, auf dem der Betrag von Hand eingegeben wird. Ohne pos_url wirft ein Klick ohne auflösbaren Betrag eine Ausnahme und löst paymos:error aus.
So funktioniert es
- 01Skript des SDK und einen Einhängepunkt auf Ihre Seite setzen
- 02
PaymosWidget.mount()mitapi_key,project_idund den Optionen aufrufen - 03Die Kundschaft klickt den Button
- 04Das SDK löst den Betrag auf (fester Wert, Rückruf oder Input-Selektor)
- 05Ist ein Betrag da — das SDK legt eine Rechnung an und öffnet den Checkout
- 06Ist kein Betrag da und
pos_urlgesetzt — das SDK öffnet den Terminal-Ziffernblock unter dieser URL - 07Ist kein Betrag da und keine
pos_url— das SDK wirft eine Ausnahme und löstpaymos:erroraus - 08Die Zahlung wird verarbeitet — ein Webhook geht an Ihre eingetragene Webhook-URL
Installation
<script src="https://paymos.io/v1/paymos-widget.js"></script>
<div id="paymos-widget"></div>
Den Betrag auflösen
Das SDK löst den Zahlungsbetrag im Moment des Klicks auf und nimmt dabei die erste verfügbare Quelle:
- 01
amount— eine feste Dezimalzeichenkette in der Konfiguration. Am besten für Einzelproduktseiten oder Artikel mit festem Preis. - 02
get_amount()— eine Rückruffunktion, die den Betrag als Dezimalzeichenkette liefert. Nehmen Sie das, wenn die Summe erst berechnet wird (etwa aus einem Warenkorb). - 03
amount_selector— ein CSS-Selektor auf ein<input>-Element. Das SDK liest beim Klick dessen.value. Nützlich, wenn die Kundschaft den Betrag selbst eintippt.
Liefert keine dieser Quellen eine gültige positive Dezimalzeichenkette, öffnet das SDK das Terminal unter Ihrer pos_url — einen Ziffernblock, auf dem der Betrag von Hand eingegeben wird. Haben Sie keine pos_url gesetzt, wirft der Klick PaymosWidget requires an amount, amountSelector, or price_id. und es öffnet sich kein Checkout.
// Fixed price (price_id) — RECOMMENDED for fixed products.
// Create the price once in the dashboard; the server resolves the amount and
// currency from it, so a buyer cannot change them in DevTools. No amount in the embed.
PaymosWidget.mount('#paymos-widget', {
api_key: 'YOUR_PUBLIC_KEY',
price_id: 'price_YOUR_PRICE_ID'
});
// Fixed amount — client-supplied (editable in the browser; use for donations / free-amount)
PaymosWidget.mount('#paymos-widget', {
api_key: 'YOUR_PUBLIC_KEY',
project_id: 'prj_YOUR_PROJECT_ID',
amount: '25.00',
currency: 'USD'
});
// Dynamic amount — computed at click time
PaymosWidget.mount('#paymos-widget', {
api_key: 'YOUR_PUBLIC_KEY',
project_id: 'prj_YOUR_PROJECT_ID',
get_amount: () => calculateCartTotal().toFixed(2),
currency: 'USD'
});
// Input selector — reads value from an <input> element
PaymosWidget.mount('#paymos-widget', {
api_key: 'YOUR_PUBLIC_KEY',
project_id: 'prj_YOUR_PROJECT_ID',
amount_selector: '#donation-amount',
currency: 'USD'
});
Zwei Wege der Einbindung
Das SDK bietet zwei Einstiegspunkte. Nehmen Sie den, der zu Ihrer Seite passt:
mount(selector, opts) — das SDK zeichnet den Button
Das SDK setzt einen fertig gestalteten Bezahl-Button in das Zielelement (der Text kommt aus der Option label, voreingestellt "Support with crypto"). Am besten für Einzelproduktseiten, schlichte Landingpages und Spenden-Widgets — überall dort, wo Sie kein CSS schreiben wollen.
<script src="https://paymos.io/v1/paymos-widget.js"></script>
<div id="paymos-widget"></div>
<script>
PaymosWidget.mount('#paymos-widget', {
api_key: 'pk_live_…',
project_id: 'prj_…',
amount: '25.00',
currency: 'USD',
label: 'Support with crypto'
});
</script>
open(opts) — Sie zeichnen den Button, das SDK öffnet das Overlay
Sie behalten das DOM des Buttons vollständig in der Hand (Ihr Designsystem, Ihr CSS, Ihre Icons) und rufen aus einem Klick-Handler PaymosWidget.open(opts) auf. Am besten für Preisseiten mit mehreren Tarifen, Warenkörbe und eigene UI-Frameworks (React-, Vue-, Svelte-Komponenten).
<button id="buy-growth">Subscribe to Growth — $79/mo</button>
<script>
document.getElementById('buy-growth').addEventListener('click', function () {
PaymosWidget.open({
api_key: 'pk_live_…',
project_id: 'prj_…',
amount: 79,
currency: 'USD',
client_id: 'plan:growth'
});
});
</script>
Beide Wege sprechen dasselbe Backend an, lösen dieselben Webhooks aus und senden dieselben Fensterereignisse. Der Unterschied liegt allein darin, wer den Button gestaltet — open() ist das, was der Link Demo öffnen im Dashboard startet (eine Preisseite mit drei unabhängig gestalteten Buttons, die alle durch ein gemeinsames Overlay laufen).
Wann das SDK, wann die REST-API
Das Low-Code SDK ist ein Werkzeug für den Browser — es setzt einen Bezahl-Button auf eine statische HTML-Seite, ganz ohne Backend. Das passt hervorragend für:
- Spenden und Trinkgeld (die Kundschaft wählt den Betrag)
- Kassenabläufe, bei denen das Personal den Betrag eintippt
- Widgets mit freiem Betrag („Zahle, was es dir wert ist“)
- Interne Sandbox- und Staging-Demos
Überall dort, wo der Preis auf Ihrer Seite feststeht (Abonnements, digitale Güter, physische Bestellungen, Kurse, Lizenzen), denken Sie daran: Der Betrag steht in der Seite und lässt sich in den DevTools ändern — eine entschlossene Person kann für Ihren 99-$-Tarif 0.01 abschicken. Nutzen Sie dafür die REST-API von Ihrem Server aus, mit dem geheimen Schlüssel. Das SDK ist nicht kaputt; diese Aufteilung ist bei jedem browserseitigen Checkout dieselbe (Stripe, LemonSqueezy, PayPal): der veröffentlichbare Schlüssel in der Seite, der geheime auf dem Server.
Konfiguration
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
api_key |
string |
Ja | Öffentlicher SDK-Schlüssel aus dem Dashboard (pk_...) |
project_id |
string |
Ja, außer price_id ist gesetzt |
Projektkennung (prj_...) |
price_id |
string |
Nein | Ein im Dashboard angelegter fester Preis (price_...). Der Server löst Betrag und Währung daraus auf, sodass die Käuferseite sie nicht ändern kann — empfohlen für feste Produkte. Er hat Vorrang vor jeder Betragsquelle unten |
amount |
string | number |
Nein | Fester Zahlungsbetrag als Dezimalzeichenkette oder Zahl |
get_amount |
function |
Nein | Rückruf, der beim Klick den Betrag als Dezimalzeichenkette liefert |
amount_selector |
string |
Nein | CSS-Selektor eines Inputs mit dem Betrag |
currency |
string |
Nein | Code der Fiat-Währung (USD, EUR usw.). Voreingestellt: USD |
client_id |
string |
Nein | Ihre interne Kundenkennung (wird an die Rechnung gehängt) |
mode |
string |
Nein | "iframe" (Voreinstellung) — Modal-Overlay. "redirect" — Weiterleitung der ganzen Seite |
label |
string |
Nein | Buttontext. Voreingestellt: "Support with crypto" |
width |
string |
Nein | "auto" (Voreinstellung) oder "full" für volle Breite |
accent_color |
string |
Nein | Akzentfarbe des Buttons (Hex). Voreingestellt: #ff6b35 |
text_color |
string |
Nein | Textfarbe des Buttons (Hex). Voreingestellt: #ffffff. Die Kontrastprüfung greift nur, wenn Sie zusätzlich eine eigene accent_color übergeben: Erreicht Ihre Textfarbe dagegen 4,5, bleibt sie stehen, sonst wählt das SDK Schwarz oder Weiß nach gemessenem Kontrast. Auf der ausgelieferten Akzentfarbe entfällt die Prüfung, Ihr Wert gilt unverändert |
radius |
number |
Nein | Eckenrundung des Buttons, 0–32 px. Voreingestellt: 18 |
frame_title |
string |
Nein | Barrierefreier Titel des iframe-Elements. Voreingestellt: "Paymos checkout" |
aria_label |
string |
Nein | Barrierefreier Name des Modaldialogs. Voreingestellt: "Paymos checkout" |
pos_url |
string |
Nein | URL Ihrer Kassen- oder Terminal-Seite. Ist sie gesetzt, öffnet der Button das Terminal, wenn sich kein Betrag auflösen lässt |
target |
string |
Nein | "_self" (Voreinstellung) oder "_blank" (nur im Weiterleitungsmodus) |
auto_close_delay |
number |
Nein | Millisekunden, die der Erfolgsbildschirm sichtbar bleibt, bevor sich das Modal selbst schließt. Voreingestellt: 0 (aus). Jede Interaktion im Modal bricht den Ablauf ab. |
haptics |
boolean |
Nein | Kurzes haptisches Feedback auf Plattformen, die es unterstützen (Android, manche PWAs). iOS Safari ignoriert die Vibration API — dort passiert nichts. Beachtet prefers-reduced-motion. Voreingestellt: true |
timeout |
number |
Nein | Millisekunden, bis die Anfrage zur Rechnungserstellung abgebrochen wird. Der Wert muss positiv sein; alles andere fällt auf die Voreinstellung zurück. Voreingestellt: 30000 |
debug |
boolean |
Nein | Vollständige Error-Objekte in der Konsole ausgeben statt nur der Meldung. Voreingestellt: false |
Vollständiges Beispiel
<script src="https://paymos.io/v1/paymos-widget.js"></script>
<div id="paymos-widget"></div>
<script>
PaymosWidget.mount('#paymos-widget', {
api_key: 'YOUR_PUBLIC_KEY',
project_id: 'prj_YOUR_PROJECT_ID',
amount: '25.00',
currency: 'USD',
label: 'Support with crypto',
mode: 'iframe',
accent_color: '#FF6B35',
text_color: '#FFFFFF',
radius: 20
});
</script>
Programmatische Schnittstelle
Sie können den Checkout auch öffnen, ohne einen Button einzuhängen:
// Open checkout programmatically (no button)
await PaymosWidget.open({
api_key: 'YOUR_PUBLIC_KEY',
project_id: 'prj_YOUR_PROJECT_ID',
amount: '50.00',
currency: 'USD',
mode: 'iframe'
});
// Close the modal
PaymosWidget.close();
// Remove the button and clean up
PaymosWidget.destroy('#paymos-widget');
Ereignisse
Das SDK löst CustomEvents auf window aus, damit Ihre Seite auf den Lebenszyklus des Checkouts reagieren kann. Alle Nutzdaten liegen in event.detail.
| Ereignis | Wann es ausgelöst wird | event.detail |
|---|---|---|
paymos:opened |
Das Modal ist eingehängt und die iframe-URL gesetzt. | { url } |
paymos:closed |
Das Modal wurde entfernt (aus jedem Grund, auch wenn der optionale auto_close_delay abgelaufen ist). |
{ reason: 'escape' | 'iframe' | 'replaced' | 'api' | 'success' } |
paymos:succeeded |
Die Zahlung der Kundschaft hat paid oder paid_over erreicht. Kommt per postMessage aus dem iframe. |
{ invoiceId } |
paymos:failed |
Ein endgültiger Fehlzustand (underpaid, expired, cancelled). |
{ invoiceId, reason } |
paymos:error |
Das SDK konnte die Rechnung gar nicht erst anlegen (Netzwerk, Auth, CORS, Zeitüberschreitung). | { message } |
Die Ereignisse succeeded und failed gibt es nur im iframe-Modus — die Zahlungsseite liefert sie über window.parent.postMessage. Das SDK nimmt eine Nachricht nur vom Origin der eingebetteten Checkout-URL an und nur vom contentWindow genau dieses iframes; niemand sonst auf der Händlerseite kann sie also fälschen.
Im Weiterleitungsmodus verlässt die Seite den Browser, bevor das Ergebnis feststeht — nutzen Sie dort einen Webhook auf Ihrem Server, um die Zahlung zu bestätigen.
// 1. The customer paid — auto-close the modal and redirect to a thank-you page.
window.addEventListener('paymos:succeeded', (e) => {
console.log('Paid:', e.detail.invoiceId);
PaymosWidget.close();
// Absolute and on your own domain: a root-relative path in a published
// code sample gets crawled as one of OUR URLs — Googlebot did exactly that
// and filed /thank-you?order= as a 404 against paymos.io.
window.location.href = 'https://your-shop.example/thank-you?order=' + e.detail.invoiceId;
});
// 2. Payment failed (underpaid / expired / cancelled).
window.addEventListener('paymos:failed', (e) => {
console.warn('Payment failed:', e.detail.invoiceId, e.detail.reason);
// e.detail.reason: 'underpaid' | 'expired' | 'cancelled'
});
// 3. Modal lifecycle.
window.addEventListener('paymos:opened', (e) => console.log('Opened', e.detail.url));
window.addEventListener('paymos:closed', (e) => console.log('Closed', e.detail.reason));
// e.detail.reason: 'escape' | 'iframe' | 'replaced' | 'api' | 'success'
// 4. Invoice creation failed (network down, bad config, server error).
window.addEventListener('paymos:error', (e) => {
console.error('SDK error:', e.detail.message);
});
Allowed Origin
Das SDK arbeitet nur auf Domains, die dem Allowed Origin in Ihren Widget-Einstellungen entsprechen. Anfragen von anderen Origins werden abgewiesen.
Rückfall auf das Terminal
Der Rückfall ist ausdrücklich einzuschalten: Richten Sie pos_url auf Ihre Terminal-Seite. Lässt sich kein gültiger Betrag auflösen (kein amount, get_amount() liefert null, oder das Input hinter amount_selector ist leer), öffnet das SDK diese URL — einen Ziffernblock, auf dem der Betrag von Hand eingegeben wird. Das hilft an der Kasse, wo die Summe je Verkauf anders ausfällt.
Lassen Sie pos_url weg, wirft derselbe Fall stattdessen PaymosWidget requires an amount, amountSelector, or price_id. — auf Ihrer Seite kommt das als Ereignis paymos:error an.