Sistema de suscripción con Vue 3, Vite y Stripe.

Cree un sistema de suscripción con Vue 3, Vite y Stripe.

Denisse Avatar

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.
Terminal
mkdir 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.

Terminal
npm init -y code .
  • Instale las librerías para el servidor Express js.
Instalar a través de npm o yarn
npm 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.
Config
npx 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 archivo stripe.ts.
stripe.ts
  • Reinicie su editor si está usando VS Code, abra su terminal nuevamente y ejecute:
Terminal
npm run build npm run dev
  • Deberías ver esto 👇 en tu terminal.

Terminal Concurrently

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.

Terminal
Project 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.
Terminal
cd 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/.env
VITE_STRIPE_PUBLISHABLE_KEY= VITE_BASIC_PLAN= VITE_PREMIUM_PLAN=
  • Si tiene problemas y el servidor TypeScript no reconoce sus variables .env, cree un env.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

SignUp View

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 archivo subscription.ts. inserte el siguiente código.
client/src/stores/subscription.ts
import { 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

Escoge tu Plan View

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

Checkout View

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.vue
import { 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 carpeta src y declare un index.d.ts con el siguiente código.
client/src/index.d.ts
export {} declare global { interface Window { Stripe: Stripe } }