Project

General

Profile

Add-payments-fron-end » History » Version 9

Dmitry Vasilev, 11/21/2025 10:53 AM

1 1 Dmitry Vasilev
# Инструкция фронтенд-разработчикам
2
3
Как создавать Payment Methods через Stripe для нашего приложения
4
📌 Цель
5
6
Пассажир должен добавить свою карту, чтобы мы могли:
7
8
- безопасно сохранять карту (Stripe vault)
9
- автоматически списывать деньги после поездки (off-session)
10
- проводить SCA-подтверждение (3D-Secure)
11
12
Для этого используется SetupIntent + Stripe Elements.
13 2 Dmitry Vasilev
14 5 Dmitry Vasilev
### 1️⃣ Шаг 1. Запросить SetupIntent с бэкенда
15 3 Dmitry Vasilev
16 4 Dmitry Vasilev
**Дергаем ручку "Create setup intent object" - POST /api/payments/setup_intents**
17 2 Dmitry Vasilev
18
Получаем 
19
20
```
21
{
22
    "data": {
23
        "id": "seti_1SUmTQK65qfXWkSiVIM19pAC",
24
        "client_secret": "seti_1SUmTQK65qfXWkSiVIM19pAC_secret_TRfp4egUtC6WlqSvYDjYruElmCEFjez",
25
        "payment_method_types": [
26
            "card"
27
        ],
28
        "account_id": "0cf6a16f-6492-4190-842b-f1563e7e3d7b",
29
        "user_id": "5f0d292c-f3f7-4a2a-b129-a1d0761cfb12",
30
        "stripe_account_id": null
31
    },
32
    "status": true
33
}
34
```
35
36
client_secret нужен фронту, чтобы вызвать Stripe.confirmCardSetup().
37 6 Dmitry Vasilev
38 8 Dmitry Vasilev
---
39
40 7 Dmitry Vasilev
### 2️⃣ Шаг 2. Инициализация Stripe на фронте
41
42
```
43 6 Dmitry Vasilev
import { loadStripe } from '@stripe/stripe-js';
44
45 1 Dmitry Vasilev
const stripe = await loadStripe(PUBLIC_STRIPE_KEY);
46 7 Dmitry Vasilev
```
47 9 Dmitry Vasilev
48
---
49
50
### 3️⃣ Шаг 3. Создать Card Element и собрать данные карты
51
52
```
53
const elements = stripe.elements();
54
const cardElement = elements.create('card');
55
cardElement.mount('#card-element');
56
```
57
58
---
59
60
### 4️⃣ Шаг 4. Подтвердить SetupIntent (3D-Secure + сохранение карты)
61
62
```
63
const { setupIntent, error } = await stripe.confirmCardSetup(
64
  clientSecret,
65
  {
66
    payment_method: {
67
      card: cardElement,
68
      billing_details: {
69
        name: userFullName,
70
      },
71
    },
72
  }
73
);
74
```
75
76
Если всё ok:
77
78
setupIntent.status === "succeeded"
79
**setupIntent.payment_method  // <-- вот это нужно передать на бэкенд**
80
81
Если ошибка:
82
83
- insufficient authentication
84
- card declined
85
- 3DS failed
86
- Фронту нужно отобразить сообщение.
87
88
---
89
90
### 5️⃣ Шаг 5. Отправить payment_method на бэкенд
91
92
```
93
POST /api/payments/payment_methods
94
Content-Type: application/json
95
Authorization: Bearer <token>
96
97
{
98
  "payment_method": "pm_123456789"
99
}
100
```
101
102
Бэкенд:
103
104
- привязывает payment_method к Customer
105
- сохраняет в базе
106
- теперь карта готова к off-session оплатам