Cree un sistema de suscripción con Vue 3, Vite y Stripe.
Por:
Denisse Abreu
oct 10, 2022 7pm ET
Eng/Spa 10-min
Hola 👋🏼, en este tutorial, te mostraré cómo crear un sistema de suscripción con Vue 3, Vite y Stripe.
Nuestro entorno de trabajo es Vue 3 con Vite, Express js y TypeScript. Para el CSS, usaré
Tailwind CSS. Si no tienes un proyecto, puedes usar mi repositorio aquí:
Suscripciones con Vue 3 y Stripe.
Si está buscando un sistema de suscripción con vue 2, consulte este tutorial:
Cree un sistema de suscripción con Stripe y Vue js.
¡Empecemos!
Configure Express js y el Typescript Server.
Comenzaremos instalando Express js y TypeScript. Si no quieres usar Express js, revisa las diferentes integraciones de servidor que tiene Stripe en su documentación de integración de suscripciones.
- Cree un nuevo directorio en su computadora y vaya a ese directorio.
Terminalmkdir vue-subscriptions cd vue-subscriptions
Cree un proyecto de Node js, use el indicador -y para crearlo sin hacer preguntas, y abre el proyecto en tu editor de código. Vaya a package.json y complete los valores vacíos.
Terminalnpm init -y code .
- Instale las librerías para el servidor Express js.
Instalar a través de npm o yarnnpm install stripe --save npm install cors dotenv express
- Instale todas las librerías relacionadas a TypeScript con el indicador -D (desarrollo).
npm install -D typescript @types/cors @types/express @types/node concurrently nodemon
- Cree el archivo de configuración de TypeScript.
Confignpx tsc --init
- Vaya al archivo tsconfig.json descomente y agregue estos valores JSON.
tsconfig.json
- Vaya a package.json y actualice los valores de los scripts.
package.json
-
Cree
index.ts
en la raíz del proyecto e inserte el siguiente código.
index.ts
-
Cree una carpeta
routes
en la raíz y dentro cree un archivostripe.ts
.
stripe.ts
- Reinicie su editor si está usando VS Code, abra su terminal nuevamente y ejecute:
Terminalnpm run build npm run dev
- Deberías ver esto 👇 en tu terminal.
Configura Vue 3 y Stripe.
En esta parte del tutorial, instalaremos e integraremos Stripe en Vue 3.
Primero, abra su terminal y ejecute npm init vue@latest
;
después de ejecutar este comando, Vue le hará algunas preguntas sobre el proyecto.
Para obtener más información sobre la instalación de Vue en su computadora, visite
Guía de inicio de Vue.
TerminalProject name: client Add TypeScript? Yes Add JSX Support? No Add Vue Router for Single Page Application development? Yes Add Pinia for state management? Yes
-
Vaya a la carpeta
client
e instale los paquetes.
Terminalcd client npm install
-
Después de instalar con éxito Vue 3, vaya a
index.html
y copie el CDN de Stripe en el encabezado del archivo (head).
index.html
Cree el archivo .env
en la raíz de la
carpeta del cliente e inserte sus claves de Stripe. si no tienes
las claves secretas de su producto o no ha creado sus planes de suscripción,
siga la Documentación de Stripe en
cómo crear su modelo de precios.
client/.envVITE_STRIPE_PUBLISHABLE_KEY= VITE_BASIC_PLAN= VITE_PREMIUM_PLAN=
-
Si tiene problemas y el servidor TypeScript no reconoce sus
variables
.env
, cree unenv.d.ts
en la raíz de la carpeta del cliente y reinicie el servidor TS.
client/env.d.ts
Integre Stripe en sus componentes Vue 3.
Nuestro primer paso para integrar Stripe a sus componentes Vue 3 es construir el formulario de registro. Recopile toda la información personal de su cliente, incluyendo su dirección física; Envíe esta información al servidor de TypeScript. Si todo está bien, recibirá una respuesta JSON del servidor con el objeto del cliente (customer object). Guarde este objeto en el 'user store' que crearemos usando Pinia. El parámetro 'rules' es el proveedor de validación Vee-Validate.
client/src/components/SignUpForm.vue
Para enviar la información personal de su cliente al servidor, necesitamos
un 'storage'. Vaya a src
y cree stores
; en el interior,
cree user.ts
. Este archivo hará la llamada al servidor
usando Axios,
almacene en el 'state' el objeto del cliente (customer object).
client/src/stores/user.ts
-
Llame a la función
SignUp()
y lance el 'plan view' con Vue Router.
client/src/components/SignUpForm.vue
Después de almacenar en el state el 'customer object', trairemos el 'plan view'. Esta plan view tendrá a cargo crear la suscripción. llame al servidor nuevamente y use Pinia para almacenar el plan que el cliente eligió, el plan id y el 'secret' del cliente que obtendremos como respuesta del servidor.
-
Vaya a la carpeta
stores
y cree un archivosubscription.ts
. inserte el siguiente código.
client/src/stores/subscription.tsimport { defineStore } from 'pinia' import axios from 'axios' interface PlanData { subscriptionId: string clientSecret: string } interface PlanChose { plan: string price: string } const url = '/stripe' export const usePlanStore = defineStore('plan', { state: () => ({ planData: {} as PlanData, planChose: {} as PlanChose }), actions: { async createSubscription( customerId: string | null, priceId: string | undefined, price: string, plan: string ) { try { const res = await axios.post(`${url}/create-subscription`, { customerId, priceId }) if (res.status === 200) { this.planData = res.data planChose = { plan, price } return this.planData } } catch (error) { throw new Error() } } } })
- Cree su plan view.
client/src/components/PlanView.vue
Traiga el 'user store' y envíe los parámetros de suscripción al 'plan store' que creamos previamente. Si la respuesta del servidor es buena, se lanzará el 'checkout view'.
client/src/components/PlanView.vue
Felicidades 🎉 esta es la parte final! Construiremos la última parte de este sistema de suscripción con Stripe. Cree un 'checkout view'; dentro de este 'checkout view', cree un formulario de pago. Este formulario estará a cargo de presentar el elemento de la tarjeta Stripe al cliente, finalizar la transacción, y activar la suscripción.
client/src/components/CheckoutForm.vue
Traiga sus 'stores' y la clave publicable de Stripe desde el expediente .env
.
Se lanzará la ruta 'thankyou' en una suscripción exitosa.
client/src/components/CheckoutForm.vueimport { ref, onMounted } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '../stores/user' import { usePlanStore } from '../stores/subscription' const userStore = useUserStore() const planStore = usePlanStore() const router = useRouter() const disabled = ref(false) const card = ref(null) const stripe = window.Stripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY) const elements = stripe.elements() const style = { base: { color: '#32325d', fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: 'antialiased', fontSize: '16px', '::placeholder': { color: '#aab7c4' } }, invalid: { color: '#fa755a', iconColor: '#fa755a' } } const el = elements.create('card', { style: style }) function displayError(event: typeof stripe) { const displayError: typeof stripe = document.getElementById('card-errors') if (event.error) { displayError.textContent = event.error.message } else { displayError.textContent = '' } } onMounted(() => { el.mount(card.value) el.on('change', (event: HTMLElement) => { displayError(event) }) }) const Submit = async () => { disabled.value = true const clientSecret = planStore.planData.clientSecret const fullName = userStore.userData.name const result = await stripe.confirmCardPayment(clientSecret, { payment_method: { type: 'card', card: el, billing_details: { name: fullName } } }) if (result.error) { disabled.value = false alert(result.error.message) } else { // Successful subscription payment // The subscription automatically becomes active upon payment. router.push({ name: 'thankyou', params: { subscription: planStore.planData.subscriptionId } }) } }
-
En caso de que el servidor TypeScript comience a arrojar errores en la función
window.Stripe()
, vaya a la carpetasrc
y declare unindex.d.ts
con el siguiente código.
client/src/index.d.tsexport {} declare global { interface Window { Stripe: Stripe } }