Как можно отслеживать оплату и сроки истечения подписки в системе Stripe?

Какова структура и функциональность компонентов кода, включая клиентскую часть на React и серверную часть на NestJS, которые обрабатывают процесс подписки с использованием Stripe?
  • 19 ноября 2024 г. 7:43
Ответы на вопрос 1
Для отслеживания оплаты и сроков истечения подписки в системе Stripe, вам нужно настроить соответствующие события и интегрировать клиентскую и серверную части приложения. Ниже приведен план и пример кода, который поможет реализовать процесс подписки с использованием Stripe.

### Структура проекта

- **Клиентская часть (React)**: Отправка запросов на сервер для создания и управления подписками.
- **Серверная часть (NestJS)**: Обработка логики создания, управления подписками и обработки вебхуков от Stripe.

### Серверная часть на NestJS

1. **Установите необходимые пакеты:**
   ```bash
   npm install @nestjs/common @nestjs/core @nestjs/platform-express stripe
   ```

2. **Создайте сервис для работы с Stripe:**
   ```typescript
   // stripe.service.ts
   import { Injectable } from '@nestjs/common';
   import Stripe from 'stripe';

   @Injectable()
   export class StripeService {
       private stripe: Stripe;

       constructor() {
           this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
               apiVersion: '2020-08-27',
           });
       }

       async createSubscription(customerId: string, priceId: string) {
           const subscription = await this.stripe.subscriptions.create({
               customer: customerId,
               items: [{ price: priceId }],
               expand: ['latest_invoice.payment_intent'],
           });
           return subscription;
       }

       async handleWebhook(payload: any) {
           switch (payload.type) {
               case 'invoice.payment_succeeded':
                   // Обработка успешной оплаты
                   break;
               case 'invoice.payment_failed':
                   // Обработка неудачной оплаты
                   break;
               case 'customer.subscription.updated':
                   // Обработка обновления подписки
                   break;
           }
       }
   }
   ```

3. **Создайте контроллер для обработки запросов:**
   ```typescript
   // stripe.controller.ts
   import { Controller, Post, Body, Req, Res } from '@nestjs/common';
   import { StripeService } from './stripe.service';
   import { Request, Response } from 'express';

   @Controller('stripe')
   export class StripeController {
       constructor(private readonly stripeService: StripeService) {}

       @Post('subscribe')
       async subscribe(@Body() body: { customerId: string; priceId: string }) {
           return await this.stripeService.createSubscription(body.customerId, body.priceId);
       }

       @Post('webhook')
       async webhook(@Req() req: Request, @Res() res: Response) {
           const payload = req.body;
           await this.stripeService.handleWebhook(payload);
           res.status(200).send('Received');
       }
   }
   ```

4. **Настройте маршрутизацию и обработку вебхуков в `main.ts`:**
   ```typescript
   import { NestFactory } from '@nestjs/core';
   import { AppModule } from './app.module';
   import * as express from 'express';
   import * as bodyParser from 'body-parser';

   async function bootstrap() {
       const app = await NestFactory.create(AppModule);
       app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));
       await app.listen(3000);
   }
   bootstrap();
   ```

### Клиентская часть на React

1. **Установите необходимые библиотеки:**
   ```bash
   npm install @stripe/react-stripe-js @stripe/stripe-js axios
   ```

2. **Создайте компонент для обработки подписки:**
   ```jsx
   // SubscriptionForm.js
   import React, { useState } from 'react';
   import { loadStripe } from '@stripe/stripe-js';
   import axios from 'axios';

   const stripePromise = loadStripe('your-publishable-key-here');

   const SubscriptionForm = () => {
       const [loading, setLoading] = useState(false);
       
       const handleSubscribe = async () => {
           setLoading(true);
           const stripe = await stripePromise;
           try {
               const response = await axios.post('http://localhost:3000/stripe/subscribe', {
                   customerId: 'customer-id',
                   priceId: 'price-id',
               });
               // Обработка успешной подписки
               console.log(response.data);
           } catch (error) {
               console.error('Error subscribing:', error);
           } finally {
               setLoading(false);
           }
       };

       return (
           <button onClick={handleSubscribe} disabled={loading}>
               {loading ? 'Loading...' : 'Subscribe'}
           </button>
       );
   };

   export default SubscriptionForm;
   ```

### Об
Похожие вопросы