claudient 0.1.0

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.
Files changed (283) hide show
  1. package/.claude-plugin/plugin.json +42 -0
  2. package/CONTEXT.md +58 -0
  3. package/README.md +165 -0
  4. package/agents/build-resolvers/de/python-resolver.md +64 -0
  5. package/agents/build-resolvers/de/typescript-resolver.md +65 -0
  6. package/agents/build-resolvers/es/python-resolver.md +64 -0
  7. package/agents/build-resolvers/es/typescript-resolver.md +65 -0
  8. package/agents/build-resolvers/fr/python-resolver.md +64 -0
  9. package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
  10. package/agents/build-resolvers/nl/python-resolver.md +64 -0
  11. package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
  12. package/agents/build-resolvers/python-resolver.md +62 -0
  13. package/agents/build-resolvers/typescript-resolver.md +63 -0
  14. package/agents/core/architect.md +64 -0
  15. package/agents/core/code-reviewer.md +78 -0
  16. package/agents/core/de/architect.md +66 -0
  17. package/agents/core/de/code-reviewer.md +80 -0
  18. package/agents/core/de/planner.md +63 -0
  19. package/agents/core/de/security-reviewer.md +93 -0
  20. package/agents/core/es/architect.md +66 -0
  21. package/agents/core/es/code-reviewer.md +80 -0
  22. package/agents/core/es/planner.md +63 -0
  23. package/agents/core/es/security-reviewer.md +93 -0
  24. package/agents/core/fr/architect.md +66 -0
  25. package/agents/core/fr/code-reviewer.md +80 -0
  26. package/agents/core/fr/planner.md +63 -0
  27. package/agents/core/fr/security-reviewer.md +93 -0
  28. package/agents/core/nl/architect.md +66 -0
  29. package/agents/core/nl/code-reviewer.md +80 -0
  30. package/agents/core/nl/planner.md +63 -0
  31. package/agents/core/nl/security-reviewer.md +93 -0
  32. package/agents/core/planner.md +61 -0
  33. package/agents/core/security-reviewer.md +91 -0
  34. package/guides/agent-orchestration.md +231 -0
  35. package/guides/de/agent-orchestration.md +174 -0
  36. package/guides/de/getting-started.md +164 -0
  37. package/guides/de/hooks-cookbook.md +160 -0
  38. package/guides/de/memory-management.md +153 -0
  39. package/guides/de/security.md +180 -0
  40. package/guides/de/skill-authoring.md +214 -0
  41. package/guides/de/token-optimization.md +156 -0
  42. package/guides/es/agent-orchestration.md +174 -0
  43. package/guides/es/getting-started.md +164 -0
  44. package/guides/es/hooks-cookbook.md +160 -0
  45. package/guides/es/memory-management.md +153 -0
  46. package/guides/es/security.md +180 -0
  47. package/guides/es/skill-authoring.md +214 -0
  48. package/guides/es/token-optimization.md +156 -0
  49. package/guides/fr/agent-orchestration.md +174 -0
  50. package/guides/fr/getting-started.md +164 -0
  51. package/guides/fr/hooks-cookbook.md +227 -0
  52. package/guides/fr/memory-management.md +169 -0
  53. package/guides/fr/security.md +180 -0
  54. package/guides/fr/skill-authoring.md +214 -0
  55. package/guides/fr/token-optimization.md +158 -0
  56. package/guides/getting-started.md +164 -0
  57. package/guides/hooks-cookbook.md +423 -0
  58. package/guides/memory-management.md +192 -0
  59. package/guides/nl/agent-orchestration.md +174 -0
  60. package/guides/nl/getting-started.md +164 -0
  61. package/guides/nl/hooks-cookbook.md +160 -0
  62. package/guides/nl/memory-management.md +153 -0
  63. package/guides/nl/security.md +180 -0
  64. package/guides/nl/skill-authoring.md +214 -0
  65. package/guides/nl/token-optimization.md +156 -0
  66. package/guides/security.md +229 -0
  67. package/guides/skill-authoring.md +226 -0
  68. package/guides/token-optimization.md +169 -0
  69. package/hooks/lifecycle/cost-tracker.md +49 -0
  70. package/hooks/lifecycle/cost-tracker.sh +59 -0
  71. package/hooks/lifecycle/pre-compact-save.md +56 -0
  72. package/hooks/lifecycle/pre-compact-save.sh +37 -0
  73. package/hooks/lifecycle/session-start.md +50 -0
  74. package/hooks/lifecycle/session-start.sh +47 -0
  75. package/hooks/post-tool-use/audit-log.md +53 -0
  76. package/hooks/post-tool-use/audit-log.sh +53 -0
  77. package/hooks/post-tool-use/prettier.md +53 -0
  78. package/hooks/post-tool-use/prettier.sh +49 -0
  79. package/hooks/pre-tool-use/block-dangerous.md +48 -0
  80. package/hooks/pre-tool-use/block-dangerous.sh +76 -0
  81. package/hooks/pre-tool-use/git-push-confirm.md +46 -0
  82. package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
  83. package/mcp/configs/github.json +11 -0
  84. package/mcp/configs/postgres.json +11 -0
  85. package/mcp/de/recommended-servers.md +170 -0
  86. package/mcp/es/recommended-servers.md +170 -0
  87. package/mcp/fr/recommended-servers.md +170 -0
  88. package/mcp/nl/recommended-servers.md +170 -0
  89. package/mcp/recommended-servers.md +168 -0
  90. package/package.json +45 -0
  91. package/prompts/project-starters/de/fastapi-project.md +62 -0
  92. package/prompts/project-starters/de/nextjs-project.md +82 -0
  93. package/prompts/project-starters/es/fastapi-project.md +62 -0
  94. package/prompts/project-starters/es/nextjs-project.md +82 -0
  95. package/prompts/project-starters/fastapi-project.md +60 -0
  96. package/prompts/project-starters/fr/fastapi-project.md +62 -0
  97. package/prompts/project-starters/fr/nextjs-project.md +82 -0
  98. package/prompts/project-starters/nextjs-project.md +80 -0
  99. package/prompts/project-starters/nl/fastapi-project.md +62 -0
  100. package/prompts/project-starters/nl/nextjs-project.md +82 -0
  101. package/prompts/system-prompts/ai-product.md +80 -0
  102. package/prompts/system-prompts/data-pipeline.md +76 -0
  103. package/prompts/system-prompts/de/ai-product.md +82 -0
  104. package/prompts/system-prompts/de/data-pipeline.md +78 -0
  105. package/prompts/system-prompts/de/saas-backend.md +71 -0
  106. package/prompts/system-prompts/es/ai-product.md +82 -0
  107. package/prompts/system-prompts/es/data-pipeline.md +78 -0
  108. package/prompts/system-prompts/es/saas-backend.md +71 -0
  109. package/prompts/system-prompts/fr/ai-product.md +82 -0
  110. package/prompts/system-prompts/fr/data-pipeline.md +78 -0
  111. package/prompts/system-prompts/fr/saas-backend.md +71 -0
  112. package/prompts/system-prompts/nl/ai-product.md +82 -0
  113. package/prompts/system-prompts/nl/data-pipeline.md +78 -0
  114. package/prompts/system-prompts/nl/saas-backend.md +71 -0
  115. package/prompts/system-prompts/saas-backend.md +69 -0
  116. package/prompts/task-specific/changelog.md +81 -0
  117. package/prompts/task-specific/de/changelog.md +83 -0
  118. package/prompts/task-specific/de/debugging.md +78 -0
  119. package/prompts/task-specific/de/pr-description.md +69 -0
  120. package/prompts/task-specific/debugging.md +76 -0
  121. package/prompts/task-specific/es/changelog.md +83 -0
  122. package/prompts/task-specific/es/debugging.md +78 -0
  123. package/prompts/task-specific/es/pr-description.md +69 -0
  124. package/prompts/task-specific/fr/changelog.md +83 -0
  125. package/prompts/task-specific/fr/debugging.md +78 -0
  126. package/prompts/task-specific/fr/pr-description.md +69 -0
  127. package/prompts/task-specific/nl/changelog.md +83 -0
  128. package/prompts/task-specific/nl/debugging.md +78 -0
  129. package/prompts/task-specific/nl/pr-description.md +69 -0
  130. package/prompts/task-specific/pr-description.md +67 -0
  131. package/rules/common/coding-style.md +45 -0
  132. package/rules/common/de/coding-style.md +47 -0
  133. package/rules/common/de/git.md +48 -0
  134. package/rules/common/de/performance.md +40 -0
  135. package/rules/common/de/security.md +45 -0
  136. package/rules/common/de/testing.md +45 -0
  137. package/rules/common/es/coding-style.md +47 -0
  138. package/rules/common/es/git.md +48 -0
  139. package/rules/common/es/performance.md +40 -0
  140. package/rules/common/es/security.md +45 -0
  141. package/rules/common/es/testing.md +45 -0
  142. package/rules/common/fr/coding-style.md +47 -0
  143. package/rules/common/fr/git.md +48 -0
  144. package/rules/common/fr/performance.md +40 -0
  145. package/rules/common/fr/security.md +45 -0
  146. package/rules/common/fr/testing.md +45 -0
  147. package/rules/common/git.md +46 -0
  148. package/rules/common/nl/coding-style.md +47 -0
  149. package/rules/common/nl/git.md +48 -0
  150. package/rules/common/nl/performance.md +40 -0
  151. package/rules/common/nl/security.md +45 -0
  152. package/rules/common/nl/testing.md +45 -0
  153. package/rules/common/performance.md +38 -0
  154. package/rules/common/security.md +43 -0
  155. package/rules/common/testing.md +43 -0
  156. package/rules/language-specific/de/go.md +48 -0
  157. package/rules/language-specific/de/python.md +38 -0
  158. package/rules/language-specific/de/typescript.md +51 -0
  159. package/rules/language-specific/es/go.md +48 -0
  160. package/rules/language-specific/es/python.md +38 -0
  161. package/rules/language-specific/es/typescript.md +51 -0
  162. package/rules/language-specific/fr/go.md +48 -0
  163. package/rules/language-specific/fr/python.md +38 -0
  164. package/rules/language-specific/fr/typescript.md +51 -0
  165. package/rules/language-specific/go.md +46 -0
  166. package/rules/language-specific/nl/go.md +48 -0
  167. package/rules/language-specific/nl/python.md +38 -0
  168. package/rules/language-specific/nl/typescript.md +51 -0
  169. package/rules/language-specific/python.md +36 -0
  170. package/rules/language-specific/typescript.md +49 -0
  171. package/scripts/cli.js +161 -0
  172. package/scripts/link-skills.sh +35 -0
  173. package/scripts/list-skills.sh +34 -0
  174. package/skills/ai-engineering/agent-construction.md +285 -0
  175. package/skills/ai-engineering/claude-api.md +248 -0
  176. package/skills/ai-engineering/de/agent-construction.md +287 -0
  177. package/skills/ai-engineering/de/claude-api.md +250 -0
  178. package/skills/ai-engineering/es/agent-construction.md +287 -0
  179. package/skills/ai-engineering/es/claude-api.md +250 -0
  180. package/skills/ai-engineering/fr/agent-construction.md +287 -0
  181. package/skills/ai-engineering/fr/claude-api.md +250 -0
  182. package/skills/ai-engineering/nl/agent-construction.md +287 -0
  183. package/skills/ai-engineering/nl/claude-api.md +250 -0
  184. package/skills/backend/dotnet/csharp.md +304 -0
  185. package/skills/backend/dotnet/de/csharp.md +306 -0
  186. package/skills/backend/dotnet/es/csharp.md +306 -0
  187. package/skills/backend/dotnet/fr/csharp.md +306 -0
  188. package/skills/backend/dotnet/nl/csharp.md +306 -0
  189. package/skills/backend/go/de/go.md +307 -0
  190. package/skills/backend/go/es/go.md +307 -0
  191. package/skills/backend/go/fr/go.md +307 -0
  192. package/skills/backend/go/go.md +305 -0
  193. package/skills/backend/go/nl/go.md +307 -0
  194. package/skills/backend/nodejs/de/nestjs.md +274 -0
  195. package/skills/backend/nodejs/de/nextjs.md +222 -0
  196. package/skills/backend/nodejs/es/nestjs.md +274 -0
  197. package/skills/backend/nodejs/es/nextjs.md +222 -0
  198. package/skills/backend/nodejs/fr/nestjs.md +274 -0
  199. package/skills/backend/nodejs/fr/nextjs.md +222 -0
  200. package/skills/backend/nodejs/nestjs.md +272 -0
  201. package/skills/backend/nodejs/nextjs.md +220 -0
  202. package/skills/backend/nodejs/nl/nestjs.md +274 -0
  203. package/skills/backend/nodejs/nl/nextjs.md +222 -0
  204. package/skills/backend/python/de/django.md +285 -0
  205. package/skills/backend/python/de/fastapi.md +244 -0
  206. package/skills/backend/python/django.md +283 -0
  207. package/skills/backend/python/es/django.md +285 -0
  208. package/skills/backend/python/es/fastapi.md +244 -0
  209. package/skills/backend/python/fastapi.md +242 -0
  210. package/skills/backend/python/fr/django.md +285 -0
  211. package/skills/backend/python/fr/fastapi.md +244 -0
  212. package/skills/backend/python/nl/django.md +285 -0
  213. package/skills/backend/python/nl/fastapi.md +244 -0
  214. package/skills/data-ml/dbt-data-pipelines.md +155 -0
  215. package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
  216. package/skills/data-ml/de/pandas-polars.md +147 -0
  217. package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
  218. package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
  219. package/skills/data-ml/es/pandas-polars.md +147 -0
  220. package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
  221. package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
  222. package/skills/data-ml/fr/pandas-polars.md +147 -0
  223. package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
  224. package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
  225. package/skills/data-ml/nl/pandas-polars.md +147 -0
  226. package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
  227. package/skills/data-ml/pandas-polars.md +145 -0
  228. package/skills/data-ml/pytorch-tensorflow.md +169 -0
  229. package/skills/database/de/graphql.md +181 -0
  230. package/skills/database/es/graphql.md +181 -0
  231. package/skills/database/fr/graphql.md +181 -0
  232. package/skills/database/graphql.md +179 -0
  233. package/skills/database/nl/graphql.md +181 -0
  234. package/skills/devops-infra/de/docker.md +133 -0
  235. package/skills/devops-infra/de/github-actions.md +179 -0
  236. package/skills/devops-infra/de/kubernetes.md +129 -0
  237. package/skills/devops-infra/de/terraform.md +130 -0
  238. package/skills/devops-infra/docker.md +131 -0
  239. package/skills/devops-infra/es/docker.md +133 -0
  240. package/skills/devops-infra/es/github-actions.md +179 -0
  241. package/skills/devops-infra/es/kubernetes.md +129 -0
  242. package/skills/devops-infra/es/terraform.md +130 -0
  243. package/skills/devops-infra/fr/docker.md +133 -0
  244. package/skills/devops-infra/fr/github-actions.md +179 -0
  245. package/skills/devops-infra/fr/kubernetes.md +129 -0
  246. package/skills/devops-infra/fr/terraform.md +130 -0
  247. package/skills/devops-infra/github-actions.md +177 -0
  248. package/skills/devops-infra/kubernetes.md +127 -0
  249. package/skills/devops-infra/nl/docker.md +133 -0
  250. package/skills/devops-infra/nl/github-actions.md +179 -0
  251. package/skills/devops-infra/nl/kubernetes.md +129 -0
  252. package/skills/devops-infra/nl/terraform.md +130 -0
  253. package/skills/devops-infra/terraform.md +128 -0
  254. package/skills/finance-payments/de/stripe.md +187 -0
  255. package/skills/finance-payments/es/stripe.md +187 -0
  256. package/skills/finance-payments/fr/stripe.md +187 -0
  257. package/skills/finance-payments/nl/stripe.md +187 -0
  258. package/skills/finance-payments/stripe.md +185 -0
  259. package/workflows/code-review.md +151 -0
  260. package/workflows/de/code-review.md +153 -0
  261. package/workflows/de/debugging-session.md +146 -0
  262. package/workflows/de/feature-development.md +155 -0
  263. package/workflows/de/new-project-bootstrap.md +175 -0
  264. package/workflows/de/refactor-safely.md +150 -0
  265. package/workflows/debugging-session.md +144 -0
  266. package/workflows/es/code-review.md +153 -0
  267. package/workflows/es/debugging-session.md +146 -0
  268. package/workflows/es/feature-development.md +155 -0
  269. package/workflows/es/new-project-bootstrap.md +175 -0
  270. package/workflows/es/refactor-safely.md +150 -0
  271. package/workflows/feature-development.md +153 -0
  272. package/workflows/fr/code-review.md +153 -0
  273. package/workflows/fr/debugging-session.md +146 -0
  274. package/workflows/fr/feature-development.md +155 -0
  275. package/workflows/fr/new-project-bootstrap.md +175 -0
  276. package/workflows/fr/refactor-safely.md +150 -0
  277. package/workflows/new-project-bootstrap.md +173 -0
  278. package/workflows/nl/code-review.md +153 -0
  279. package/workflows/nl/debugging-session.md +146 -0
  280. package/workflows/nl/feature-development.md +155 -0
  281. package/workflows/nl/new-project-bootstrap.md +175 -0
  282. package/workflows/nl/refactor-safely.md +150 -0
  283. package/workflows/refactor-safely.md +148 -0
@@ -0,0 +1,187 @@
1
+ > 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../stripe.md).
2
+
3
+ # Stripe Integration Skill
4
+
5
+ ## Wann aktivieren
6
+ - Stripe Checkout oder Payment Intents für Einmalzahlungen implementieren
7
+ - Stripe-Abonnements und Abrechnungszyklen einrichten
8
+ - Stripe-Webhooks für Zahlungsereignisse verarbeiten
9
+ - Rückerstattungen, Streitigkeiten oder Zahlungsabbrüche implementieren
10
+ - Stripe Connect für Marktplatz-/Plattformzahlungen einrichten
11
+ - Fehlgeschlagene Zahlungen, abgelehnte Karten oder Webhook-Zustellprobleme debuggen
12
+ - SCA (Starke Kundenauthentifizierung) Compliance implementieren
13
+
14
+ ## Wann NICHT verwenden
15
+ - PayPal, Braintree, Adyen, Mollie — andere Zahlungsanbieter mit anderen SDKs
16
+ - Krypto-Zahlungen
17
+ - Interne Buchhaltungs- oder Rechnungssysteme ohne Zahlungs-Gateway
18
+ - Banküberweisung / nur ACH-Flows (anderes Stripe-Produkt — Payment Elements gelten noch, aber Flow unterscheidet sich)
19
+
20
+ ## Anweisungen
21
+
22
+ ### Niemals Zahlungsdaten hardcoden oder protokollieren
23
+ ```typescript
24
+ // NIEMALS Kartendetails, vollständige Payment-Intent-Objekte oder Kunden-PII protokollieren
25
+ // SCHLECHT:
26
+ console.log('Payment intent:', paymentIntent); // Kann sensible Daten enthalten
27
+
28
+ // GUT:
29
+ console.log('Payment intent created:', paymentIntent.id, paymentIntent.status);
30
+ ```
31
+
32
+ ### Payment Intents — serverseitige Erstellung
33
+ ```typescript
34
+ import Stripe from 'stripe';
35
+
36
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
37
+ apiVersion: '2024-12-18.acacia', // API-Version immer pinnen
38
+ });
39
+
40
+ // Payment Intent serverseitig erstellen — niemals clientseitig
41
+ export async function createPaymentIntent(
42
+ amount: number, // Immer in kleinster Währungseinheit (Cents für USD)
43
+ currency: string,
44
+ customerId: string,
45
+ metadata: Record<string, string>
46
+ ): Promise<{ clientSecret: string; paymentIntentId: string }> {
47
+ const paymentIntent = await stripe.paymentIntents.create({
48
+ amount, // z.B. 2999 = $29.99
49
+ currency, // z.B. 'usd', 'eur'
50
+ customer: customerId,
51
+ automatic_payment_methods: { enabled: true },
52
+ metadata, // Interne IDs hier speichern
53
+ idempotency_key: `pi_${customerId}_${Date.now()}`, // Doppelte Abbuchungen verhindern
54
+ });
55
+
56
+ return {
57
+ clientSecret: paymentIntent.client_secret!,
58
+ paymentIntentId: paymentIntent.id,
59
+ };
60
+ }
61
+ ```
62
+
63
+ ### Webhook-Verarbeitung — immer Signatur verifizieren
64
+ ```typescript
65
+ import { headers } from 'next/headers';
66
+
67
+ export async function POST(request: Request) {
68
+ const body = await request.text(); // Roher Body — kein geparsten JSON
69
+ const signature = headers().get('stripe-signature')!;
70
+
71
+ let event: Stripe.Event;
72
+ try {
73
+ event = stripe.webhooks.constructEvent(
74
+ body,
75
+ signature,
76
+ process.env.STRIPE_WEBHOOK_SECRET!
77
+ );
78
+ } catch (err) {
79
+ // Ungültige Signatur — sofort ablehnen
80
+ return new Response('Invalid signature', { status: 400 });
81
+ }
82
+
83
+ // Idempotent verarbeiten — Webhooks können mehr als einmal zugestellt werden
84
+ switch (event.type) {
85
+ case 'payment_intent.succeeded':
86
+ await handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
87
+ break;
88
+ case 'payment_intent.payment_failed':
89
+ await handlePaymentFailed(event.data.object as Stripe.PaymentIntent);
90
+ break;
91
+ case 'customer.subscription.deleted':
92
+ await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
93
+ break;
94
+ default:
95
+ // Protokollieren, aber kein Fehler bei unbekannten Ereignissen — Stripe fügt neue Ereignisse im Laufe der Zeit hinzu
96
+ console.log(`Unhandled event type: ${event.type}`);
97
+ }
98
+
99
+ return new Response(null, { status: 200 });
100
+ }
101
+
102
+ // Immer prüfen, ob bereits verarbeitet, bevor DB-Änderungen vorgenommen werden
103
+ async function handlePaymentSucceeded(paymentIntent: Stripe.PaymentIntent) {
104
+ const orderId = paymentIntent.metadata.order_id;
105
+
106
+ // Idempotenzprüfung
107
+ const existing = await db.order.findUnique({ where: { id: orderId } });
108
+ if (existing?.status === 'paid') return; // Bereits verarbeitet
109
+
110
+ await db.order.update({
111
+ where: { id: orderId },
112
+ data: { status: 'paid', stripePaymentIntentId: paymentIntent.id }
113
+ });
114
+ }
115
+ ```
116
+
117
+ ### Abonnements
118
+ ```typescript
119
+ // Abonnement erstellen
120
+ const subscription = await stripe.subscriptions.create({
121
+ customer: customerId,
122
+ items: [{ price: priceId }],
123
+ payment_behavior: 'default_incomplete', // Nicht aktivieren bis Zahlung bestätigt
124
+ expand: ['latest_invoice.payment_intent'],
125
+ });
126
+
127
+ // Wichtige Webhook-Ereignisse für Abonnements:
128
+ // customer.subscription.created → Zugang bereitstellen
129
+ // customer.subscription.updated → Planänderungen verarbeiten
130
+ // customer.subscription.deleted → Zugang widerrufen
131
+ // invoice.payment_succeeded → Zugangsperiode verlängern
132
+ // invoice.payment_failed → Mahnung senden, dann nach Nachfrist sperren
133
+ ```
134
+
135
+ ### Testmodus-Disziplin
136
+ ```typescript
137
+ // Testkartennummern in der Entwicklung verwenden:
138
+ // Erfolg: 4242 4242 4242 4242
139
+ // Ablehnung: 4000 0000 0000 0002
140
+ // Auth erforderlich: 4000 0025 0000 3155
141
+ // Test-Webhook-CLI verwenden: stripe listen --forward-to localhost:3000/api/webhooks/stripe
142
+
143
+ // Niemals Testschlüssel in der Produktion, niemals Live-Schlüssel in der Entwicklung verwenden
144
+ const isLiveMode = process.env.STRIPE_SECRET_KEY!.startsWith('sk_live_');
145
+ if (isLiveMode && process.env.NODE_ENV !== 'production') {
146
+ throw new Error('Live Stripe keys must not be used outside production');
147
+ }
148
+ ```
149
+
150
+ ### Fehlerbehandlung
151
+ ```typescript
152
+ try {
153
+ const charge = await stripe.charges.create({ ... });
154
+ } catch (err) {
155
+ if (err instanceof Stripe.errors.StripeCardError) {
156
+ // Karte abgelehnt — benutzerfreundliche Meldung anzeigen
157
+ return { error: err.message, code: err.code };
158
+ }
159
+ if (err instanceof Stripe.errors.StripeRateLimitError) {
160
+ // Mit exponentiellem Backoff wiederholen
161
+ throw err;
162
+ }
163
+ if (err instanceof Stripe.errors.StripeInvalidRequestError) {
164
+ // Fehlerhafter API-Aufruf — protokollieren und Code korrigieren
165
+ console.error('Invalid Stripe request:', err.message);
166
+ throw err;
167
+ }
168
+ // Andere Fehler: StripeAPIError, StripeConnectionError, StripeAuthenticationError
169
+ throw err;
170
+ }
171
+ ```
172
+
173
+ ## Beispiel
174
+
175
+ **Benutzer:** Einen Checkout-Flow für ein SaaS-Produkt implementieren: serverseitig einen Payment Intent erstellen, beim Erfolg den Webhook verarbeiten, um das Abonnement zu aktivieren, und fehlgeschlagene Zahlungen behandeln.
176
+
177
+ **Erwartete Ausgabe:**
178
+ - `POST /api/checkout` — erstellt PaymentIntent, gibt `clientSecret` zurück
179
+ - `POST /api/webhooks/stripe` — verifiziert Signatur, verarbeitet `payment_intent.succeeded` (idempotentes DB-Update), `payment_intent.payment_failed` (protokollieren + benachrichtigen)
180
+ - Metadaten auf PaymentIntent: `user_id`, `plan_id`, `order_id`
181
+ - Alle Beträge in Cents, Währung explizit
182
+ - API-Version gepinnt
183
+ - Keine Protokollierung sensibler Daten
184
+
185
+ ---
186
+
187
+ > **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. Zahlungsflows aufbauen oder KI-Produkte monetarisieren? [uitbreiden.com](https://uitbreiden.com/)
@@ -0,0 +1,187 @@
1
+ > 🇪🇸 Esta es la traducción en español. [Versión en inglés](../stripe.md).
2
+
3
+ # Skill de Integración con Stripe
4
+
5
+ ## Cuándo activar
6
+ - Implementar Stripe Checkout o Payment Intents para pagos únicos
7
+ - Configurar suscripciones y ciclos de facturación en Stripe
8
+ - Manejar webhooks de Stripe para eventos de pago
9
+ - Implementar reembolsos, disputas o cancelaciones de pagos
10
+ - Configurar Stripe Connect para pagos en marketplace/plataforma
11
+ - Depurar pagos fallidos, tarjetas rechazadas o problemas de entrega de webhooks
12
+ - Implementar cumplimiento de SCA (Strong Customer Authentication)
13
+
14
+ ## Cuándo NO usar
15
+ - PayPal, Braintree, Adyen, Mollie — proveedores de pago diferentes con SDKs diferentes
16
+ - Pagos con criptomonedas
17
+ - Sistemas internos de contabilidad o facturación sin pasarela de pago
18
+ - Flujos solo de transferencia bancaria/ACH (producto diferente de Stripe — Payment Elements aún aplica, pero el flujo difiere)
19
+
20
+ ## Instrucciones
21
+
22
+ ### Nunca hardcodees ni registres datos de pago
23
+ ```typescript
24
+ // NUNCA registres detalles de tarjeta, objetos completos de payment intent o PII del cliente
25
+ // MALO:
26
+ console.log('Payment intent:', paymentIntent); // Puede contener datos sensibles
27
+
28
+ // BUENO:
29
+ console.log('Payment intent created:', paymentIntent.id, paymentIntent.status);
30
+ ```
31
+
32
+ ### Payment Intents — creación en el servidor
33
+ ```typescript
34
+ import Stripe from 'stripe';
35
+
36
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
37
+ apiVersion: '2024-12-18.acacia', // Siempre fija la versión de la API
38
+ });
39
+
40
+ // Crear payment intent en el servidor — nunca en el cliente
41
+ export async function createPaymentIntent(
42
+ amount: number, // Siempre en la unidad de moneda más pequeña (centavos para USD)
43
+ currency: string,
44
+ customerId: string,
45
+ metadata: Record<string, string>
46
+ ): Promise<{ clientSecret: string; paymentIntentId: string }> {
47
+ const paymentIntent = await stripe.paymentIntents.create({
48
+ amount, // p.ej., 2999 = $29.99
49
+ currency, // p.ej., 'usd', 'eur'
50
+ customer: customerId,
51
+ automatic_payment_methods: { enabled: true },
52
+ metadata, // Almacena tus IDs internos aquí
53
+ idempotency_key: `pi_${customerId}_${Date.now()}`, // Prevenir cargos duplicados
54
+ });
55
+
56
+ return {
57
+ clientSecret: paymentIntent.client_secret!,
58
+ paymentIntentId: paymentIntent.id,
59
+ };
60
+ }
61
+ ```
62
+
63
+ ### Manejo de webhooks — siempre verifica la firma
64
+ ```typescript
65
+ import { headers } from 'next/headers';
66
+
67
+ export async function POST(request: Request) {
68
+ const body = await request.text(); // Cuerpo sin procesar — no JSON parseado
69
+ const signature = headers().get('stripe-signature')!;
70
+
71
+ let event: Stripe.Event;
72
+ try {
73
+ event = stripe.webhooks.constructEvent(
74
+ body,
75
+ signature,
76
+ process.env.STRIPE_WEBHOOK_SECRET!
77
+ );
78
+ } catch (err) {
79
+ // Firma inválida — rechazar inmediatamente
80
+ return new Response('Invalid signature', { status: 400 });
81
+ }
82
+
83
+ // Procesar idempotentemente — los webhooks pueden entregarse más de una vez
84
+ switch (event.type) {
85
+ case 'payment_intent.succeeded':
86
+ await handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
87
+ break;
88
+ case 'payment_intent.payment_failed':
89
+ await handlePaymentFailed(event.data.object as Stripe.PaymentIntent);
90
+ break;
91
+ case 'customer.subscription.deleted':
92
+ await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
93
+ break;
94
+ default:
95
+ // Registrar pero no dar error en eventos desconocidos — Stripe agrega nuevos eventos con el tiempo
96
+ console.log(`Unhandled event type: ${event.type}`);
97
+ }
98
+
99
+ return new Response(null, { status: 200 });
100
+ }
101
+
102
+ // Siempre verifica si ya fue procesado antes de hacer cambios en la BD
103
+ async function handlePaymentSucceeded(paymentIntent: Stripe.PaymentIntent) {
104
+ const orderId = paymentIntent.metadata.order_id;
105
+
106
+ // Verificación de idempotencia
107
+ const existing = await db.order.findUnique({ where: { id: orderId } });
108
+ if (existing?.status === 'paid') return; // Ya procesado
109
+
110
+ await db.order.update({
111
+ where: { id: orderId },
112
+ data: { status: 'paid', stripePaymentIntentId: paymentIntent.id }
113
+ });
114
+ }
115
+ ```
116
+
117
+ ### Suscripciones
118
+ ```typescript
119
+ // Crear suscripción
120
+ const subscription = await stripe.subscriptions.create({
121
+ customer: customerId,
122
+ items: [{ price: priceId }],
123
+ payment_behavior: 'default_incomplete', // No activar hasta que se confirme el pago
124
+ expand: ['latest_invoice.payment_intent'],
125
+ });
126
+
127
+ // Eventos webhook clave para suscripciones:
128
+ // customer.subscription.created → aprovisionar acceso
129
+ // customer.subscription.updated → manejar cambios de plan
130
+ // customer.subscription.deleted → revocar acceso
131
+ // invoice.payment_succeeded → extender período de acceso
132
+ // invoice.payment_failed → enviar correo de dunning, luego suspender después del período de gracia
133
+ ```
134
+
135
+ ### Disciplina en modo de prueba
136
+ ```typescript
137
+ // Usar números de tarjeta de prueba en desarrollo:
138
+ // Éxito: 4242 4242 4242 4242
139
+ // Rechazada: 4000 0000 0000 0002
140
+ // Requiere autenticación: 4000 0025 0000 3155
141
+ // Usar webhook CLI de prueba: stripe listen --forward-to localhost:3000/api/webhooks/stripe
142
+
143
+ // Nunca usar claves de prueba en producción, nunca usar claves en vivo en desarrollo
144
+ const isLiveMode = process.env.STRIPE_SECRET_KEY!.startsWith('sk_live_');
145
+ if (isLiveMode && process.env.NODE_ENV !== 'production') {
146
+ throw new Error('Live Stripe keys must not be used outside production');
147
+ }
148
+ ```
149
+
150
+ ### Manejo de errores
151
+ ```typescript
152
+ try {
153
+ const charge = await stripe.charges.create({ ... });
154
+ } catch (err) {
155
+ if (err instanceof Stripe.errors.StripeCardError) {
156
+ // Tarjeta rechazada — mostrar mensaje amigable al usuario
157
+ return { error: err.message, code: err.code };
158
+ }
159
+ if (err instanceof Stripe.errors.StripeRateLimitError) {
160
+ // Reintentar con backoff exponencial
161
+ throw err;
162
+ }
163
+ if (err instanceof Stripe.errors.StripeInvalidRequestError) {
164
+ // Llamada a la API incorrecta — registrar y corregir el código
165
+ console.error('Invalid Stripe request:', err.message);
166
+ throw err;
167
+ }
168
+ // Otros errores: StripeAPIError, StripeConnectionError, StripeAuthenticationError
169
+ throw err;
170
+ }
171
+ ```
172
+
173
+ ## Ejemplo
174
+
175
+ **Usuario:** Implementar un flujo de checkout para un producto SaaS: crear un payment intent en el servidor, manejar el webhook al tener éxito para activar la suscripción y manejar pagos fallidos.
176
+
177
+ **Salida esperada:**
178
+ - `POST /api/checkout` — crea PaymentIntent, devuelve `clientSecret`
179
+ - `POST /api/webhooks/stripe` — verifica firma, maneja `payment_intent.succeeded` (actualización idempotente en BD), `payment_intent.payment_failed` (registrar + notificar)
180
+ - Metadata en PaymentIntent: `user_id`, `plan_id`, `order_id`
181
+ - Todos los importes en centavos, moneda explícita
182
+ - Versión de la API fijada
183
+ - Sin registro de datos sensibles
184
+
185
+ ---
186
+
187
+ > **Trabaja con nosotros:** Claudient está respaldado por [Uitbreiden](https://uitbreiden.com/) — construimos productos de IA y soluciones B2B con comunidades de desarrolladores. ¿Construyendo flujos de pago o monetizando productos de IA? [uitbreiden.com](https://uitbreiden.com/)
@@ -0,0 +1,187 @@
1
+ > 🇫🇷 This is the French translation. [English version](../stripe.md).
2
+
3
+ # Compétence Intégration Stripe
4
+
5
+ ## Quand activer
6
+ - Implémenter Stripe Checkout ou Payment Intents pour les paiements uniques
7
+ - Configurer les abonnements Stripe et les cycles de facturation
8
+ - Gérer les webhooks Stripe pour les événements de paiement
9
+ - Implémenter des remboursements, litiges ou annulations de paiement
10
+ - Configurer Stripe Connect pour les paiements marketplace/plateforme
11
+ - Déboguer des paiements échoués, des cartes refusées ou des problèmes de livraison de webhooks
12
+ - Implémenter la conformité SCA (Strong Customer Authentication)
13
+
14
+ ## Quand NE PAS utiliser
15
+ - PayPal, Braintree, Adyen, Mollie — fournisseurs de paiement différents avec des SDKs différents
16
+ - Paiements crypto
17
+ - Systèmes comptables internes ou de facturation sans passerelle de paiement
18
+ - Flux uniquement par virement bancaire / ACH (produit Stripe différent — Payment Elements s'applique toujours, mais le flux diffère)
19
+
20
+ ## Instructions
21
+
22
+ ### Ne jamais coder en dur ou logger des données de paiement
23
+ ```typescript
24
+ // NE JAMAIS logger les détails de carte, les objets payment intent complets, ou les PII clients
25
+ // MAUVAIS :
26
+ console.log('Payment intent:', paymentIntent); // Peut contenir des données sensibles
27
+
28
+ // BON :
29
+ console.log('Payment intent created:', paymentIntent.id, paymentIntent.status);
30
+ ```
31
+
32
+ ### Payment Intents — création côté serveur
33
+ ```typescript
34
+ import Stripe from 'stripe';
35
+
36
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
37
+ apiVersion: '2024-12-18.acacia', // Toujours épingler la version de l'API
38
+ });
39
+
40
+ // Créer le payment intent côté serveur — jamais côté client
41
+ export async function createPaymentIntent(
42
+ amount: number, // Toujours dans la plus petite unité monétaire (centimes pour USD)
43
+ currency: string,
44
+ customerId: string,
45
+ metadata: Record<string, string>
46
+ ): Promise<{ clientSecret: string; paymentIntentId: string }> {
47
+ const paymentIntent = await stripe.paymentIntents.create({
48
+ amount, // ex: 2999 = 29,99€
49
+ currency, // ex: 'usd', 'eur'
50
+ customer: customerId,
51
+ automatic_payment_methods: { enabled: true },
52
+ metadata, // Stocker vos IDs internes ici
53
+ idempotency_key: `pi_${customerId}_${Date.now()}`, // Prévenir les charges en doublon
54
+ });
55
+
56
+ return {
57
+ clientSecret: paymentIntent.client_secret!,
58
+ paymentIntentId: paymentIntent.id,
59
+ };
60
+ }
61
+ ```
62
+
63
+ ### Gestion des webhooks — toujours vérifier la signature
64
+ ```typescript
65
+ import { headers } from 'next/headers';
66
+
67
+ export async function POST(request: Request) {
68
+ const body = await request.text(); // Corps brut — pas de JSON parsé
69
+ const signature = headers().get('stripe-signature')!;
70
+
71
+ let event: Stripe.Event;
72
+ try {
73
+ event = stripe.webhooks.constructEvent(
74
+ body,
75
+ signature,
76
+ process.env.STRIPE_WEBHOOK_SECRET!
77
+ );
78
+ } catch (err) {
79
+ // Signature invalide — rejeter immédiatement
80
+ return new Response('Invalid signature', { status: 400 });
81
+ }
82
+
83
+ // Traiter de manière idempotente — les webhooks peuvent être livrés plus d'une fois
84
+ switch (event.type) {
85
+ case 'payment_intent.succeeded':
86
+ await handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
87
+ break;
88
+ case 'payment_intent.payment_failed':
89
+ await handlePaymentFailed(event.data.object as Stripe.PaymentIntent);
90
+ break;
91
+ case 'customer.subscription.deleted':
92
+ await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
93
+ break;
94
+ default:
95
+ // Logger mais ne pas lever d'erreur sur les événements inconnus — Stripe en ajoute de nouveaux au fil du temps
96
+ console.log(`Unhandled event type: ${event.type}`);
97
+ }
98
+
99
+ return new Response(null, { status: 200 });
100
+ }
101
+
102
+ // Toujours vérifier si déjà traité avant de modifier la DB
103
+ async function handlePaymentSucceeded(paymentIntent: Stripe.PaymentIntent) {
104
+ const orderId = paymentIntent.metadata.order_id;
105
+
106
+ // Vérification d'idempotence
107
+ const existing = await db.order.findUnique({ where: { id: orderId } });
108
+ if (existing?.status === 'paid') return; // Déjà traité
109
+
110
+ await db.order.update({
111
+ where: { id: orderId },
112
+ data: { status: 'paid', stripePaymentIntentId: paymentIntent.id }
113
+ });
114
+ }
115
+ ```
116
+
117
+ ### Abonnements
118
+ ```typescript
119
+ // Créer un abonnement
120
+ const subscription = await stripe.subscriptions.create({
121
+ customer: customerId,
122
+ items: [{ price: priceId }],
123
+ payment_behavior: 'default_incomplete', // Ne pas activer avant confirmation du paiement
124
+ expand: ['latest_invoice.payment_intent'],
125
+ });
126
+
127
+ // Événements webhook clés pour les abonnements :
128
+ // customer.subscription.created → provisionner l'accès
129
+ // customer.subscription.updated → gérer les changements de plan
130
+ // customer.subscription.deleted → révoquer l'accès
131
+ // invoice.payment_succeeded → étendre la période d'accès
132
+ // invoice.payment_failed → envoyer un email de relance, puis suspendre après la période de grâce
133
+ ```
134
+
135
+ ### Discipline du mode test
136
+ ```typescript
137
+ // Utiliser des numéros de carte de test en développement :
138
+ // Succès : 4242 4242 4242 4242
139
+ // Refus : 4000 0000 0000 0002
140
+ // Auth requise : 4000 0025 0000 3155
141
+ // Utiliser la CLI webhook de test : stripe listen --forward-to localhost:3000/api/webhooks/stripe
142
+
143
+ // Ne jamais utiliser des clés de test en production, ne jamais utiliser des clés live en développement
144
+ const isLiveMode = process.env.STRIPE_SECRET_KEY!.startsWith('sk_live_');
145
+ if (isLiveMode && process.env.NODE_ENV !== 'production') {
146
+ throw new Error('Live Stripe keys must not be used outside production');
147
+ }
148
+ ```
149
+
150
+ ### Gestion des erreurs
151
+ ```typescript
152
+ try {
153
+ const charge = await stripe.charges.create({ ... });
154
+ } catch (err) {
155
+ if (err instanceof Stripe.errors.StripeCardError) {
156
+ // Carte refusée — afficher un message convivial
157
+ return { error: err.message, code: err.code };
158
+ }
159
+ if (err instanceof Stripe.errors.StripeRateLimitError) {
160
+ // Réessayer avec backoff exponentiel
161
+ throw err;
162
+ }
163
+ if (err instanceof Stripe.errors.StripeInvalidRequestError) {
164
+ // Mauvais appel API — logger et corriger le code
165
+ console.error('Invalid Stripe request:', err.message);
166
+ throw err;
167
+ }
168
+ // Autres erreurs : StripeAPIError, StripeConnectionError, StripeAuthenticationError
169
+ throw err;
170
+ }
171
+ ```
172
+
173
+ ## Exemple
174
+
175
+ **Utilisateur :** Implémenter un flux de checkout pour un produit SaaS : créer un payment intent côté serveur, gérer le webhook au succès pour activer l'abonnement et gérer les paiements échoués.
176
+
177
+ **Sortie attendue :**
178
+ - `POST /api/checkout` — crée le PaymentIntent, retourne `clientSecret`
179
+ - `POST /api/webhooks/stripe` — vérifie la signature, gère `payment_intent.succeeded` (mise à jour DB idempotente), `payment_intent.payment_failed` (log + notification)
180
+ - Métadonnées sur le PaymentIntent : `user_id`, `plan_id`, `order_id`
181
+ - Tous les montants en centimes, devise explicite
182
+ - Version de l'API épinglée
183
+ - Pas de logging de données sensibles
184
+
185
+ ---
186
+
187
+ > **Travaillez avec nous :** Claudient est soutenu par [Uitbreiden](https://uitbreiden.com/) — nous construisons des produits IA et des solutions B2B avec des communautés de développeurs. Vous construisez des flux de paiement ou monétisez des produits IA ? [uitbreiden.com](https://uitbreiden.com/)