Documentation Index
Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
Use this file to discover all available pages before exploring further.
Konfigurationen
Folgende Einstellungen sind relevant für die Konfiguration der Zahlungsart stripe:
Module
Folgende Module sind relevant für die Integration der Zahlungsart stripe im Bestellprozess:
- $wsStripe - stripe-Zahlungsarten Modul
- $wsCheckout - Checkout-Zustand, Adressen, Versand, Zahlung, Probleme, Summen
- $wsActions - Aktionen erzeugen und auswerten
- $wsAccount - Login-Status, E-Mail, Adressen, loadAddress()
- $wsViews - Aktuelle URL, Zielseiten, View-URLs
- $wsBasket - Warenkorb und Bestellübersicht
- $wsConfig - Konfigurationswerte, zum Beispiel Anreden und Währung
Aktionen
Folgende Aktionen sind relevant für die Integration der Zahlungsart stripe:
Folgende zusätzlichen Inhalte müssen für die Zahlungsart integriert werden.
Frontend-Integration
Stripe stellt ein eigenes JavaScript-SDK bereit, das in das Template eingebunden werden muss. Es übernimmt die Darstellung der Zahlungsfelder und die Kommunikation mit Stripe.
HTML-Struktur
Folgender HTML-Block muss im Template plaziert werden:
#wsStripePaymentElement ist der Container, in den Stripe die Zahlungsfelder (z.B. Kreditkartennummer, PayPal-Button etc.) automatisch einbettet
- Das Formular sendet beim Klick auf “Mit Stripe bezahlen” den Bezahlvorgang ab
<div id="wsStripePaymentElement">
</div>
<form method="post" action="{{= $wsViews.current.url() }}" id="wsCheckoutStripeConfirmForm">
<input type="hidden" name="wsact" value="{{= $cActionCheckoutConfirm.id }}">
<input type="hidden" name="wscsrf" value="{{= $cActionCheckoutConfirm.csrf }}">
<input type="hidden" name="wstarget" value="{{= $wsViews.viewUrl('confirm.htm') }}">
<button class="btn btn-success btn-block wsStripeOrderBtn" {{if not $wsCheckout.isValid}}disabled{{/if}}>
Mit Stripe bezahlen
</button>
</form>
JavaScript
Der folgenden Script-Block muss direkt nach dem HTML-Block eingefügt werden. Er muss in {{ autoescape “js” }} eingeschlossen sein, damit Template-Variablen im JavaScript-Kontext korrekt verarbeitet werden.
Der Ablauf im Script ist folgender:
- Stripe initialisieren - Das SDK wird mit den Zugangsdaten aus $wsStripe.configuration gestartet
- Zahlungsfelder anzeigen - Stripe rendert die Zahlungsauswahl (Kreditkarte, PayPal etc.) in den
#wsStripePaymentElement-Container. Die Adresseingabefelder von Stripe werden dabei deaktiviert, weil die Adresse des Kunden bereits im Shop bekannt ist und automatisch übergeben wird.
- Bezahlung auslösen - Beim Absenden des Formulars werden die eingegebenen Zahlungsdaten zusammen mit der Rechnungsadresse aus $wsAccount an Stripe geschickt. Stripe gibt dafür ein Confirmation-Token zurück.
- Token an den Shop senden - Das Token wird an den Shop übermittelt, der damit den eigentlichen Zahlungsvorgang bei Stripe startet.
- Ergebnis verarbeiten - Schlägt die Zahlung fehl, wird eine Fehlermeldung angezeigt. Ist eine zusätzliche Bestätigung nötig (z.B. 3D Secure), übernimmt Stripe das automatisch.
- Weiterleitung - Nach erfolgreicher Zahlung wird der Kunde zur Bestellbestätigungsseite weitergeleitet.
{{ autoescape "js" }}
<script>
{{ var $stripeConfig = $wsStripe.configuration }}
const stripe = Stripe("{{= $stripeConfig.publishableKey }}", {
stripeAccount: "{{= $stripeConfig.targetAccount }}"
});
const appearance = {
theme: 'stripe', // Aussehen anpassbar, siehe Stripe Appearance API
};
const options = {
mode: 'payment',
amount: {{= $wsCheckout.getAmountInSmallestUnit($wsCheckout.sum.total) }},
currency: '{{= lower($wsCheckout.sum.currency) }}',
paymentMethodCreation: 'manual',
appearance,
};
const elements = stripe.elements(options);
// Adresseingabefelder von Stripe deaktivieren – die Adresse wird
// weiter unten beim Absenden automatisch aus $wsAccount übergeben
const paymentElement = elements.create('payment', {
fields: {
billingDetails: {
name: 'never',
email: 'never',
phone: 'never',
address: {
line1: 'never',
line2: 'never',
city: 'never',
state: 'auto', // Bundesland ist in unseren Adressen nicht vorhanden
country: 'never',
postalCode: 'never'
}
}
}
});
paymentElement.mount("#wsStripePaymentElement");
document
.querySelector("#wsCheckoutStripeConfirmForm")
.addEventListener("submit", handleSubmit);
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
// Prüfen ob die Zahlungseingaben vollständig sind
const {error: submitError} = await elements.submit();
if (submitError) {
showMessage(submitError.message);
return;
}
// Zahlungsdaten + Rechnungsadresse an Stripe schicken,
// Stripe gibt dafür ein Confirmation Token zurück
const {error, confirmationToken} = await stripe.createConfirmationToken({
elements,
params: {
payment_method_data: {
billing_details: {
{{ foreach $addr in $wsAccount.addresses }}
{{if $addr.id==$wsCheckout.selectedBillAddress}}
address: {
city: "{{=$addr.city}}",
country: "{{=$addr.country}}",
line1: "{{=$addr.street}}",
line2: "",
postal_code: "{{=$addr.zip}}",
},
email: "{{ if $wsCheckout.guestMail }}{{= $wsCheckout.guestMail }}{{ else }}{{= $wsAccount.email }}{{ /if }}",
name: "{{=$addr.firstName}} {{=$addr.lastName}}",
phone: "{{= $addr.phone }}",
{{ /if }}
{{ /foreach }}
}
}
}
});
if (error) {
showMessage(error.message);
return;
}
// Confirmation Token an den Shop schicken, der startet damit den Zahlungsvorgang
var action = $('#confirmForm').attr('action');
var payload = $('#confirmForm').serialize();
payload += `&confirmationToken=${confirmationToken.id}`;
const response = await fetch(action, {
method: 'post',
body: payload
});
const dataContentType = response.headers.get("content-type");
if (dataContentType && !dataContentType.includes("application/json")) {
// Antwort ist kein JSON (z.B. wenn AGB nicht akzeptiert wurden) – Seite neu laden
return;
}
const data = await response.json();
const { success } = data;
if (success === false) {
// Zahlung abgelehnt – Fehlerdetails unter: https://docs.stripe.com/testing#declined-payments
const {error_code, decline_code} = data;
showMessage(`Zahlung fehlgeschlagen: ${error_code} ${decline_code}`);
setLoading(false);
return;
}
// Falls eine zusätzliche Bestätigung nötig ist (z.B. 3D Secure),
// übernimmt Stripe das automatisch
const { clientSecret, status } = data;
if (status === "requires_action") {
const { error } = await stripe.handleNextAction({ clientSecret });
if (error) {
showMessage(error.message);
setLoading(false);
return;
}
}
setLoading(false);
// Zahlung erfolgreich – zur Bestellbestätigung weiterleiten
window.location.href = "{{= $wsViews.viewUrl('confirm.htm', {wsPayment: 'stripe', stripe_action: 'return'}) }}";
}
// ------- UI-Hilfsfunktionen -------
function showMessage(messageText) {
// TODO: Fehlermeldung anzeigen
}
function setLoading(isLoading) {
let wsStripeOrderBtn = document.querySelectorAll(".wsStripeOrderBtn");
wsStripeOrderBtn.forEach(btn => btn.disabled = isLoading);
// TODO: Lade-Indikator ein-/ausblenden
}
</script>
{{ /autoescape }}
Weiterführende Links