Resource missing error when adding payment method for subscription - laravel

Im using laravel cashier for stripe, im creating a subscription with no card up front and 15 days trial when user registration, im following laravel cashier tutorial to add payment method for user so card can be charged when trial is over but i keep getting error
below is my controller
class BillingController extends Controller {
public function getBilling()
{
return view('dashboard.billing', [
'intent' => Auth::user()->createSetupIntent()
]);
}
}
this is my view and script
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-3">
#include('dashboard.partial.menu')
</div>
<div class="col-9">
<div class="card">
<div class="card-header">
Update Card Info
</div>
<div class="card-body">
#if(Auth::user()->subscribed() && Auth::user()->subscription('monthly')->onTrial())
<h6 class="card-title">Trial ends at: <span class="badge badge-primary">{{$diff = Carbon\Carbon::parse(Auth::user()->subscription('monthly')->trial_ends_at)->diffForHumans()}}</span></h6>
#endif
<h5>Subscription Details</h5>
<p>Monthly Membership - .99 <small>(Renews every month)</small></p>
#if (Auth::user()->hasPaymentMethod())
<h6>Card on file</h6>
<p>{{Auth::user()->card_brand}}: ending in <span class="badge badge-primary">{{Auth::user()->card_last_four}}</span></p>
#endif
<div class="form-group">
<input class="form-control" id="card-holder-name" type="text" placeholder="Cardholder name">
</div>
<!-- Stripe Elements Placeholder -->
<div id="card-element" class="form-control" style='margin-bottom: 1.5em;height: 2.4em; padding-top: .7em;'></div>
<div class="form-group">
<button class="btn btn-primary" id="card-button" data-secret="{{ $intent->client_secret }}">
Update Payment Method
</button>
</div>
</div>
</div>
</div>
</div>
</div>
#endsection #push('scripts')
window.addEventListener('load',function() { const stripe = Stripe('pk_test_xxxxxxxxxxxxxxxxxxxxxxx');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', async (e) => {
const { setupIntent, error } = await stripe.handleCardSetup(
clientSecret, cardElement, {
payment_method_data: {
billing_details: { name: cardHolderName.value }
}
}
);
if (error) {
console.log(error);
} else {
stripePaymentHandler(setupIntent);
}
});
});
#endpush
and i get this error
Object { type: "invalid_request_error", code: "resource_missing", doc_url: "https://stripe.com/docs/error-codes/resource-missing", message: "No such setupintent: seti_1FjTcII7sKb0v4gBuFe9ZZ5f", param: "intent" }

Related

Laravel Ajax Add To Cart Not working 500 internal error

I have code I am working on. I will list the page, the route, and the controller code. When I inspect and click on the add to cart button I get 500 internal server error and I cannot figure out what I did. It should be giving a message checking to see if the item is already in the cart and if not send a message saying item is in the cart but I can't get past the 500 internal server error.
Page
#extends('layouts.frontend.frontend')
#section('title')
Distinctly Mine - {{$products->name}}
#endsection
#section('content')
<div class="py-3 mb-4 shadow-sm babyblue border-top">
<div class="container">
<h6 class="mb-0">Collections / {{$products->category->name}} / {{$products->name}}</h6>
</div>
</div>
<div class="container">
<div class="card-shadow shadow-sm product_data">
<div class="card-body">
<div class="row">
<div class="col-md-4 border-right">
<div class="img-hover-zoom img-hover-zoom--xyz card-img-top">
<img src="{{ asset('backend/uploads/products/'.$products->image) }}" class="w-100 h-100" alt="{{$products->name}}">
</div>
</div>
<div class="col-md-8">
<h2 class="mb-0">{{ $products->name}}</h2>
<hr>
<label for="" class="me-3">Price: ${{$products->original_price}}</label>
<p class="mt-3">{!! $products->small_description !!}</p>
<hr>
#if($products->qty > 0)
<label for="" class="badge bg-success text-dark fw-bold">In Stock</label>
#else
<label for="" class="badge bg-danger text dark fw-bold">Out of Stock</label>
#endif
<div class="row mt-2">
<div class="col-md-2">
<input type="hidden" value="{{$products->id}}" class="prod_id">
<label for="Quantity">Quantity</label>
<div class="input-group text-center mb-3" style="width:130px">
<button type="button" class="input-group-text decrement-btn">-</button>
<input type="text" name="quantity" value="1" class="form-control qty-input" />
<button type="button" class="input-group-text increment-btn">+</button>
</div>
</div>
<div class="col-md-10">
<br />
<button type="button" class="btn btn-warning text-dark fw-bold ms-3 float-start"><i class=" me-1 fa fa-heart text-danger me-1"></i>Add To Wishlist</button>
<button type="button" class="btn btn-success ms-3 float-start text-dark fw-bold addToCartBtn"><i class="me-1 fa fa-shopping-cart text-dark me-1"></i>Add to Cart</button>
</div>
<hr>
<h2>Description</h2>
{{$products->description}}
</div>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
<script>
$(document).ready(function (){
$('.addToCartBtn').click(function (e){
e.preventDefault();
var product_id = $(this).closest('.product_data').find('.prod_id').val();
var product_qty = $(this).closest('.product_data').find('.qty-input').val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: "POST",
url: "/add-to-cart",
data: {
'product_id': product_id,
'product_qty': product_qty,
},
dataType: "dataType",
success: function (response){
alert(response.status);
}
});
});
$('.increment-btn').click(function (e){
e.preventDefault();
var inc_value = $('.qty-input').val();
var value = parseInt(inc_value,10);
value = isNaN(value) ? 0 :value;
if(value < 10)
{
value++;
$('.qty-input').val(value);
}
});
$('.decrement-btn').click(function (e){
e.preventDefault();
var dec_value = $('.qty-input').val();
var value = parseInt(dec_value,10);
value = isNaN(value) ? 0 :value;
if(value > 1)
{
value--;
$('.qty-input').val(value);
}
});
});
</script>
#endsection
Route
Route::middleware(['auth'])->group(function (){
Route::post('/add-to-cart',[CartController::class,'addProduct']);
});
Controller
<?php
namespace App\Http\Controllers\Frontend;
use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class CartController extends Controller
{
public function addProduct(Request $request)
{
$product_id = $request->input('product_id');
$product_qty = $request->input('product_qty');
if(Auth::check())
{
$prod_check = Product::where('id',$product_id)->first();
if($prod_check)
{
if(Cart::where('prod_id',$product_id)->where('user_id',Auth::id())->exists())
{
return response()->json(['status' => $prod_check->name." Already Added to cart"]);
}else{
$cartItem = new Cart();
$cartItem->prod_id = $product_id;
$cartItem->user_id = Auth::id();
$cartItem->prod_qty = $product_qty;
$cartItem->save();
return response()->json(['status'=>$prod_check->name." Added to cart"]);
}
}
}
else{
return response()->json(['status'=> "Login To Continue"]);
}
}
}

Laravel & Vue.js Form Validation Errors

I am getting a continuous validation error despite the data being valid. I originally had this forming working, at the time I was only storing one email at a time. When I added the "addNewRow" function, I was unable to post the data. Each time I get a validation error, I am quite new to Vue, and I'm not sure where I am going wrong with either the post method or my validation.
Here is my controller:
public function notifyTeam(Request $request, Agency $id)
{
$request->validate([
'email' => 'unique:users|required|email|max:255|unique:agency_emails',
]);
$user = Auth::user();
$agency = Agency::where('id', $user->agency_id)->first();
$subdomain = $agency->subdomain;
$emails = json_decode($request->getContent('emailArray'), true);
foreach($emails as $email){
$authorizedEmails = new AgencyEmail;
$authorizedEmails->email = $request->email;
$authorizedEmails->agency_id = $agency->id;
$authorizedEmails->save();
}
// Generate Link
// /{subdomain}/register
// Email the link to specified users
// vue component
return redirect()->route('dashboard');
}
And here is my Vue Component:
<template>
<div class="row justify-content-center">
<div class="col-md-4">
<div class="row justify-content-center">
</div>
<h1 class="agency_h1 mt-5 mb-5">ASSEMBLE THE TROOPS</h1>
<form method="POST" #submit.prevent="submit">
<input type="hidden" name="_token" :value="csrf">
<label for="email">E-mail Address</label>
<div class="form-group row" v-for="(field, k) in fields" :key="k">
<div class="input-group">
<input id="email" type="email" class="form-control" name="email[]" v-model="field.email"
required placeholder="Add An Email Address">
</div>
<div class="col">
<div class="alert alert-success alert-dismissible fade show sticky-top mt-2" role="alert"
v-show="success">
Emails Have Been Seent
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="alert alert-danger alert-dismissible fade show sticky-top mt-2" role="alert"
v-if="errors && errors.email">
{{ errors.email[0] }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
</div>
<button type="submit" class="btn btn-success mb-2" #click="addNewRow">Add Row +</button>
<button type="submit" class="btn btn-primary btn-block mb-5" >Create Your Agency</button>
</form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
fields: [{
email: '',
}],
errors: {},
success: false,
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
},
methods: {
addNewRow() {
this.fields.push({
email: '',
});
},
submit() {
axios.post('/create-team', {
emailArray: this.fields
})
.then(response => {
this.fields = {};
this.success = true;
this.errors = {};
})
.catch(error => {
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
console.log('Still not saved');
});
},
},
}
</script>

Default card not storing when creating Stripe subscription with Laravel Cashier

I am creating a new subscription in Stripe, using Laravel 6 and Cashier 10.7, but the default card is not storing in the Stripe customer profile. The subscription is creating fine and no errors, but the card is not storing.
My payment page controller looks like this
public function payment() {
$user = Auth::user();
if ($user->stripe_id == null) {
$user->createAsStripeCustomer();
}
return view('auth.payment', [
'intent' => $user->createSetupIntent()
]);
}
my payment blade like this
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-6 mt-5 mb-2">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
#if ($errors->any())
<div class="alert alert-danger">
<strong>Whoops!</strong> There was a problem.
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<div class="h2 text-center">
{{ __('Please enter your card details') }}
</div>
<div class="card">
<div class="card-body">
<form method="post" action="{{ route('startSubscription') }}" id="payment-form">
#csrf
<div class="group">
<label class="stripe-label">
<span class="mr-1 p-2">{{ __('Cardholder Name') }}</span>
<input id="card-holder-name" class="field" placeholder="Jordan Jones" />
</label>
</div>
<!-- Stripe Elements Placeholder -->
<div class="group">
<label class="stripe-label">
<span class="mr-1 p-2">{{ __('Card') }}</span>
<div id="card-element" class="field p-3"></div>
</label>
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
<button id="card-button" class="btn btn-lg btn-block btn-success" data-secret="{{ $intent->client_secret }}">
<i class="fas fa-credit-card mr-1"></i>{{ __('Add Payment Method') }}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('javascript')
<script>
const stripe = Stripe('pk_********');
const elements = stripe.elements();
const cardElement = elements.create('card', {hidePostalCode: true});
cardElement.mount('#card-element');
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.handleCardSetup(clientSecret, cardElement).then(function(result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
stripePaymentHandler(result.setupIntent);
}
});
});
// Submit the form with the token ID.
function stripePaymentHandler(setupIntent) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripePaymentMethod');
hiddenInput.setAttribute('value', setupIntent.payment_method);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
</script>
#endsection
and my create subscription controller like this
public function subscriptionPayment(Request $request) {
$user = Auth::user();
$paymentMethod = $request->stripePaymentMethod;
try {
$newSubscription = $user->newSubscription('Author', 'plan_HGvJkewD0eaX5Y')->trialDays(60)->create($paymentMethod, ['email' => $user->email]);
} catch ( IncompletePayment $exception ){
return redirect()->route(
'payment',
[$exception->payment->id, 'redirect' => route('home')]
);
}
return redirect()->route('home')
->with('status', 'Great! Your payment has been processed and your subscription is now active.');
}
I have tried including
if ($user->hasPaymentMethod()) {
$user->updateDefaultPaymentMethod($paymentMethod);
} else {
$user->addPaymentMethod($paymentMethod);
}
but this throws and error and I'm not sure I should need it anyway.
Any pointers would be great. Thanks.

Laravel Vue js Response Result not updating after axios call

I have vue component.After axios response counter not updating on popup. showInterest function is called on created method.
<template>
<span class="interested-button">
<a data-toggle="modal" data-target="#buyModel" #click="showInterest(idea_id, owner_id)">
<i class="fa fa-usd" aria-hidden="true"></i> Interested to buy?
</a>
<div
class="modal fade"
id="buyModel"
tabindex="-1"
role="dialog"
aria-labelledby="buyModelLabel"
aria-hidden="true"
>
<div class="modal-dialog" role="ideabuy">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="buyModelLabel">How much you are willing to spend?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{{ sharedPriceCount }}
<template v-if="sharedPriceCount == 0">
<form #submit.prevent="saveIdeaPrice">
<div class="modal-body">
<div class="form-group">
<input type="text" v-model="price" class="form-control">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
</template>
<template v-else>
<div class="modal-body">
<div class="form-group">You have already shown interest for this Idea.</div>
</div>
</template>
</div>
</div>
</div>
</span>
</template>
<script>
import mixins from "../mixins";
export default {
name: "buyProduct",
mixins: [mixins],
props: ["input_name", "idea_id", "owner_id"],
data() {
return {
result: [],
loading: false,
price: 0,
sharedPriceCount: 0
};
},
created() {},
mounted() {},
methods: {
saveIdeaPrice() {
axios
.post("/idea-buy-price", {
id: this.idea_id,
owner: this.owner_id,
price: this.price
})
.then(res => {
this.loading = false;
})
.catch(res => (this.loading = false));
},
showInterest(idea_id, owner_id) {
let _self = this;
axios
.get("/idea-buy-price/" + idea_id + "/" + owner_id)
.then(
function(response) {
_self.result = JSON.stringify(response.data.data);
_self.sharedPriceCount = response.data.data.length;
console.log(_self.sharedPriceCount);
_self.loading = false;
}.bind(_self)
)
.catch(
function(error) {
_self.loading = false;
}.bind(_self)
);
},
updateCall() {}
}
};
</script>
I am getting Array data through api call.but on popup its not working properly.I want to update this.sharedPriceCount when popup open.to show the popup content.without refreshing page.
Anyone can help me on this?
If result and loading are updated then please disregard following:
I had trouble with this. within function in axios call.
Solved it by defining
var _self = this;
before axios call and using _self within response function

Call method other component in vue

How to call method other component in Vue?
I have component HeaderSearch
<template>
<form action="">
<div class="form-group">
<div class="input-group">
<span class="input-group-btn">
<button class="btn" type="button">
<i class="fa fa-search"></i>
</button>
</span>
<input type="text" #keyup="search(keyword)" v-model="keyword" class="form-control" placeholder="Search...">
</div>
</div>
</form>
</template>
<script>
export default {
data(){
return { keyword: "" };
},
methods: {
search: function(keyword){
if(keyword == ''){
// Want call method fetchPost in PostHome component here
}else{
}
}
}
}
</script>
And I have component PostHome
<template>
<div>
<div class="box r_8 box_shadow" v-for="post in posts">
<div class="box_header">
<a :href="post.url">
<h3 class="mg_bottom_10" v-text="post.title"></h3>
</a>
<small v-text="post.description"></small>
<a :href="post.url" class="box_header_readmore">Read more</a>
</div>
<div class="box_body">
<a :href="post.url" v-show="post.thumbnail">
<img :src="post.thumbnail" class="img_responsive" style="min-height: 300px;background-color: #f1f1f1;
">
</a>
</div>
<div class="box_footer" v-show="post.tags.length > 0">
<ul>
<li v-for="tag in post.tags">
<a v-text="tag.name" href="javascript:void(0)"></a>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
posts: null,
}
},
methods: {
fetchPosts: function(){
var url = base_url + '/user/posts'
this.$http.get(url).then(res => {
this.posts = res.data;
});
}
},
created: function(){
this.fetchPosts();
}
}
</script>
I want when user type keyup to search then if
keyword == ''
call method fetchPost method in PostHome component
You can use Mixins if that method is reusable.
Reference: https://v2.vuejs.org/v2/guide/mixins.html

Resources