Erstellung eines serverseitigen Checkout-Formulars mit Vue.js: Konfiguration der Checkout- Komponente

Avatar of Sarah Drasner
Sarah Drasner am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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

  1. Einrichtung und Testen
  2. Stripe-Funktion und Hosting
  3. Anwendung und Checkout-Komponente
  4. Konfiguration der Checkout-Komponente (Dieser Beitrag)

Zur Erinnerung, hier sind wir an diesem Punkt unserer Anwendung

cart and checkout

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.
    get function url
  • 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 failure und 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

success.vue in the application

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.