@spree/docs 0.1.58 → 0.1.59
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.
|
@@ -3,6 +3,8 @@ title: Customers
|
|
|
3
3
|
description: Customer accounts — registration, authentication, profiles, and guest checkout
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
import { Since } from '/snippets/since.mdx';
|
|
7
|
+
|
|
6
8
|
## Overview
|
|
7
9
|
|
|
8
10
|
Customers interact with your store through the Store API. They can register, log in, manage their profile, and view order history.
|
|
@@ -168,6 +170,59 @@ curl -X PATCH 'https://api.mystore.com/api/v3/store/customer/password_resets/RES
|
|
|
168
170
|
|
|
169
171
|
On success, the user is automatically logged in and a JWT token is returned. The reset token expires after 15 minutes (configurable via `Spree::Config.customer_password_reset_expires_in`) and is single-use (changing the password invalidates it).
|
|
170
172
|
|
|
173
|
+
## Newsletter Subscriptions
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
Headless storefronts often need to collect newsletter signups before account creation (footer forms, popup overlays). The Store API exposes a double opt-in subscription flow that mirrors the password reset webhook pattern.
|
|
177
|
+
|
|
178
|
+
### Step 1: Subscribe
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
```typescript SDK
|
|
182
|
+
await client.newsletterSubscribers.create({
|
|
183
|
+
email: 'guest@example.com',
|
|
184
|
+
redirect_url: 'https://myshop.com/newsletter/confirm',
|
|
185
|
+
})
|
|
186
|
+
// Returns the NewsletterSubscriber (verified: false for guests)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash cURL
|
|
190
|
+
curl -X POST 'https://api.mystore.com/api/v3/store/newsletter_subscribers' \
|
|
191
|
+
-H 'X-Spree-Api-Key: pk_xxx' \
|
|
192
|
+
-H 'Content-Type: application/json' \
|
|
193
|
+
-d '{
|
|
194
|
+
"email": "guest@example.com",
|
|
195
|
+
"redirect_url": "https://myshop.com/newsletter/confirm"
|
|
196
|
+
}'
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
The optional `redirect_url` points at the storefront page that will receive the verification token. It is validated against the store's [Allowed Origins](allowed-origins.md) — URLs that do not match are silently dropped from the webhook payload (secure-by-default).
|
|
201
|
+
|
|
202
|
+
This fires a `newsletter_subscriber.subscription_requested` event whose payload includes `email`, `verification_token`, and the validated `redirect_url`. Subscribe to this event from your storefront's webhook handler to send the confirmation email — the link in the email should point to `<redirect_url>?token=<verification_token>`. The bundled `spree_emails` package also listens to this event and sends a default confirmation email if you're not running a headless storefront.
|
|
203
|
+
|
|
204
|
+
If the request is authenticated via a customer JWT and the JWT's email matches the subscribed email, the subscription is **auto-verified** and no event is fired (the user has already proven email ownership).
|
|
205
|
+
|
|
206
|
+
### Step 2: Verify
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
```typescript SDK
|
|
210
|
+
await client.newsletterSubscribers.verify({
|
|
211
|
+
token: 'token-from-email',
|
|
212
|
+
})
|
|
213
|
+
// Returns the verified NewsletterSubscriber
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```bash cURL
|
|
217
|
+
curl -X POST 'https://api.mystore.com/api/v3/store/newsletter_subscribers/verify' \
|
|
218
|
+
-H 'X-Spree-Api-Key: pk_xxx' \
|
|
219
|
+
-H 'Content-Type: application/json' \
|
|
220
|
+
-d '{ "token": "token-from-email" }'
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
On success, the subscriber is marked verified. If the subscription is linked to a customer record, that customer's `accepts_email_marketing` flag is also set to `true`. Consent is preserved across registration: if a guest subscribes and later registers with the same email, the existing subscriber is reused — registration won't accidentally reset their opt-in state.
|
|
225
|
+
|
|
171
226
|
## Customer Profile
|
|
172
227
|
|
|
173
228
|
|
|
@@ -24,7 +24,7 @@ Spree Backend → Webhook POST → Storefront → render email → send via Rese
|
|
|
24
24
|
|
|
25
25
|
1. **Create a webhook endpoint** in Spree Admin → Settings → Developers → Webhooks:
|
|
26
26
|
- **URL:** `https://your-storefront.com/api/webhooks/spree`
|
|
27
|
-
- **Events:** `order.completed`, `order.canceled`, `order.shipped`, `customer.password_reset_requested`
|
|
27
|
+
- **Events:** `order.completed`, `order.canceled`, `order.shipped`, `customer.password_reset_requested`, `newsletter_subscriber.subscription_requested`
|
|
28
28
|
|
|
29
29
|
2. **Configure the storefront** with the webhook secret and email provider:
|
|
30
30
|
|
|
@@ -45,6 +45,7 @@ EMAIL_FROM=Your Store <orders@your-domain.com>
|
|
|
45
45
|
| `order.canceled` | Cancellation notice |
|
|
46
46
|
| `order.shipped` | Shipping notification with tracking link |
|
|
47
47
|
| `customer.password_reset_requested` | Password reset link |
|
|
48
|
+
| `newsletter_subscriber.subscription_requested` | Newsletter double opt-in confirmation link |
|
|
48
49
|
|
|
49
50
|
### Custom Frameworks
|
|
50
51
|
|
|
@@ -150,6 +150,7 @@ Email templates are React components in `src/lib/emails/`:
|
|
|
150
150
|
| `order-canceled.tsx` | `order.canceled` | Cancellation notice with items |
|
|
151
151
|
| `shipment-shipped.tsx` | `order.shipped` | Tracking number and link |
|
|
152
152
|
| `password-reset.tsx` | `customer.password_reset_requested` | Reset button and fallback link |
|
|
153
|
+
| `newsletter-confirmation.tsx` | `newsletter_subscriber.subscription_requested` | Double opt-in confirmation link |
|
|
153
154
|
|
|
154
155
|
Customize templates by editing these files directly. They use `@react-email/components` for email-safe layout primitives.
|
|
155
156
|
|
|
@@ -175,6 +176,7 @@ export const POST = createWebhookHandler({
|
|
|
175
176
|
'order.canceled': handleOrderCanceled,
|
|
176
177
|
'order.shipped': handleOrderShipped,
|
|
177
178
|
'customer.password_reset_requested': handlePasswordReset,
|
|
179
|
+
'newsletter_subscriber.subscription_requested': handleNewsletterConfirmation,
|
|
178
180
|
},
|
|
179
181
|
})
|
|
180
182
|
```
|