@stripe-sdk/core 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -261
- package/dist/client/index.d.mts +0 -4
- package/dist/client/index.d.ts +0 -4
- package/dist/client/index.js +70 -11
- package/dist/client/index.mjs +71 -12
- package/dist/{index-D8rM_YD4.d.mts → index-BKDJf1Hz.d.mts} +1 -27
- package/dist/{index-D8rM_YD4.d.ts → index-BKDJf1Hz.d.ts} +1 -27
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +601 -231
- package/dist/index.mjs +602 -232
- package/dist/next/index.d.mts +55 -32
- package/dist/next/index.d.ts +55 -32
- package/dist/next/index.js +362 -143
- package/dist/next/index.mjs +362 -143
- package/dist/server/index.d.mts +61 -21
- package/dist/server/index.d.ts +61 -21
- package/dist/server/index.js +546 -237
- package/dist/server/index.mjs +546 -237
- package/dist/server/webhooks/index.d.mts +1 -1
- package/dist/server/webhooks/index.d.ts +1 -1
- package/dist/server/webhooks/index.js +19 -7
- package/dist/server/webhooks/index.mjs +19 -7
- package/package.json +8 -5
- package/dist/client/index.js.map +0 -1
- package/dist/client/index.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/next/index.js.map +0 -1
- package/dist/next/index.mjs.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/index.mjs.map +0 -1
- package/dist/server/webhooks/index.js.map +0 -1
- package/dist/server/webhooks/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @stripe-sdk/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A **turnkey** Stripe SDK for your applications. Integrate payments, subscriptions, invoices, webhooks, marketplace and more in just a few lines. Compatible with React, Next.js, Vue, Angular and any JavaScript framework.
|
|
4
|
+
|
|
5
|
+
**[Documentation: English](docs/en/) | [Documentation: Francais](docs/fr/)**
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -8,9 +10,11 @@ SDK Stripe **cle en main** pour vos applications. Integrez les paiements, abonne
|
|
|
8
10
|
npm install @stripe-sdk/core stripe @stripe/stripe-js @stripe/react-stripe-js
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
> For server-only usage (no React), you only need: `npm install @stripe-sdk/core stripe`
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
12
16
|
|
|
13
|
-
### 1. Variables
|
|
17
|
+
### 1. Environment Variables
|
|
14
18
|
|
|
15
19
|
```env
|
|
16
20
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
@@ -18,7 +22,7 @@ STRIPE_SECRET_KEY=sk_test_...
|
|
|
18
22
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
### 2.
|
|
25
|
+
### 2. Server Initialization
|
|
22
26
|
|
|
23
27
|
```ts
|
|
24
28
|
// lib/stripe.ts
|
|
@@ -33,22 +37,22 @@ export const stripe = initStripe({
|
|
|
33
37
|
|
|
34
38
|
---
|
|
35
39
|
|
|
36
|
-
##
|
|
40
|
+
## Payments
|
|
37
41
|
|
|
38
|
-
###
|
|
42
|
+
### Simple Payment with Built-in Form
|
|
39
43
|
|
|
40
|
-
**
|
|
44
|
+
**Server** - Create a PaymentIntent:
|
|
41
45
|
|
|
42
46
|
```ts
|
|
43
47
|
// app/api/create-payment/route.ts
|
|
44
|
-
import '@/lib/stripe';
|
|
48
|
+
import '@/lib/stripe';
|
|
45
49
|
import { createPaymentIntent } from '@stripe-sdk/core/server';
|
|
46
50
|
|
|
47
51
|
export async function POST(req: Request) {
|
|
48
52
|
const { amount } = await req.json();
|
|
49
53
|
|
|
50
54
|
const result = await createPaymentIntent({
|
|
51
|
-
amount, //
|
|
55
|
+
amount, // in cents (1000 = 10.00 EUR)
|
|
52
56
|
currency: 'eur',
|
|
53
57
|
});
|
|
54
58
|
|
|
@@ -60,7 +64,7 @@ export async function POST(req: Request) {
|
|
|
60
64
|
}
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
**Client** -
|
|
67
|
+
**Client** - Payment form:
|
|
64
68
|
|
|
65
69
|
```tsx
|
|
66
70
|
// app/checkout/page.tsx
|
|
@@ -89,7 +93,7 @@ export default function CheckoutPage() {
|
|
|
89
93
|
<CheckoutForm
|
|
90
94
|
onSuccess={(id) => console.log('Paid!', id)}
|
|
91
95
|
onError={(err) => console.error(err)}
|
|
92
|
-
submitLabel="
|
|
96
|
+
submitLabel="Pay 20 EUR"
|
|
93
97
|
showEmail
|
|
94
98
|
/>
|
|
95
99
|
</StripeElementsProvider>
|
|
@@ -97,26 +101,25 @@ export default function CheckoutPage() {
|
|
|
97
101
|
}
|
|
98
102
|
```
|
|
99
103
|
|
|
100
|
-
### Checkout Session (
|
|
104
|
+
### Checkout Session (Stripe-hosted page)
|
|
101
105
|
|
|
102
106
|
```ts
|
|
103
|
-
// Server
|
|
104
107
|
import { createCheckoutSession } from '@stripe-sdk/core/server';
|
|
105
108
|
|
|
106
109
|
const result = await createCheckoutSession({
|
|
107
110
|
mode: 'payment',
|
|
108
111
|
lineItems: [{ priceId: 'price_xxx', quantity: 1 }],
|
|
109
|
-
successUrl: 'https://
|
|
110
|
-
cancelUrl: 'https://
|
|
112
|
+
successUrl: 'https://mysite.com/success?session_id={CHECKOUT_SESSION_ID}',
|
|
113
|
+
cancelUrl: 'https://mysite.com/cancel',
|
|
111
114
|
automaticTax: true,
|
|
112
115
|
allowPromotionCodes: true,
|
|
113
116
|
});
|
|
114
117
|
|
|
115
|
-
// Redirect
|
|
118
|
+
// Redirect the user to result.data.url
|
|
116
119
|
```
|
|
117
120
|
|
|
118
121
|
```tsx
|
|
119
|
-
// Client - redirect
|
|
122
|
+
// Client - redirect to Checkout
|
|
120
123
|
import { useCheckout } from '@stripe-sdk/core/client';
|
|
121
124
|
|
|
122
125
|
function BuyButton() {
|
|
@@ -130,11 +133,11 @@ function BuyButton() {
|
|
|
130
133
|
await redirectToCheckout(sessionId);
|
|
131
134
|
};
|
|
132
135
|
|
|
133
|
-
return <button onClick={handleClick} disabled={isLoading}>
|
|
136
|
+
return <button onClick={handleClick} disabled={isLoading}>Buy Now</button>;
|
|
134
137
|
}
|
|
135
138
|
```
|
|
136
139
|
|
|
137
|
-
### Payment Link (
|
|
140
|
+
### Payment Link (no-code)
|
|
138
141
|
|
|
139
142
|
```ts
|
|
140
143
|
import { createPaymentLink } from '@stripe-sdk/core/server';
|
|
@@ -144,22 +147,21 @@ const result = await createPaymentLink({
|
|
|
144
147
|
allowPromotionCodes: true,
|
|
145
148
|
afterCompletion: {
|
|
146
149
|
type: 'redirect',
|
|
147
|
-
redirectUrl: 'https://
|
|
150
|
+
redirectUrl: 'https://mysite.com/thank-you',
|
|
148
151
|
},
|
|
149
152
|
});
|
|
150
153
|
|
|
151
|
-
console.log(result.data.url); //
|
|
154
|
+
console.log(result.data.url); // Shareable link
|
|
152
155
|
```
|
|
153
156
|
|
|
154
157
|
---
|
|
155
158
|
|
|
156
|
-
##
|
|
157
|
-
|
|
158
|
-
### Creer un abonnement
|
|
159
|
+
## Subscriptions
|
|
159
160
|
|
|
160
161
|
```ts
|
|
161
|
-
import { createSubscription } from '@stripe-sdk/core/server';
|
|
162
|
+
import { createSubscription, updateSubscription, cancelSubscription, resumeSubscription } from '@stripe-sdk/core/server';
|
|
162
163
|
|
|
164
|
+
// Create
|
|
163
165
|
const result = await createSubscription({
|
|
164
166
|
customerId: 'cus_xxx',
|
|
165
167
|
priceId: 'price_monthly_xxx',
|
|
@@ -167,39 +169,24 @@ const result = await createSubscription({
|
|
|
167
169
|
paymentBehavior: 'default_incomplete',
|
|
168
170
|
});
|
|
169
171
|
|
|
170
|
-
//
|
|
171
|
-
// -> utiliser avec StripeElementsProvider pour confirmer le paiement
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Changer de plan
|
|
175
|
-
|
|
176
|
-
```ts
|
|
177
|
-
import { updateSubscription } from '@stripe-sdk/core/server';
|
|
178
|
-
|
|
172
|
+
// Change plan
|
|
179
173
|
await updateSubscription({
|
|
180
174
|
subscriptionId: 'sub_xxx',
|
|
181
175
|
items: [{ id: 'si_xxx', priceId: 'price_annual_xxx' }],
|
|
182
176
|
prorationBehavior: 'create_prorations',
|
|
183
177
|
});
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Annuler / Reprendre
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
import { cancelSubscription, resumeSubscription } from '@stripe-sdk/core/server';
|
|
190
178
|
|
|
191
|
-
//
|
|
179
|
+
// Cancel at period end
|
|
192
180
|
await cancelSubscription({
|
|
193
181
|
subscriptionId: 'sub_xxx',
|
|
194
182
|
cancelAtPeriodEnd: true,
|
|
195
|
-
cancellationDetails: { feedback: 'too_expensive' },
|
|
196
183
|
});
|
|
197
184
|
|
|
198
|
-
//
|
|
185
|
+
// Resume
|
|
199
186
|
await resumeSubscription('sub_xxx');
|
|
200
187
|
```
|
|
201
188
|
|
|
202
|
-
###
|
|
189
|
+
### PricingTable Component
|
|
203
190
|
|
|
204
191
|
```tsx
|
|
205
192
|
import { PricingTable, type PricingPlan } from '@stripe-sdk/core/client';
|
|
@@ -212,7 +199,7 @@ const plans: PricingPlan[] = [
|
|
|
212
199
|
amount: 900,
|
|
213
200
|
currency: 'eur',
|
|
214
201
|
interval: 'month',
|
|
215
|
-
features: ['5
|
|
202
|
+
features: ['5 projects', '1 GB storage', 'Email support'],
|
|
216
203
|
},
|
|
217
204
|
{
|
|
218
205
|
id: 'pro',
|
|
@@ -221,9 +208,9 @@ const plans: PricingPlan[] = [
|
|
|
221
208
|
amount: 2900,
|
|
222
209
|
currency: 'eur',
|
|
223
210
|
interval: 'month',
|
|
224
|
-
features: ['
|
|
211
|
+
features: ['Unlimited projects', '100 GB storage', 'Priority support', 'API access'],
|
|
225
212
|
highlighted: true,
|
|
226
|
-
badge: '
|
|
213
|
+
badge: 'Popular',
|
|
227
214
|
},
|
|
228
215
|
];
|
|
229
216
|
|
|
@@ -234,101 +221,53 @@ const plans: PricingPlan[] = [
|
|
|
234
221
|
/>
|
|
235
222
|
```
|
|
236
223
|
|
|
237
|
-
### Composant SubscriptionManager
|
|
238
|
-
|
|
239
|
-
```tsx
|
|
240
|
-
import { SubscriptionManager } from '@stripe-sdk/core/client';
|
|
241
|
-
|
|
242
|
-
<SubscriptionManager
|
|
243
|
-
subscription={{
|
|
244
|
-
id: 'sub_xxx',
|
|
245
|
-
status: 'active',
|
|
246
|
-
planName: 'Pro',
|
|
247
|
-
amount: 2900,
|
|
248
|
-
currency: 'eur',
|
|
249
|
-
interval: 'month',
|
|
250
|
-
currentPeriodEnd: '2025-03-01',
|
|
251
|
-
cancelAtPeriodEnd: false,
|
|
252
|
-
}}
|
|
253
|
-
onCancel={async (id) => {
|
|
254
|
-
await fetch(`/api/subscriptions/${id}/cancel`, { method: 'POST' });
|
|
255
|
-
}}
|
|
256
|
-
onResume={async (id) => {
|
|
257
|
-
await fetch(`/api/subscriptions/${id}/resume`, { method: 'POST' });
|
|
258
|
-
}}
|
|
259
|
-
onManageBilling={() => window.location.href = '/api/portal'}
|
|
260
|
-
/>
|
|
261
|
-
```
|
|
262
|
-
|
|
263
224
|
---
|
|
264
225
|
|
|
265
|
-
##
|
|
226
|
+
## Customers
|
|
266
227
|
|
|
267
228
|
```ts
|
|
268
229
|
import {
|
|
269
|
-
createCustomer,
|
|
270
|
-
|
|
271
|
-
updateCustomer,
|
|
272
|
-
deleteCustomer,
|
|
273
|
-
listCustomers,
|
|
274
|
-
searchCustomers,
|
|
230
|
+
createCustomer, retrieveCustomer, updateCustomer,
|
|
231
|
+
deleteCustomer, listCustomers, searchCustomers,
|
|
275
232
|
} from '@stripe-sdk/core/server';
|
|
276
233
|
|
|
277
|
-
// Creer
|
|
278
234
|
const { data: customer } = await createCustomer({
|
|
279
235
|
email: 'user@example.com',
|
|
280
236
|
name: 'John Doe',
|
|
281
237
|
metadata: { userId: 'usr_123' },
|
|
282
238
|
});
|
|
283
239
|
|
|
284
|
-
// Rechercher
|
|
285
240
|
const { data: results } = await searchCustomers("email:'user@example.com'");
|
|
286
|
-
|
|
287
|
-
// Mettre a jour
|
|
288
|
-
await updateCustomer({
|
|
289
|
-
customerId: 'cus_xxx',
|
|
290
|
-
name: 'Jane Doe',
|
|
291
|
-
defaultPaymentMethodId: 'pm_xxx',
|
|
292
|
-
});
|
|
293
241
|
```
|
|
294
242
|
|
|
295
243
|
---
|
|
296
244
|
|
|
297
|
-
##
|
|
245
|
+
## Customer Portal
|
|
298
246
|
|
|
299
247
|
```ts
|
|
300
248
|
import { createPortalSession } from '@stripe-sdk/core/server';
|
|
301
249
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
returnUrl: 'https://monsite.com/account',
|
|
308
|
-
});
|
|
309
|
-
return Response.json({ url: result.data.url });
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// Le client est redirige vers le portail Stripe pour gerer
|
|
313
|
-
// ses abonnements, moyens de paiement et factures.
|
|
250
|
+
const result = await createPortalSession({
|
|
251
|
+
customerId: 'cus_xxx',
|
|
252
|
+
returnUrl: 'https://mysite.com/account',
|
|
253
|
+
});
|
|
254
|
+
// Redirect user to result.data.url
|
|
314
255
|
```
|
|
315
256
|
|
|
316
257
|
---
|
|
317
258
|
|
|
318
|
-
##
|
|
259
|
+
## Save a Payment Method (SetupIntent)
|
|
319
260
|
|
|
320
261
|
```ts
|
|
321
|
-
// Serveur
|
|
322
262
|
import { createSetupIntent } from '@stripe-sdk/core/server';
|
|
323
263
|
|
|
324
264
|
const result = await createSetupIntent({
|
|
325
265
|
customerId: 'cus_xxx',
|
|
326
|
-
usage: 'off_session',
|
|
266
|
+
usage: 'off_session',
|
|
327
267
|
});
|
|
328
268
|
```
|
|
329
269
|
|
|
330
270
|
```tsx
|
|
331
|
-
// Client
|
|
332
271
|
import { StripeElementsProvider, SetupForm } from '@stripe-sdk/core/client';
|
|
333
272
|
|
|
334
273
|
<StripeElementsProvider
|
|
@@ -336,65 +275,44 @@ import { StripeElementsProvider, SetupForm } from '@stripe-sdk/core/client';
|
|
|
336
275
|
clientSecret={setupClientSecret}
|
|
337
276
|
>
|
|
338
277
|
<SetupForm
|
|
339
|
-
onSuccess={(setupId, pmId) =>
|
|
340
|
-
|
|
341
|
-
}}
|
|
342
|
-
submitLabel="Sauvegarder la carte"
|
|
278
|
+
onSuccess={(setupId, pmId) => console.log('Saved!', pmId)}
|
|
279
|
+
submitLabel="Save Card"
|
|
343
280
|
/>
|
|
344
281
|
</StripeElementsProvider>
|
|
345
282
|
```
|
|
346
283
|
|
|
347
284
|
---
|
|
348
285
|
|
|
349
|
-
##
|
|
286
|
+
## Products & Prices
|
|
350
287
|
|
|
351
288
|
```ts
|
|
352
|
-
import {
|
|
353
|
-
createProduct,
|
|
354
|
-
createPrice,
|
|
355
|
-
listProducts,
|
|
356
|
-
listPrices,
|
|
357
|
-
} from '@stripe-sdk/core/server';
|
|
289
|
+
import { createProduct, createPrice, listProducts, listPrices } from '@stripe-sdk/core/server';
|
|
358
290
|
|
|
359
|
-
// Creer un produit avec prix par defaut
|
|
360
291
|
const { data: product } = await createProduct({
|
|
361
|
-
name: 'Plan
|
|
362
|
-
description: 'Acces complet a la plateforme',
|
|
292
|
+
name: 'Pro Plan',
|
|
363
293
|
defaultPriceData: {
|
|
364
|
-
unitAmount: 2900,
|
|
294
|
+
unitAmount: 2900,
|
|
365
295
|
currency: 'eur',
|
|
366
296
|
recurring: { interval: 'month' },
|
|
367
297
|
},
|
|
368
298
|
});
|
|
369
299
|
|
|
370
|
-
// Ajouter un prix annuel
|
|
371
300
|
await createPrice({
|
|
372
301
|
productId: product.id,
|
|
373
|
-
unitAmount: 29000,
|
|
302
|
+
unitAmount: 29000,
|
|
374
303
|
currency: 'eur',
|
|
375
304
|
recurring: { interval: 'year' },
|
|
376
305
|
lookupKey: 'pro_annual',
|
|
377
306
|
});
|
|
378
|
-
|
|
379
|
-
// Lister les produits actifs
|
|
380
|
-
const { data: products } = await listProducts({ active: true, limit: 20 });
|
|
381
307
|
```
|
|
382
308
|
|
|
383
309
|
---
|
|
384
310
|
|
|
385
|
-
##
|
|
311
|
+
## Invoices
|
|
386
312
|
|
|
387
313
|
```ts
|
|
388
|
-
import {
|
|
389
|
-
createInvoice,
|
|
390
|
-
createInvoiceItem,
|
|
391
|
-
finalizeInvoice,
|
|
392
|
-
sendInvoice,
|
|
393
|
-
listInvoices,
|
|
394
|
-
getUpcomingInvoice,
|
|
395
|
-
} from '@stripe-sdk/core/server';
|
|
314
|
+
import { createInvoice, createInvoiceItem, finalizeInvoice, sendInvoice } from '@stripe-sdk/core/server';
|
|
396
315
|
|
|
397
|
-
// Creer et envoyer une facture
|
|
398
316
|
const { data: invoice } = await createInvoice({
|
|
399
317
|
customerId: 'cus_xxx',
|
|
400
318
|
collectionMethod: 'send_invoice',
|
|
@@ -404,79 +322,55 @@ const { data: invoice } = await createInvoice({
|
|
|
404
322
|
await createInvoiceItem({
|
|
405
323
|
customerId: 'cus_xxx',
|
|
406
324
|
invoiceId: invoice.id,
|
|
407
|
-
amount: 5000,
|
|
325
|
+
amount: 5000,
|
|
408
326
|
currency: 'eur',
|
|
409
|
-
description: 'Consulting -
|
|
327
|
+
description: 'Consulting - January 2025',
|
|
410
328
|
});
|
|
411
329
|
|
|
412
330
|
await finalizeInvoice(invoice.id);
|
|
413
331
|
await sendInvoice(invoice.id);
|
|
414
|
-
|
|
415
|
-
// Prochaine facture d'un abonnement
|
|
416
|
-
const { data: upcoming } = await getUpcomingInvoice('cus_xxx', 'sub_xxx');
|
|
417
332
|
```
|
|
418
333
|
|
|
419
334
|
---
|
|
420
335
|
|
|
421
|
-
##
|
|
336
|
+
## Refunds & Disputes
|
|
422
337
|
|
|
423
338
|
```ts
|
|
424
|
-
import {
|
|
425
|
-
createRefund,
|
|
426
|
-
listRefunds,
|
|
427
|
-
retrieveDispute,
|
|
428
|
-
updateDispute,
|
|
429
|
-
} from '@stripe-sdk/core/server';
|
|
339
|
+
import { createRefund, updateDispute } from '@stripe-sdk/core/server';
|
|
430
340
|
|
|
431
|
-
//
|
|
341
|
+
// Full refund
|
|
432
342
|
await createRefund({ paymentIntentId: 'pi_xxx' });
|
|
433
343
|
|
|
434
|
-
//
|
|
435
|
-
await createRefund({
|
|
436
|
-
paymentIntentId: 'pi_xxx',
|
|
437
|
-
amount: 500, // 5.00 EUR
|
|
438
|
-
reason: 'requested_by_customer',
|
|
439
|
-
});
|
|
344
|
+
// Partial refund
|
|
345
|
+
await createRefund({ paymentIntentId: 'pi_xxx', amount: 500, reason: 'requested_by_customer' });
|
|
440
346
|
|
|
441
|
-
//
|
|
347
|
+
// Respond to dispute
|
|
442
348
|
await updateDispute({
|
|
443
349
|
disputeId: 'dp_xxx',
|
|
444
|
-
evidence: {
|
|
445
|
-
customerName: 'John Doe',
|
|
446
|
-
productDescription: 'Abonnement SaaS mensuel',
|
|
447
|
-
serviceDocumentation: 'file_xxx',
|
|
448
|
-
},
|
|
350
|
+
evidence: { customerName: 'John Doe', productDescription: 'Monthly SaaS subscription' },
|
|
449
351
|
submit: true,
|
|
450
352
|
});
|
|
451
353
|
```
|
|
452
354
|
|
|
453
355
|
---
|
|
454
356
|
|
|
455
|
-
## Coupons & Codes
|
|
357
|
+
## Coupons & Promotion Codes
|
|
456
358
|
|
|
457
359
|
```ts
|
|
458
|
-
import {
|
|
459
|
-
createCoupon,
|
|
460
|
-
createPromotionCode,
|
|
461
|
-
listPromotionCodes,
|
|
462
|
-
} from '@stripe-sdk/core/server';
|
|
360
|
+
import { createCoupon, createPromotionCode } from '@stripe-sdk/core/server';
|
|
463
361
|
|
|
464
|
-
// Coupon -20%
|
|
465
362
|
const { data: coupon } = await createCoupon({
|
|
466
363
|
percentOff: 20,
|
|
467
364
|
duration: 'repeating',
|
|
468
365
|
durationInMonths: 3,
|
|
469
|
-
name: '
|
|
366
|
+
name: 'Launch 2025',
|
|
470
367
|
});
|
|
471
368
|
|
|
472
|
-
// Code promo public
|
|
473
369
|
await createPromotionCode({
|
|
474
370
|
couponId: coupon.id,
|
|
475
371
|
code: 'LAUNCH20',
|
|
476
372
|
maxRedemptions: 100,
|
|
477
|
-
restrictions: {
|
|
478
|
-
firstTimeTransaction: true,
|
|
479
|
-
},
|
|
373
|
+
restrictions: { firstTimeTransaction: true },
|
|
480
374
|
});
|
|
481
375
|
```
|
|
482
376
|
|
|
@@ -485,41 +379,22 @@ await createPromotionCode({
|
|
|
485
379
|
## Stripe Connect (Marketplace)
|
|
486
380
|
|
|
487
381
|
```ts
|
|
488
|
-
import {
|
|
489
|
-
createConnectAccount,
|
|
490
|
-
createAccountLink,
|
|
491
|
-
createTransfer,
|
|
492
|
-
getBalance,
|
|
493
|
-
} from '@stripe-sdk/core/server';
|
|
382
|
+
import { createConnectAccount, createAccountLink, createTransfer, getBalance } from '@stripe-sdk/core/server';
|
|
494
383
|
|
|
495
|
-
// Creer un compte vendeur
|
|
496
384
|
const { data: account } = await createConnectAccount({
|
|
497
385
|
type: 'express',
|
|
498
386
|
email: 'seller@example.com',
|
|
499
|
-
capabilities: {
|
|
500
|
-
cardPayments: { requested: true },
|
|
501
|
-
transfers: { requested: true },
|
|
502
|
-
},
|
|
387
|
+
capabilities: { cardPayments: { requested: true }, transfers: { requested: true } },
|
|
503
388
|
});
|
|
504
389
|
|
|
505
|
-
// Lien d'onboarding
|
|
506
390
|
const { data: link } = await createAccountLink({
|
|
507
391
|
accountId: account.id,
|
|
508
|
-
refreshUrl: 'https://
|
|
509
|
-
returnUrl: 'https://
|
|
392
|
+
refreshUrl: 'https://mysite.com/onboarding/refresh',
|
|
393
|
+
returnUrl: 'https://mysite.com/onboarding/complete',
|
|
510
394
|
type: 'account_onboarding',
|
|
511
395
|
});
|
|
512
|
-
// Rediriger le vendeur vers link.url
|
|
513
|
-
|
|
514
|
-
// Transferer des fonds
|
|
515
|
-
await createTransfer({
|
|
516
|
-
amount: 8000, // 80 EUR au vendeur
|
|
517
|
-
currency: 'eur',
|
|
518
|
-
destinationAccountId: account.id,
|
|
519
|
-
});
|
|
520
396
|
|
|
521
|
-
|
|
522
|
-
const { data: balance } = await getBalance();
|
|
397
|
+
await createTransfer({ amount: 8000, currency: 'eur', destinationAccountId: account.id });
|
|
523
398
|
```
|
|
524
399
|
|
|
525
400
|
---
|
|
@@ -538,29 +413,11 @@ export const POST = createNextWebhookHandler({
|
|
|
538
413
|
'payment_intent.succeeded': async (event) => {
|
|
539
414
|
const pi = event.data.object;
|
|
540
415
|
console.log('Payment succeeded:', pi.id);
|
|
541
|
-
// Mettre a jour votre base de donnees
|
|
542
|
-
},
|
|
543
|
-
|
|
544
|
-
'customer.subscription.created': async (event) => {
|
|
545
|
-
const sub = event.data.object;
|
|
546
|
-
console.log('New subscription:', sub.id);
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
'customer.subscription.deleted': async (event) => {
|
|
550
|
-
const sub = event.data.object;
|
|
551
|
-
console.log('Subscription cancelled:', sub.id);
|
|
552
|
-
},
|
|
553
|
-
|
|
554
|
-
'invoice.payment_failed': async (event) => {
|
|
555
|
-
const invoice = event.data.object;
|
|
556
|
-
console.log('Payment failed for:', invoice.customer);
|
|
557
|
-
// Envoyer un email au client
|
|
558
|
-
},
|
|
559
|
-
|
|
560
|
-
'checkout.session.completed': async (event) => {
|
|
561
|
-
const session = event.data.object;
|
|
562
|
-
console.log('Checkout completed:', session.id);
|
|
563
416
|
},
|
|
417
|
+
'customer.subscription.created': async (event) => { /* ... */ },
|
|
418
|
+
'customer.subscription.deleted': async (event) => { /* ... */ },
|
|
419
|
+
'invoice.payment_failed': async (event) => { /* ... */ },
|
|
420
|
+
'checkout.session.completed': async (event) => { /* ... */ },
|
|
564
421
|
},
|
|
565
422
|
onError: (error, event) => {
|
|
566
423
|
console.error('Webhook error:', error.message, event?.type);
|
|
@@ -586,7 +443,7 @@ export default createPagesWebhookHandler({
|
|
|
586
443
|
|
|
587
444
|
---
|
|
588
445
|
|
|
589
|
-
## Next.js -
|
|
446
|
+
## Next.js Pre-built API Routes
|
|
590
447
|
|
|
591
448
|
```ts
|
|
592
449
|
// app/api/create-payment-intent/route.ts
|
|
@@ -594,9 +451,7 @@ import '@/lib/stripe';
|
|
|
594
451
|
import { createPaymentIntentRoute } from '@stripe-sdk/core/next';
|
|
595
452
|
|
|
596
453
|
export const POST = createPaymentIntentRoute({
|
|
597
|
-
// Optionnel : modifier l'input avant creation
|
|
598
454
|
beforeCreate: async (input, request) => {
|
|
599
|
-
// Verifier l'authentification, forcer un montant, etc.
|
|
600
455
|
return { ...input, currency: 'eur' };
|
|
601
456
|
},
|
|
602
457
|
});
|
|
@@ -606,7 +461,6 @@ export const POST = createPaymentIntentRoute({
|
|
|
606
461
|
// app/api/create-checkout-session/route.ts
|
|
607
462
|
import '@/lib/stripe';
|
|
608
463
|
import { createCheckoutSessionRoute } from '@stripe-sdk/core/next';
|
|
609
|
-
|
|
610
464
|
export const POST = createCheckoutSessionRoute();
|
|
611
465
|
```
|
|
612
466
|
|
|
@@ -614,20 +468,19 @@ export const POST = createCheckoutSessionRoute();
|
|
|
614
468
|
// app/api/create-portal-session/route.ts
|
|
615
469
|
import '@/lib/stripe';
|
|
616
470
|
import { createPortalSessionRoute } from '@stripe-sdk/core/next';
|
|
617
|
-
|
|
618
471
|
export const POST = createPortalSessionRoute();
|
|
619
472
|
```
|
|
620
473
|
|
|
621
474
|
---
|
|
622
475
|
|
|
623
|
-
##
|
|
476
|
+
## Error Handling
|
|
624
477
|
|
|
625
|
-
|
|
478
|
+
All server functions return an `SDKResult<T>`:
|
|
626
479
|
|
|
627
480
|
```ts
|
|
628
481
|
type SDKResult<T> =
|
|
629
|
-
| { data: T; error: null } //
|
|
630
|
-
| { data: null; error: SDKError } //
|
|
482
|
+
| { data: T; error: null } // Success
|
|
483
|
+
| { data: null; error: SDKError } // Error
|
|
631
484
|
|
|
632
485
|
type SDKError = {
|
|
633
486
|
message: string;
|
|
@@ -641,60 +494,34 @@ type SDKError = {
|
|
|
641
494
|
const result = await createPaymentIntent({ amount: 2000, currency: 'eur' });
|
|
642
495
|
|
|
643
496
|
if (result.error) {
|
|
644
|
-
console.error(result.error.message);
|
|
645
|
-
// "Your card was declined"
|
|
497
|
+
console.error(result.error.message); // "Your card was declined"
|
|
646
498
|
return;
|
|
647
499
|
}
|
|
648
500
|
|
|
649
|
-
console.log(result.data.id); // pi_xxx - TypeScript
|
|
501
|
+
console.log(result.data.id); // pi_xxx - TypeScript infers the correct type
|
|
650
502
|
```
|
|
651
503
|
|
|
652
504
|
---
|
|
653
505
|
|
|
654
|
-
## Architecture
|
|
655
|
-
|
|
656
|
-
```
|
|
657
|
-
src/
|
|
658
|
-
server/ # Code serveur uniquement
|
|
659
|
-
stripe-client.ts # Init & singleton Stripe
|
|
660
|
-
payments/ # PaymentIntent, Checkout, PaymentLink, SetupIntent
|
|
661
|
-
customers/ # CRUD clients + Portail
|
|
662
|
-
subscriptions/ # CRUD abonnements
|
|
663
|
-
products/ # Produits & Prix
|
|
664
|
-
invoices/ # Facturation
|
|
665
|
-
refunds/ # Remboursements & Litiges
|
|
666
|
-
connect/ # Marketplace, Transfers, Payouts, Balance
|
|
667
|
-
coupons/ # Coupons & Codes promo
|
|
668
|
-
webhooks/ # Handler avec verification de signature
|
|
669
|
-
client/ # Code client (React)
|
|
670
|
-
providers/ # StripeProvider, StripeElementsProvider
|
|
671
|
-
hooks/ # usePayment, useSetupIntent, useCheckout
|
|
672
|
-
components/ # CheckoutForm, SetupForm, PricingTable, SubscriptionManager
|
|
673
|
-
next/ # Utilitaires specifiques Next.js
|
|
674
|
-
index.ts # Server Actions, API route helpers
|
|
675
|
-
types/ # Types TypeScript complets
|
|
676
|
-
utils/ # Gestion d'erreurs
|
|
677
|
-
```
|
|
678
|
-
|
|
679
506
|
## Imports
|
|
680
507
|
|
|
681
508
|
```ts
|
|
682
|
-
//
|
|
509
|
+
// Server only
|
|
683
510
|
import { ... } from '@stripe-sdk/core/server';
|
|
684
511
|
|
|
685
|
-
// Client
|
|
512
|
+
// Client only (React)
|
|
686
513
|
import { ... } from '@stripe-sdk/core/client';
|
|
687
514
|
|
|
688
515
|
// Webhooks
|
|
689
516
|
import { ... } from '@stripe-sdk/core/webhooks';
|
|
690
517
|
|
|
691
|
-
//
|
|
518
|
+
// Next.js helpers
|
|
692
519
|
import { ... } from '@stripe-sdk/core/next';
|
|
693
520
|
|
|
694
|
-
//
|
|
521
|
+
// Everything (watch out for tree-shaking)
|
|
695
522
|
import { ... } from '@stripe-sdk/core';
|
|
696
523
|
```
|
|
697
524
|
|
|
698
|
-
##
|
|
525
|
+
## License
|
|
699
526
|
|
|
700
527
|
MIT
|