Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

boyjarv's avatar

Help required setting up stripe subscription in Vue

I Need help setting up stripe subscription payments from Vue to Laravel. I have setup Laravel Cashier and I have a product in my stripe dev account I need help passing this from Vue to Laravel, making the payment and recording the data in the users table and other tables that cashier created on migrate. I can pay for someone to do this for me, please DM me

0 likes
3 replies
martinbean's avatar

@boyjarv You’ll get much more attention on your posts if you post more information.

Show code. Show what you’ve actually attempted, and explain what isn’t working.

Also, no one can DM you as this forum doesn’t have DM functionality from what I can see.

boyjarv's avatar

ok so I have setup Cashier in my Laravel Project and installed stripe-php, I have not yet setup any controllers for stripe. I have a users table with additional columns for stripe. I added Billable trait to my User model:

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Cashier\Billable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable, Billable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'client_id',
        'first_name',
        'last_name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];

    public function client()
    {
        return $this->belongsTo(Client::class);
    }
}

I have added the following code in config/services.php

'stripe' => [
        'model' => App\User::class,
        'key' => env('STRIPE_KEY'),
        'secret' => env('STRIPE_SECRET'),
    ],

I have added API keys to my EN file:

STRIPE_KEY=pk_test_xxx
STRIPE_SECRET=sk_test_xxx
CASHIER_CURRENCTY=gbp
CASHIER_MODEL=App\User

In my Vue project I have a register page and can register users, I have added stripe-js, here is my Register component in Vue:

<template>
  <div id="register">
    <TopNavigation />
    <div class="w-full p-6 flex justify-center items-center">
      <div class="w-full max-w-xs">
        <div class="bg-gray-600 p-8 shadow rounded mb-6">
          <h1 class="mb-6 text-lg text-gray-100 font-thing">
            Let's get rocking
          </h1>
          <div class="mb-4">
            <SelectInput
              label="Client"
              :labelColor="false"
              :options="transformedOptions"
              placeholder="Please select"
              v-model:input="clientId"
              :error="errors.client_id ? errors.client_id[0] : ''"
            />
          </div>  
          <div class="mb-4">
            <TextInput
              label="First Name"
              :labelColor="false"
              placeholder="John"
              v-model:input="firstName"
              inputType="text"
              :error="errors.first_name ? errors.first_name[0] : ''"
            />
          </div>
          <div class="mb-4">
            <TextInput
              label="Last Name"
              :labelColor="false"
              placeholder="John"
              v-model:input="lastName"
              inputType="text"
              :error="errors.last_name ? errors.last_name[0] : ''"
            />
          </div>
          <div class="mb-4">
            <TextInput
              label="Email"
              :labelColor="false"
              placeholder="[email protected]"
              v-model:input="email"
              inputType="text"
              :error="errors.email ? errors.email[0] : ''"
            />
          </div>
          <div class="mb-4">
            <TextInput
              label="Password"
              :labelColor="false"
              placeholder="john123456"
              v-model:input="password"
              inputType="password"
              :error="errors.password ? errors.password[0] : ''"
            />
          </div>
          <div class="mb-4">
            <TextInput
              label="Confirm Password"
              :labelColor="false"
              placeholder="john123456"
              v-model:input="confirmPassword"
              inputType="password"
            />
          </div>
          
          <label>
            Card Number
            <div id="card-element" ref="cardElement"></div>
          </label>
                    
          <button
            class="block w-full bg-green-500 text-white rounded-sm py-3 text-sm tracking-wide"
            type="submit"
            @click="register"
          >
            Register
          </button>
        </div>

        <p class="text-center text-md text-gray-900">
          Already have an account?...
          <router-link
            class="text-blue-500 no-underline hover:underline"
            to="/login"
          >
            Login
          </router-link>
        </p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { loadStripe } from '@stripe/stripe-js';
import { ref, onMounted, computed } from "vue";
import { useUserStore } from '../store/UserStore';
import { useClientStore } from '../store/ClientStore';
import { useProfileStore } from '../store/ProfileStore';
import { usePostStore } from '../store/PostStore';
import { useRouter } from 'vue-router';
import TextInput from "@/components/global/TextInput.vue";
import SelectInput from "@/components/global/SelectInput.vue";
import axios from "axios";
import TopNavigation from "@/components/structure/TopNavigation.vue";

const userStore = useUserStore();
const clientStore = useClientStore();
const router = useRouter();
const profileStore = useProfileStore();
const postStore = usePostStore();

let errors = ref([]);
let clientId = ref(null);
let firstName = ref(null);
let lastName = ref(null);
let email = ref(null);
let password = ref(null);
let confirmPassword = ref(null);
let clients = ref([]);
let stripe = ref(null); // Declare stripe as a reactive property
let cardElement = ref(null);

let transformedOptions = computed(() => {
  return clients.value.map(client => ({
    value: client.id,
    label: client.name
  }));
});

onMounted(async () => {
  await clientStore.fetchClients();
  clients.value = clientStore.clients;

  stripe.value = await initializeStripe(); // Assign the initialized stripe value

  const elements = stripe.value.elements(); // Get the Stripe elements instance

  // Create the card element and mount it to the DOM
  const card = elements.create('card');
  card.mount('#card-element');

  cardElement.value = card; // Store the card element reference in the reactive property
});


const initializeStripe = async () => {
  const stripe = await loadStripe('pk_test_51LGnwdH8B3O205oeNawhEVgb4g7R3iFEQjPk25ScCUvq0jYgv46VQCDH2tpDnJW08WYdjYzXNvDZYLB2oDUjavWd0044IrAwxH'); // Replace with your Stripe publishable key
  return stripe;
}

const register = async () => {
  errors.value = [];

  try {
    let res = await axios.post('api/register', {
      client_id: clientId.value,
      first_name: firstName.value,
      last_name: lastName.value,
      email: email.value,
      password: password.value,
      password_confirmation: confirmPassword.value,
    });

    axios.defaults.headers.common['Authorization'] = 'Bearer ' + res.data.token;
    userStore.setUserDetails(res);
    await profileStore.fetchProfileById(userStore.id);
    await postStore.fetchPostsByUserId(userStore.id);

    const stripeInstance = await initializeStripe();

    const { error, paymentMethod } = await stripeInstance.createPaymentMethod({
      type: 'card',
      card: cardElement.value, // Obtain the card element reference from the DOM
    });

    if (error) {
      console.error('Failed to create payment method:', error);
    } else {
      // Payment method is created, you can now send the payment method ID to your Laravel app for further processing
      const paymentMethodId = paymentMethod.id;
      console.log(paymentMethodId);
      // Send the paymentMethodId to your Laravel backend for further processing (e.g., with an API request)
    }

    router.push('/account/profile/' + userStore.id);
  } catch (err) {
    errors.value = err.response.data.errors;
  }
};

</script>

Here is what my register form looks like: https://ibb.co/QfL1dMQ

I can see a form field to put in my card details, when I fill in fake card details, I can register a new user still but no order has gone to Stripe.

I have setup a stripe product which is a subscription product of £6 per month an dI have a productID but I don't know what to do with it and how to get this into Laravel and orders coming in?! please help

Please or to participate in this conversation.