Hola 🖐🏼, en esta guía, te mostraré cómo crear un sistema de suscripción con Vue.js y Stripe. Nuestro entorno de trabajo es Vue.js Options API, Vue Router y Express.js como administrador de backend. Para la UI/UX, estoy usando Vuetify. Si está buscando la API de composición de Vue 3 y la integración de TypeScript, consulte este turorial Cree un sistema de suscripción con Vue 3, Vite y Stripe. Debido a lo extenso de este tutorial, les dejo el enlace a mi sitio web.
Si no tienes un proyecto, puedes copiar el mío aquí: vue-stripe-subscriptions
1. Configura Stripe.
Primero, configuremos nuestro entorno. Copie en su archivo env su clave publicable de stripe; puede encontrar esta clave en la sección del desarrollador del Stripe 'Dashboard'. Crea dos productos en la sección de productos del 'Dashboard', el plan Básico por cinco dólares y el plan Premium por diez. Copie los ID de los productos en el archivo env.
VUE_APP_STRIPE_KEY=<YOUR-PUBLISHABLE-KEY>
VUE_APP_BASIC_PLAN=<YOUR-BASIC-PLAN>
VUE_APP_PREMIUM_PLAN=<YOUR-PREMIUM-PLAN>
- Una vez que haya abierto su cuenta con Stripe , copie la etiqueta del script en el encabezado de index.html.
<head>
<script src="https://js.stripe.com/v3/"></script>
</head>
2. Integración.
Nuestro primer movimiento para integrar Stripe a Vue.js será realizando el evento 'on-click' cuando el cliente quiera suscribirse. Recopilaremos el correo electrónico y el nombre completo del cliente; en producción, debe recopilar información adicional, como la dirección del cliente.
<v-card-actions>
<v-btn
id="stripeBtn"
class="mb-2"
block
:loading="loading"
@click="Signup"
>
Sign Up
</v-btn>
</v-card-actions>
- En el siguiente bloque 'try and catch', enviamos, al backend, la información personal del cliente que recopilamos del formulario de registro. Si recibimos una respuesta, empujaremos el plan 'view' con el id del cliente como parámetro. Consulte los Vue Router Docs sobre cómo configurar el paso de parámetros entre 'views'.
// methods
import PostService from '../post-service'
async Signup() {
const { email, fullname } = this
try {
const res = await PostService.createCust(
email,
fullname
)
if (res.data.customer) {
this.$router.push({
name:'Plan',
params: {
fullName: fullname,
customerId: res.data.customer
},
props: true
})
}
} catch (error) {
this.alert1 = true;
this.alertTxt = 'Error, Try again!'
}
}
- Cree un archivo en el src, el trabajo de este archivo es enviar solicitudes http al backend con Axios.
import axios from 'axios';
const url = 'http://localhost:3000/api/posts';
class PostService {
// Crea el cliente
static async createCust(email, fullname) {
const res = await axios.post(url, {
email, fullname
});
return res;
}
// Crea la suscripción
static async createSubs(customerId, priceId) {
const res = await axios.post(`${url}/subs`, {
customerId, priceId
});
return res;
}
// Elimina la suscripción
static async delete(subscriptionId) {
const res = await axios.post(`${url}/delete`, {
subscriptionId,
});
return res;
}
}
export default PostService;
- Después de recibir la respuesta del servidor con la identificación del cliente, Vue Router impulsará el segundo paso; su cliente deberá elegir un plan. Cree dos botones con dos eventos de clic diferentes. Un botón será para suscribirse al plan de cinco dólares y la otra al plan de diez dólares.
<v-card-actions>
<v-btn
id="btnColor"
:disabled="disabled"
class="mx-auto mb-2"
@click="subsPlan1"
>
Select
</v-btn>
</v-card-actions>
<v-card-actions>
<v-btn
id="btnColor"
:disabled="disabled2"
class="mx-auto mb-2"
@click="subsPlan2"
>
Seclect
</v-btn>
</v-card-actions>
- La función 'createSubscription' recibirá los parámetros del plan que elija el cliente más los 'props' del paso uno. Esta función enviará, al backend, el id del cliente y el id del precio y creará la suscripción; Si los datos de respuesta son buenos, el 'checkout view' se impulsará con parámetros.
props: {
fullName: String,
customerId: String
},
data: () => ({
disabled: false,
disabled2: false,
alert2: false,
alertTxt: '',
}),
methods: {
async createSubscription(priceId, price, plan) {
const {fullName, customerId } = this
try {
const res = await PostService.createSubs(
customerId,
priceId,
)
if (res.data) {
const subscriptionId = res.data.subscriptionId
const clientSecret = res.data.clientSecret
this.$router.push({
name: 'Checkout',
params: {
fullName,
price,
plan,
clientSecret,
subscriptionId
}
})
}
} catch (err) {
this.alert2 = true
this.disabled = false
this.alertTxt = 'An error has occurred. Try again later'
}
},
async subsPlan1() {
const priceId = process.env.VUE_APP_BASIC_PLAN
const price = '5.00'
const plan = 'Basic'
this.disabled = true
this.disabled2 = false
await this.createSubscription(priceId, price, plan)
},
async subsPlan2() {
const priceId = process.env.VUE_APP_PREMIUM_PLAN
const price = '10.00'
const plan = 'Premium'
this.disabled2 = true
this.disabled = false
await this.createSubscription(priceId, price, plan)
}
}
3. Montaje del Stipe Card Element.
Este es el último paso de la integración frontend, monta el elemento de la tarjeta y crea el 'Submit event'.
<!-- Stripe Element-->
<div
ref="card"
class="inputCard"
/>
<!-- Mensajes de error en este espacio -->
<div
id="card-errors"
role="alert"
/>
<br>
<v-alert
v-model="alert"
color="red"
dense
dismissible
type="error"
>
<!-- alertTxt -->
</v-alert>
<v-btn
id="stripeBtn"
class="my-3"
block
:loading="loading"
@click="Submit"
>
Pay with Stripe
</v-btn>
- Utilice el secreto del cliente para acceder a la función de Stripe "confirmCardPayment". Dentro de esta función, envíe el método de pago y la información de facturación del cliente; Consulte la lista de parámetros que puede enviar a stripe. Si la suscripción es exitosa, se impulsará el 'ThankYou view' con el id de la suscripción como parámetro.
import PostService from '../post-service'
const stripe = window.Stripe(process.env.VUE_APP_STRIPE_KEY)
// Cree una instancia del Stripe Elements.
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 card = elements.create('card', { style: style })
export default {
props: {
fullName: String,
price: String,
plan: String,
clientSecret: String,
subscriptionId: String
},
mounted() {
card.mount(this.$refs.card)
card.on('change', (event) => {
this.displayError(event)
})
},
methods: {
displayError(event) {
const displayError = document.getElementById('card-errors')
if (event.error) {
displayError.textContent = event.error.message
} else {
displayError.textContent = ''
}
},
async Submit() {
this.loading = true
const { clientSecret, fullName, alert, alertTxt, loading } = this
const result = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
type: 'card',
card: card,
billing_details: {
name: fullName,
}
}
})
if (result.error) {
alert = true
alertTxt = result.error.message
loading = false
} else {
// Pago de suscripción exitoso
// La suscripción se activa automáticamente al momento del pago.
this.$router.push({
name: 'ThankYou',
params: {
subscriptionId: this.subscriptionId
}
})
}
}
}
}
Chequea el backend aquí: Sistema de suscripción con Stripe y Express
Top comments (0)