Dies ist der vierte Beitrag einer vierteiligen Serie. In Teil Eins haben wir eine serverseitige Stripe-Funktion auf Azure eingerichtet. Teil Zwei behandelte, wie wir die Funktion auf Github gehostet haben. Der dritte Teil behandelte Stripe Elements in Vue. Dieser letzte Beitrag zeigt, wie die Checkout-Komponente konfiguriert und der Warenkorb voll funktionsfähig gemacht wird.
Artikelserie
Zur Erinnerung, hier sind wir an diesem Punkt unserer Anwendung

Konfiguration der Checkout-Komponente
Wir müssen ein paar Dinge tun, um die Komponente anzupassen, damit sie unseren Anforderungen entspricht
- Stellen Sie sicher, dass das Formular nur angezeigt wird, wenn wir es noch nicht abgeschickt haben – die Logik dafür behandeln wir gleich in unserer
pay-Methode - Ermöglichen Sie dem Formular, die E-Mail-Adresse eines Kunden abzufragen, falls es Probleme mit der Bestellung gibt.
- Deaktivieren Sie die Schaltfläche zum Absenden, bis die erforderliche E-Mail-Adresse eingegeben wurde
- Schließlich und am wichtigsten, wechseln Sie zu unserem Testschlüssel
Hier ist unsere aktualisierte checkout-Komponente mit den Änderungen am Originalcode hervorgehoben
<div v-if="!submitted" class="payment">
<h3>Please enter your payment details:</h3>
<label for="email">Email</label>
<input id="email" type="email" v-model="stripeEmail" placeholder="[email protected]"/>
<label for="card">Credit Card</label>
<p>Test using this credit card: <span class="cc-number">4242 4242 4242 4242</span>, and enter any 5 digits for the zip code</p>
<card class='stripe-card'
id="card"
:class='{ complete }'
stripe='pk_test_5ThYi0UvX3xwoNdgxxxTxxrG'
:options='stripeOptions'
@change='complete = $event.complete'
/>
<button class='pay-with-stripe' @click='pay' :disabled='!complete || !stripeEmail'>Pay with credit card</button>
</div>
Es gibt eine Reihe von Dingen, die wir für diese Komponente speichern und verwenden müssen, also fügen wir sie zu data hinzu oder importieren sie als props. Die props, die wir von unserer übergeordneten Komponente benötigen, sind total und success. Wir benötigen den total-Betrag des Kaufs, um ihn an Stripe senden zu können, und success wird etwas sein, das wir zwischen dieser Komponente und der übergeordneten Komponente koordinieren müssen, da beide Komponenten wissen müssen, ob die Zahlung erfolgreich war. Ich schreibe die Datentypen sowie einen Standardwert für meine Props auf.
props: {
total: {
type: [Number, String],
default: '50.00'
},
success: {
type: Boolean,
default: false
}
},
Als Nächstes werden die Daten, die wir speichern müssen, die stripeEmail sein, die wir aus dem Formular gesammelt haben, stripeOptions, die ich zur Anzeige belassen habe, damit Sie einige Optionen für Ihr Formular konfigurieren können, sowie status und response, die wir aus der Kommunikation mit dem Server und Stripe erhalten. Wir wollen auch speichern, ob das Formular abgeschickt wurde und ob das Formular abgeschlossen ist, um die Schaltfläche zum Absenden zu aktivieren und zu deaktivieren, beides kann ein Boolean sein.
data() {
return {
submitted: false,
complete: false,
status: '',
response: '',
stripeOptions: {
// you can configure that cc element. I liked the default, but you can
// see https://stripe.com/docs/stripe.js#element-options for details
},
stripeEmail: ''
};
},
Nun zur Magie! Wir haben alles, was wir brauchen – wir müssen nur unsere pay()-Methode ändern, die die ganze Arbeit für uns erledigt. Ich werde dafür Axios verwenden, das die Daten empfängt und transformiert
npm i axios --save
…oder mit Yarn
yarn add axios
Wenn Sie mit Axios und seinen Funktionen nicht vertraut sind, lesen Sie diesen Artikel für einige Hintergrundinformationen.
pay() {
createToken().then(data => {
this.submitted = true; // we'll change the flag to let ourselves know it was submitted
console.log(data.token); // this is a token we would use for the stripeToken below
axios
.post(
'https://sdras-stripe.azurewebsites.net/api/charge?code=zWwbn6LLqMxuyvwbWpTFXdRxFd7a27KCRCEseL7zEqbM9ijAgj1c1w==',
{
stripeEmail: this.stripeEmail, // send the email
stripeToken: data.token.id, // testing token
stripeAmt: this.total // send the amount
},
{
headers: {
'Content-Type': 'application/json'
}
}
)
.then(response => {
this.status = 'success';
this.$emit('successSubmit');
this.$store.commit('clearCartCount');
// console logs for you :)
this.response = JSON.stringify(response, null, 2);
console.log(this.response);
})
.catch(error => {
this.status = 'failure';
// console logs for you :)
this.response = 'Error: ' + JSON.stringify(error, null, 2);
console.log(this.response);
});
});
},
Der obige Code tut eine Reihe von Dingen
- Er ermöglicht uns, zu verfolgen, ob wir das Formular abgeschickt haben oder nicht, mit
this.submitted - Er verwendet Axios, um an unsere Funktion zu senden. Diese URL haben wir erhalten, indem wir im Portal zu dem Ort gegangen sind, an dem die Funktion lebt, und auf der rechten Seite des Bildschirms auf "Function URL abrufen" geklickt haben.

- Er sendet die E-Mail, den Token und den Gesamtbetrag an die serverseitige Funktion
- Wenn erfolgreich, ändert er den Status auf
success, committet zu unserem Vuex-Store, verwendet eine Mutation, um unseren Warenkorb zu leeren, und sendet ein Signal an die übergeordnete Warenkorb-Komponente, dass die Zahlung erfolgreich war. Er loggt auch die Antwort in der Konsole, dies dient jedoch zu Bildungszwecken und sollte in der Produktion gelöscht werden. - Wenn ein Fehler auftritt, ändert er den Status auf
failureund loggt die Fehlerantwort zur Fehlerbehebung
Wenn die Zahlung fehlschlägt, was wir an unserem status erkennen, müssen wir den Benutzer darüber informieren, dass etwas schief gelaufen ist, unseren Warenkorb leeren und ihn es erneut versuchen lassen. In unserem Template
<div v-if="status === 'failure'">
<h3>Oh No!</h3>
<p>Something went wrong!</p>
<button @click="clearCheckout">Please try again</button>
</div>
Die Schaltfläche ruft die folgende clearCheckout-Methode auf, die eine Reihe von Feldern löscht und es dem Kunden ermöglicht, es erneut zu versuchen
clearCheckout() {
this.submitted = false;
this.status = '';
this.complete = false;
this.response = '';
}
Wenn die Zahlung erfolgreich ist, zeigen wir eine Ladekomponente an, die eine SVG-Animation abspielt, bis wir eine Antwort vom Server erhalten. Manchmal kann dies ein paar Sekunden dauern, daher ist es wichtig, dass unsere Animation sinnvoll ist, wenn sie kurz oder lange gesehen wird, und bei Bedarf wiederholt werden kann.
<div v-else class="loadcontain">
<h4>Please hold, we're filling up your cart with goodies</h4>
<app-loader />
</div>
So sieht das aus
Siehe den Pen shop loader von Sarah Drasner (@sdras) auf CodePen.
Wenn wir nun zur ersten Warenkorb-Komponente zurückkehren, die wir in pages/cart.vue betrachtet haben, können wir diese Seite basierend auf der zuvor eingerichteten Logik füllen, da sie nun abgeschlossen ist
<div v-if="cartTotal > 0">
<h1>Cart</h1>
...
<app-checkout :total="total" @successSubmit="success = true"></app-checkout>
</div>
<div v-else-if="cartTotal === 0 && success === false" class="empty">
<h1>Cart</h1>
<h3>Your cart is empty.</h3>
<nuxt-link exact to="/"><button>Fill 'er up!</button></nuxt-link>
</div>
<div v-else>
<app-success @restartCart="success = false"/>
<h2>Success!</h2>
<p>Your order has been processed, it will be delivered shortly.</p>
</div>
Wenn wir Artikel in unserem Warenkorb haben, zeigen wir den Warenkorb an. Wenn der Warenkorb leer ist und success false ist, lassen wir sie wissen, dass ihr Warenkorb leer ist. Andernfalls, wenn die Kasse gerade abgewickelt wurde, lassen wir sie wissen, dass alles erfolgreich abgeschlossen wurde!
Hier sind wir jetzt

In der AppSuccess.vue-Komponente haben wir eine kleine SVG-Animation, die sie sich mit dem Kauf wohlfühlen lassen soll
Siehe den Pen success von Sarah Drasner (@sdras) auf CodePen.
(Sie müssen möglicherweise "Wiederholen" drücken, um die Animation erneut abzuspielen.)
Wir haben auch einen kleinen Timer im mounted() Lifecycle Hook platziert
window.setTimeout(() => this.$emit('restartCart'), 3000);
Dies zeigt den Erfolg drei Sekunden lang an, während sie ihn lesen, und startet dann den restartCart, der in der obigen Komponente gezeigt wurde. Dies ermöglicht es uns, den Warenkorb zurückzusetzen, falls sie weiter einkaufen möchten.
Fazit
Sie haben gelernt, wie man eine serverseitige Funktion erstellt, sie auf Github hostet, erforderliche Abhängigkeiten hinzufügt, mit Stripe kommuniziert, einen Warenkorb in einer Vue-Anwendung einrichtet, eine Verbindung mit der serverseitigen Funktion und Stripe herstellt und die Logik für alle Warenkorbzustaände handhabt. *Puh, gut gemacht!*
Es ist erwähnenswert, dass die Demo-App, die wir uns angesehen haben, eine Beispielanwendung ist, die speziell für diesen Tutorial-Zweck erstellt wurde. Es gibt eine Reihe von Schritten, die Sie für eine Produktionsseite durchlaufen müssten, darunter Tests, das Erstellen des dist-Ordners der Anwendung, die Verwendung echter Stripe-Schlüssel, das Senden nur des Artikels vom Client und das Hinzufügen des Preises in der serverseitigen Funktion usw. Es gibt auch so viele Möglichkeiten, dies einzurichten, serverseitige Funktionen können so flexibel in Kombination mit etwas wie Vue sein. Hoffentlich bringt Sie dies auf den richtigen Weg und spart Ihnen Zeit, wenn Sie es selbst ausprobieren.
Vielen Dank für die tolle Tutorial-Serie! Ich bin mir nicht sicher, ob dies irgendwo konfiguriert ist und ich es übersehen habe, aber ich musste die Cent-Beträge 50.00 -> 5000 verwenden, damit die Transaktionen bei Stripe angezeigt werden. Nochmals vielen Dank!
Oh, interessant! Das musste ich nicht tun, ich frage mich, was anders war. Danke, dass Sie die Leute informieren, falls sie auch auf dieses Problem stoßen.
Ich glaube, es ist nicht sicher, den Preis direkt von der Client-Seite zu senden! Sie sollten das im Fazit für Neulinge erwähnen!
Ah ja, definitiv, ich werde diesen zusätzlichen Punkt in die Einschränkungen am Ende einfügen. Danke!
Hey, toller Artikel. Aber woher wissen wir, was der Kunde gekauft hat? Sie senden nur den Betrag an Stripe. Sollte die Azure-Funktion vielleicht Artikel erhalten und in einer Datenbank speichern, damit wir die Bestellung liefern können?
Danke
Yep! Das wird in der Schlussfolgerung erwähnt :)
Eine kleine Anmerkung: NPM benötigt das Flag –save nicht mehr, um ein Paket in die Abhängigkeiten aufzunehmen.