I’m currently working on a project that collects payment info(like the products the client wants to buy, and how much that product costs) and client details(client name, client address, client credit card info, etc.) and I need to access Stripe’s online payment system for the purchase. However, during my trial run, every time I try to click all “Pay”, I keep getting notifications that something went wrong. I checked the terminal and it keeps displaying this error:
Failed to load resource: the server responded with a status of 401 (Unauthorized)
I’m also using Django’s rest framework for my backend development, and it keeps displaying this
HTTP 401 Unauthorized
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
WWW-Authenticate: Token
{
"detail": "Authentication credentials were not provided."
}
This is the code I think the problem is located in:
<template>
<div class="page-checkout">
<div class="columns is-multiline">
<div class="column is-12">
<h1 class="title">Checkout</h1>
</div>
<div class="column is-12 box">
<table class="table is-fullwidth">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr v-for="item in cart.items" v-bind:key="item.product.id">
<td>{{ item.product.name }}</td>
<td>{{ item.product.price }}</td>
<td>{{ item.quantity }}</td>
<td>₱{{ getItemTotal(item).toFixed(2) }}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total</td>
<td>{{ cartTotalLength }}</td>
<td>₱{{ cartTotalPrice.toFixed(2) }}</td>
</tr>
</tfoot>
</table>
</div>
<div class="column is-12 box">
<h2 class="subtitle">Shipping Details</h2>
<p class="has-text-grey mb-4">* All fields required</p>
<div class="columns is-multiline">
<div class="column is-6">
<div class="field">
<label>First Name*</label>
<div class="control">
<input type="text" class="input" v-model="first_name">
</div>
</div>
<div class="field">
<label>Last Name*</label>
<div class="control">
<input type="text" class="input" v-model="last_name">
</div>
</div>
<div class="field">
<label>E-mail*</label>
<div class="control">
<input type="email" class="input" v-model="email">
</div>
</div>
<div class="field">
<label>Phone*</label>
<div class="control">
<input type="text" class="input" v-model="phone">
</div>
</div>
</div>
<div class="column is-6">
<div class="field">
<label>Address*</label>
<div class="control">
<input type="text" class="input" v-model="address">
</div>
</div>
<div class="field">
<label>Zipcode*</label>
<div class="control">
<input type="text" class="input" v-model="zipcode">
</div>
</div>
<div class="field">
<label>Place*</label>
<div class="control">
<input type="email" class="input" v-model="place">
</div>
</div>
</div>
</div>
<div class="notification is-danger mt-4" v-if="errors.length">
<p v-for="error in errors" v-bind:key="error">{{ error }}</p>
</div>
<hr>
<div id="card-element" class="mb-5"></div>
<template v-if="cartTotalLength">
<hr>
<button class="button is-dark" @click="submitForm">Pay with Stripe</button>
</template>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: "Checkout",
data() {
return {
cart: {
items: []
},
stripe: {},
card: {},
first_name: '',
last_name: '',
email: '',
phone: '',
address: '',
zipcode: '',
place: '',
errors: []
}
},
mounted() {
document.title = ' The "GO BUY IT" page | Bjackets '
this.cart = this.$store.state.cart
if (this.cartTotalLength > 0) {
this.stripe = Stripe('pk_test_51L3bhzFMIo7cZ677WbW384hMgVFcLs9E0x4sLocwajtGbnZIlplXoWSlSKr1IM89tWOCFYIBOWPpcF8OzBWGCnZR00MN1fPAGW')
const elements = this.stripe.elements();
this.card = elements.create('card', { hidePostalCode: true })
this.card.mount('#card-element')
}
},
methods: {
getItemTotal(item) {
return item.quantity * item.product.price
},
submitForm() {
this.errors = []
if (this.first_name === '') {
this.errors.push('The First Name feild is empty. Please fill-out the space with your first name. For example, "Gaylord"')
}
if (this.last_name === '') {
this.errors.push('The Last Name feild is empty. Please fill-out the space with your last name. For example, "Gaylord"')
}
if (this.email === '') {
this.errors.push('The email feild is missing. Please fill-out the space with your email. For example, "[email protected]"')
}
if (this.phone === '') {
this.errors.push('The phone feild is missing. Please fill-out the space with your contact number. For example, "123-456-7890"')
}
if (this.address === '') {
this.errors.push('The address feild is missing. Please fill-out the space with your address. In other words, tell me where you live.')
}
if (this.zipcode === '') {
this.errors.push('The zipcode feild is missing.')
}
if (this.place === '') {
this.errors.push('Are you located in Lozun, Visayas, Mindanao?')
}
if (!this.errors.length) {
this.$store.commit('setIsLoading', true)
this.stripe.createToken(this.card).then(result => {
if (result.error) {
this.$store.commit('setIsLoading', false)
this.errors.push('Something went wrong with Stripe. Please try again')
console.log(result.error.message)
} else {
this.stripeTokenHandler(result.token)
}
})
}
},
async stripeTokenHandler(token) {
const items = []
for (let i = 0; i < this.cart.items.length; i++) {
const item = this.cart.items[i]
const obj = {
product: item.product.id,
quantity: item.quantity,
price: item.product.price * item.quantity
}
items.push(obj)
}
const data = {
'first_name': this.first_name,
'last_name': this.last_name,
'email': this.email,
'address': this.address,
'zipcode': this.zipcode,
'place': this.place,
'phone': this.phone,
'items': items,
'stripe_token': token.id
}
await axios
.post('/api/v1/checkout/', data)
.then(response => {
this.$store.commit('clearCart')
this.$router.push('/cart/success')
})
.catch(error => {
this.errors.push('Something went wrong. Please try again')
console.log(error)
})
this.$store.commit('setIsLoading', false)
}
},
computed: {
cartTotalPrice() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.product.price * curVal.quantity
}, 0)
},
cartTotalLength() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.quantity
}, 0)
},
}
}
</script>