Привет 🖐🏼, в этом руководстве я покажу вам, как построить систему подписки с помощью Vue.js и Stripe. Наша рабочая среда — это Vue.js Options API, Vue Router и Express.js в качестве бэкенд-менеджера. Для UI/UX я использую Vuetify. Если вы ищете интеграцию Vue 3 Composition API и TypeScript, ознакомьтесь с моим репозиторием Subscriptions with Vue 3 and Stripe. В связи с тем, что этот учебник очень длинный, я оставляю вам ссылку на мой сайт.
Отсюда открывается лучший вид, чем отсюда.

Как построить систему подписки с помощью Stripe и Vue js | CodingPR
Узнайте, как построить систему подписки с помощью Stripe и API опций Vue js.

Если у вас нет проекта, вы можете скопировать мой здесь: vue-stripe-subscriptions
1. Настройте Stripe.
Во-первых, давайте настроим наше окружение. Скопируйте в файл env ваш публикуемый ключ stripe; вы можете найти этот ключ в разделе ‘Dashboard’ разработчика Stripe. Создайте два продукта в разделе продуктов на «Приборной панели», Базовый план за пять долларов и Премиум план за десять. Скопируйте идентификаторы продуктов в файл env.
VUE_APP_STRIPE_KEY=<YOUR-PUBLISHABLE-KEY>
VUE_APP_BASIC_PLAN=<YOUR-BASIC-PLAN>
VUE_APP_PREMIUM_PLAN=<YOUR-PREMIUM-PLAN>
- После того как вы открыли свой счет Stripe, скопируйте тег script в заголовок index.html.
<head>
<script src="https://js.stripe.com/v3/"></script>
</head>
2. Интеграция.
Нашим первым шагом по интеграции Stripe в Vue.js будет выполнение события ‘on-click’, когда клиент захочет подписаться. Мы будем собирать электронную почту и полное имя клиента; в производстве вы должны собирать дополнительную информацию, например, адрес клиента.
<v-card-actions>
<v-btn
id="stripeBtn"
class="mb-2"
block
:loading="loading"
@click="Signup"
>
Sign Up
</v-btn>
</v-card-actions>
- В следующем блоке «try and catch» мы отправляем в бэкенд личную информацию клиента, которую мы собрали в регистрационной форме. Если мы получим ответ, мы выполним план ‘view’ с идентификатором клиента в качестве параметра. О том, как настроить передачу параметров между представлениями, читайте в документации Vue Router.
// 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!'
}
}
- Создайте файл в src, задача этого файла — отправлять http-запросы на бэкенд с помощью 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;
- После получения ответа от сервера с идентификатором клиента, Vue Router запустит второй шаг; вашему клиенту нужно будет выбрать план. Создайте две кнопки с двумя разными событиями щелчка. Одна кнопка будет означать подписку на пятидолларовый план, а другая — на десятидолларовый.
<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>
- Функция ‘createSubscription’ получит параметры плана, выбранного клиентом, плюс «реквизиты» из первого шага. Эта функция отправит в бэкенд идентификатор клиента и идентификатор цены и создаст подписку; если ответные данные хороши, то будет создано «представление оформления заказа» с параметрами.
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. Сборка элемента карты Stipe.
Это последний шаг интеграции с фронтендом: установите элемент карточки и создайте событие Submit.
<!-- 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>
- Используйте секрет клиента для доступа к функции Stripe «confirmCardPayment». В этой функции передайте метод оплаты клиента и информацию для выставления счета; см. список параметров, которые вы можете отправить в stripe. Если подписка прошла успешно, будет запущено представление ‘ThankYou view’ с идентификатором подписки в качестве параметра.
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
}
})
}
}
}
}
Проверьте бэкэнд здесь: Система подписки с использованием Stripe и Express