Dies ist der dritte Teil einer vierteiligen Serie. In Teil eins haben wir eine serverlose Stripe-Funktion auf Azure eingerichtet. Teil zwei behandelte, wie wir die Funktion auf Github gehostet haben. Dieser Beitrag konzentriert sich auf die Verknüpfung von allem als Vue.js-Anwendung.
Artikelserie
Stripe bietet eine Reihe von Möglichkeiten, ein Checkout-Formular zu erstellen. Die grundlegendste ist ein einzelner Button auf der Seite, den Sie auslösen, um das benutzerdefinierte Modal von Stripe anzuzeigen. Es gibt ein Repository und eine Komponente dafür, aber so einfach die Implementierung auch ist (es ist wahrscheinlich die einfachste Art, es zu tun), ich wollte etwas mehr Anpassung und der Checkout-Ablauf sollte Teil der Seite und der Anwendung sein. Dieser Ansatz wäre für meine Bedürfnisse nicht geeignet.
Stripe Elements
Stripe bietet auch etwas namens Elements an. Elements ermöglicht es Ihnen, das Zahlungssystem von Stripe in Ihr eigenes Checkout-Formular zu integrieren und es wie Ihre eigene Website zu gestalten, um ein kohärentes Erlebnis zu erzielen. Es wird sich nicht anfühlen, als würden Sie ein Drittanbieter-Plugin verwenden. Es gibt einige vorgestaltete Beispiele, wenn Sie etwas bevorzugen, das Sie sofort verwenden können.
Glücklicherweise gibt es ein wirklich schönes Repository mit einer Vue-Version von Stripe Elements namens vue-stripe-elements. Die Dokumentation des Repositorys ist sehr gut, daher können Sie diese gerne durchlesen. Hier ist, wie ich es verwendet habe
npm i vue-stripe-elements-plus --save
...oder mit Yarn
yarn add vue-stripe-elements-plus
Sprechen wir nun über unseren Warenkorb und integrieren ihn.
Der Warenkorb
Hier sehen wir, wie die Anwendung aus der Vogelperspektive aussieht. Wir haben uns bereits mit der Funktion und den Stripe-Teilen befasst, nun tauchen wir in die Anwendung selbst ein.

Wir werden in diesen Beiträgen nicht die Einrichtung der gesamten Anwendung behandeln, sondern nur den Warenkorb und den Checkout. Ich empfehle, die folgenden Links zu überprüfen, bevor Sie fortfahren, falls Sie die Grundlagen von Vue, Vuex und Nuxt nachholen müssen.
- CSS-Tricks Vue-Leitfaden
- Einfaches serverseitiges Rendering, Routing und Seitenübergänge mit Nuxt.js
In unserem allgemeinen mit Vuex eingerichteten Store halten wir ein Verzeichnis mit all unseren Produktdaten, die zur Befüllung der Seiten mit Artikeln verwendet werden. Wir werden diese Informationen auch verwenden, um ein (derzeit leeres) Warenkorb-Objekt zu befüllen, in das Artikel zum Kauf hinzugefügt werden können. Wir werden diese Daten auf einer Seite namens `Cart.vue` im Seitenverzeichnis verwenden. Wenn Sie mit Nuxt.js nicht vertraut sind, können wir damit `.vue`-Komponenten als Seiten verwenden, indem wir sie in diesem Seitenverzeichnis erstellen. Wir können diese Seiten weiterhin mit Komponenten aus dem Komponentenverzeichnis befüllen, um eine modularere Anwendung zu erstellen. Hier sind die Teile, die wir jetzt besprechen

Wir benötigen zwei Informationen aus diesem Store in Vuex: den Inhalt des cart und den cartTotal.
Wir werden berechnete Eigenschaften in pages/Cart.vue verwenden, um diese Informationen abzurufen, damit wir sie zwischenspeichern und im Warenkorb verwenden können.
computed: {
cart() {
return this.$store.state.cart;
},
cartTotal() {
return this.$store.state.cartTotal;
},
...
}
...und wir werden eine neue berechnete Eigenschaft erstellen, die den monetären Gesamtbetrag der Artikel im Warenkorb speichert
computed: {
...
total() {
return Object.values(this.cart)
.reduce((acc, el) => acc + (el.count * el.price), 0)
.toFixed(2);
}
}
Das Erste, was wir tun werden, ist zu prüfen, ob der Warenkorb Artikel enthält. Wenn ja, müssen wir prüfen, ob die Zahlung noch nicht verarbeitet wurde. Dies müssen wir tun, da es keinen Sinn hat, ein Checkout-Formular anzuzeigen, wenn sich keine Artikel im Warenkorb befinden oder wenn die Zahlung für die hinzugefügten Artikel bereits verarbeitet wurde.
<div v-if="cartTotal > 0">
<!--we'll add our checkout here-->
</div>
<!--If the cart is empty, give them the ability to get back to the main page to add items-->
<div v-else-if="cartTotal === 0 && success === false" class="empty">
<!--we'll add our empty state here-->
</div>
<!--If there's a success, let's let people know it's being processed, we'll add a success component later on-->
<div v-else>
<!--we'll add success here-->
</div>
Wir werden auch eine `success`-Eigenschaft in unseren Daten erstellen, die wir anfangs auf false setzen und später verwenden werden, um aufzuzeichnen, ob eine Zahlung erfolgreich übermittelt wurde oder nicht.
data() {
return {
success: false
};
},
Wir möchten die Warenkorbartikel anzeigen, wenn sie existieren, ihre einzelnen Gesamtbeträge (da wir mehrere Exemplare desselben Artikels haben können) und den Endbetrag.
<div v-if="cartTotal > 0">
<h1>Cart</h1>
<div class="cartitems"
v-for="item in cart"
key="item">
<div class="carttext">
<h4>{{ item.name }}</h4>
<p>{{ item.price | usdollar }} x {{ item.count }}</p>
<p>Total for this item: <strong>{{ item.price * item.count }}</strong></p>
</div>
<img class="cartimg" :src="`/${item.img}`" :alt="`Image of ${item.name}`">
</div>
<div class="total">
<h3>Total: {{ total | usdollar }}</h3>
</div>
<!--we're going to add our checkout here-->
</div>
Wir verwenden einen Filter, um die Preise in US-Dollar zu formatieren. Ich formatiere sie auf diese Weise, anstatt sie fest zu codieren, falls ich in Zukunft andere Währungen unterstützen muss.
filters: {
usdollar: function(value) {
return `$${value}`;
}
}
Einrichtung der Checkout-Komponente
Nun erstellen wir unsere checkout-Komponente, die die gesamte Checkout-Logik von Stripe enthalten und sich mit der serverlosen Funktion verbinden wird, die wir in Teil Zwei eingerichtet haben. Wir werden die Komponente in der Datei Cart.vue registrieren.
import AppCheckout from './../components/AppCheckout.vue';
export default {
components: {
AppCheckout
},
...
}
Hier sind wir jetzt

Und in der checkout-Komponente selbst bringen wir die Basis für die Datei mit, die wir in der Dokumentation des vue-stripe-elements-Repositorys gesehen haben.
<template>
<div id='app'>
<h1>Please give us your payment details:</h1>
<card class='stripe-card'
:class='{ complete }'
stripe='pk_test_XXXXXXXXXXXXXXXXXXXXXXXX'
:options='stripeOptions'
@change='complete = $event.complete'
/>
<button class='pay-with-stripe' @click='pay' :disabled='!complete'>Pay with credit card</button>
</div>
</template>
<script>
import { stripeKey, stripeOptions } from './stripeConfig.json'
import { Card, createToken } from 'vue-stripe-elements-plus'
export default {
data () {
return {
complete: false,
stripeOptions: {
// see https://stripe.com/docs/stripe.js#element-options for details
}
}
},
components: { Card },
methods: {
pay () {
// createToken returns a Promise which resolves in a result object with
// either a token or an error key.
// See https://stripe.com/docs/api#tokens for the token object.
// See https://stripe.com/docs/api#errors for the error object.
// More general https://stripe.com/docs/stripe.js#stripe-create-token.
createToken().then(data => console.log(data.token))
}
}
}
</script>
Als Nächstes…
Bisher sieht die Komponente so aus, wie sie ist. Wir werden diese Komponente etwas an unsere Bedürfnisse anpassen müssen, aber nicht zu sehr. Bleiben Sie dran für die letzte Folge morgen, wenn wir unsere Komponente mit unserer serverlosen Funktion verbinden und den Checkout abschließen!