vault backup: 2026-05-15 16:27:02
This commit is contained in:
parent
946d68d739
commit
865b8a5c69
4 changed files with 161 additions and 1 deletions
|
|
@ -35,7 +35,7 @@ This 3-hop pattern works for hundreds of articles without vector search.
|
|||
| [[wiki/reports/_index\|reports/]] | Weekly and monthly summaries — generate: `uv run python scripts/report-generator.py --weekly` | 1 |
|
||||
| [[wiki/infrastructure/_index\|infrastructure/]] | Server inventory: all 10 SSH hosts — optical, optical-dev, optical-prod, baic, librechat, modocmms, box-cli, aimpress, pve | 12 |
|
||||
| [[wiki/testing/_index\|testing/]] | Web app testing: functional, performance, security, UI types; TDD/BDD/Agile methodologies; Selenium/Cypress/Playwright/JMeter/OWASP ZAP tools | 1 |
|
||||
| [[wiki/payloadcms/_index\|payloadcms/]] | Full Payload CMS reference — getting started, config, database (Postgres/MongoDB/SQLite), all 22 field types, access control, hooks, authentication (cookies, JWT, API keys, custom strategies, token data), admin UI, custom components, Lexical rich text, live preview, versions/drafts, Local/REST/GraphQL APIs, queries, plugins, jobs queue, upload, ecommerce, production deploy, TypeScript, migration guides, i18n, localization, hierarchy | 120 |
|
||||
| [[wiki/payloadcms/_index\|payloadcms/]] | Full Payload CMS reference — getting started, config, database (Postgres/MongoDB/SQLite), all 22 field types, access control, hooks, authentication (cookies, JWT, API keys, custom strategies, token data), admin UI, custom components, Lexical rich text, live preview, versions/drafts, Local/REST/GraphQL APIs, queries, plugins, jobs queue, upload, ecommerce, production deploy, TypeScript, migration guides, i18n, localization, hierarchy | 121 |
|
||||
|
||||
| [[wiki/shared-patterns/_index\|shared-patterns/]] | Oliver Agency standard library patterns: httpx, structlog, pydantic-settings, alembic — reuse before writing from scratch | 4 |
|
||||
| [[wiki/mistakes/_index\|mistakes/]] | Anti-patterns extracted from sessions — per-stack running lists (fastapi, react, docker, postgres, general) — injected at session start | 5 |
|
||||
|
|
|
|||
|
|
@ -122,3 +122,5 @@
|
|||
| [[wiki/payloadcms/plugin-redirects\|Redirects Plugin]] | Managed `redirects` collection (from/to + doc reference), redirect types (301/302), overrides pattern, frontend integration (Next.js middleware/redirects()) | raw/plugins__redirects.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/plugin-search\|Search Plugin]] | First-party search index: static `search` collection, hook-free queries, priority sorting, `beforeSync`/`skipSync`, on-demand reindex | raw/plugins__search.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/plugin-sentry\|Sentry Plugin]] | Sentry error tracking + performance monitoring: Next.js setup prerequisite, Postgres pg driver injection for DB traces, captureErrors, context callback | raw/plugins__sentry.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/plugin-seo\|SEO Plugin]] | `meta` field group (title/description/image) on collections/globals, auto-generate functions, real-time search preview, custom fields (og:title, json-ld), tabbedUI gotcha, direct field imports | raw/plugins__seo.md | 2026-05-15 |
|
||||
| [[wiki/payloadcms/plugin-stripe\|Stripe Plugin]] | Two-way Stripe↔Payload sync, webhook handlers, REST proxy (dev-only), `sync` auto-hooks, serverless `waitUntil` fix, `skipSync` loop prevention | raw/plugins__stripe.md | 2026-05-15 |
|
||||
|
|
|
|||
158
wiki/payloadcms/plugin-stripe.md
Normal file
158
wiki/payloadcms/plugin-stripe.md
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
---
|
||||
title: "Stripe Plugin"
|
||||
aliases: [payload-stripe, plugin-stripe, stripe-payments-payload]
|
||||
tags: [payloadcms, stripe, payments, ecommerce, plugin, webhooks, sync]
|
||||
sources: [raw/plugins__stripe.md]
|
||||
created: 2026-05-15
|
||||
updated: 2026-05-15
|
||||
---
|
||||
|
||||
# Stripe Plugin
|
||||
|
||||
Integrates [Stripe](https://stripe.com) billing into Payload CMS — two-way sync, webhook handling, and a proxied Stripe REST API behind Payload access control.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pnpm add @payloadcms/plugin-stripe
|
||||
```
|
||||
|
||||
## Basic Config
|
||||
|
||||
```ts
|
||||
import { stripePlugin } from '@payloadcms/plugin-stripe'
|
||||
|
||||
buildConfig({
|
||||
plugins: [
|
||||
stripePlugin({
|
||||
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `stripeSecretKey` * | string | — | Stripe secret key |
|
||||
| `stripeWebhooksEndpointSecret` | string | — | Webhook signing secret |
|
||||
| `rest` | boolean | `false` | Open `/api/stripe/rest` proxy (dev only) |
|
||||
| `webhooks` | object \| function | — | Webhook event handlers |
|
||||
| `sync` | array | — | Auto-sync configs between collections and Stripe resources |
|
||||
| `logs` | boolean | `false` | Log sync events to console |
|
||||
|
||||
## Auto-Opened Endpoints
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/api/stripe/rest` | POST | Proxied Stripe REST API (behind Payload access control) |
|
||||
| `/api/stripe/webhooks` | POST | Stripe webhook receiver |
|
||||
|
||||
## Webhooks Setup
|
||||
|
||||
**Dev:**
|
||||
```bash
|
||||
stripe login
|
||||
stripe listen --forward-to localhost:3000/api/stripe/webhooks
|
||||
# paste the secret into .env as STRIPE_WEBHOOKS_ENDPOINT_SECRET
|
||||
```
|
||||
|
||||
**Production:** Create webhook in Stripe dashboard → set URL to `YOUR_DOMAIN/api/stripe/webhooks` → paste secret into `.env`.
|
||||
|
||||
**Handler config:**
|
||||
```ts
|
||||
stripePlugin({
|
||||
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
||||
stripeWebhooksEndpointSecret: process.env.STRIPE_WEBHOOKS_ENDPOINT_SECRET,
|
||||
webhooks: {
|
||||
'customer.subscription.updated': ({ event, stripe, stripeConfig }) => {
|
||||
// handle event
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Serverless Warning
|
||||
|
||||
Stripe expects a `2xx` response within 10–20 seconds. The plugin processes webhooks asynchronously — in serverless environments the function instance may close before processing completes, causing duplicate events.
|
||||
|
||||
**Vercel fix:** install `@vercel/functions` — the plugin auto-detects it and wraps handlers in `waitUntil()`.
|
||||
|
||||
## Sync — Two-Way Auto-Sync
|
||||
|
||||
Maps Payload collection fields to Stripe resource properties. Hooks + webhook handlers are created automatically.
|
||||
|
||||
```ts
|
||||
stripePlugin({
|
||||
sync: [
|
||||
{
|
||||
collection: 'customers',
|
||||
stripeResourceType: 'customers',
|
||||
stripeResourceTypeSingular: 'customer',
|
||||
fields: [
|
||||
{ fieldPath: 'name', stripeProperty: 'name' },
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
**What `sync` does automatically:**
|
||||
- Adds read-only `stripeID` field (Stripe-generated cross-reference)
|
||||
- Adds direct link to resource on Stripe.com in admin
|
||||
- Adds read-only `skipSync` flag to prevent infinite loops
|
||||
- Attaches hooks: `beforeValidate: createNewInStripe`, `beforeChange: syncExistingWithStripe`, `afterDelete: deleteFromStripe`
|
||||
- Handles webhooks: `STRIPE_TYPE.created/updated/deleted`
|
||||
|
||||
> **Limitation:** Only top-level fields supported (Stripe API constraint).
|
||||
|
||||
## Server-Side Usage
|
||||
|
||||
Prefer direct Stripe SDK on server rather than the REST proxy:
|
||||
|
||||
```ts
|
||||
import Stripe from 'stripe'
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: '2022-08-01' })
|
||||
const customer = await stripe.customers.create({ email: data.email })
|
||||
```
|
||||
|
||||
Or use `stripeProxy` from the plugin:
|
||||
|
||||
```ts
|
||||
import { stripeProxy } from '@payloadcms/plugin-stripe'
|
||||
const customer = await stripeProxy({
|
||||
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
||||
stripeMethod: 'customers.create',
|
||||
stripeArgs: [{ email: data.email }],
|
||||
})
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
```ts
|
||||
import { StripeConfig, StripeWebhookHandler, StripeProxy } from '@payloadcms/plugin-stripe/types'
|
||||
```
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
- **Hides Stripe credentials** — client-side calls go through Payload's access control, never directly to Stripe
|
||||
- **REST proxy (`rest: true`) is dev-only** — opening it in production gives authenticated users full Stripe API access
|
||||
- **Two-way sync requires webhooks** — set `stripeWebhooksEndpointSecret` or changes from Stripe won't propagate to Payload
|
||||
- **Serverless + webhooks = `@vercel/functions`** — without it, async webhook handlers may be killed before completing
|
||||
- **`sync` only works on top-level Stripe fields** — nested fields require manual hooks
|
||||
- **`skipSync` flag prevents infinite loops** — sync hooks set it before triggering webhooks, webhooks check it before re-syncing
|
||||
- For e-commerce, pair with [[wiki/payloadcms/ecommerce|Ecommerce Plugin]] or [[wiki/payloadcms/ecommerce-payment-adapters|Payment Adapters]]
|
||||
|
||||
## Related
|
||||
|
||||
- [[wiki/payloadcms/plugins|Plugins Overview + Official]]
|
||||
- [[wiki/payloadcms/ecommerce|Ecommerce Plugin]]
|
||||
- [[wiki/payloadcms/ecommerce-payment-adapters|Ecommerce — Payment Adapters]]
|
||||
- [[wiki/payloadcms/access-control|Access Control]]
|
||||
- [[wiki/payloadcms/hooks-collections|Collection Hooks]]
|
||||
|
||||
## Sources
|
||||
|
||||
- `raw/plugins__stripe.md`
|
||||
- https://payloadcms.com/docs/plugins/stripe
|
||||
Loading…
Add table
Reference in a new issue