@aglyn/shared-util-email 1.0.0-beta.285 → 1.0.0-beta.287

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.
@@ -18,7 +18,13 @@
18
18
  *
19
19
  * The commerce plugin's POS hardware shop sends these to the person who
20
20
  * placed the order: the order received, the parcel shipped with its
21
- * tracking, and the parcel delivered with the way to set the reader up. The
21
+ * tracking, the parcel delivered with the way to set the reader up, and the
22
+ * order canceled and refunded before it shipped (by staff, or because the
23
+ * workspace was deleted or the buyer's account closed), a reader bought in
24
+ * person refunded by staff — and, for a reader bought in
25
+ * person at the platform's own store by someone with no account yet, the
26
+ * invitation to sign up with that address so the order joins their
27
+ * workspace on its own. The
22
28
  * platform is the seller, so they are SYSTEM emails in the platform's brand
23
29
  * (or the workspace's white label), not a store's own emails to its buyers.
24
30
  *
@@ -30,7 +36,11 @@
30
36
  *=========================================*/ export const POS_HARDWARE_EMAIL_KEYS = {
31
37
  received: 'pos-hardware-order-received',
32
38
  shipped: 'pos-hardware-order-shipped',
33
- delivered: 'pos-hardware-order-delivered'
39
+ delivered: 'pos-hardware-order-delivered',
40
+ canceled: 'pos-hardware-order-canceled',
41
+ refunded: 'pos-hardware-order-refunded',
42
+ invited: 'pos-hardware-sign-up-invite',
43
+ returnRefunded: 'pos-hardware-return-refunded'
34
44
  };
35
45
  const SOURCE = 'libs/plugins/commerce/src/lib/server/pos-hardware-notify.ts';
36
46
  /**
@@ -105,6 +115,36 @@ function tokens(origin) {
105
115
  name: 'order.setupUrl',
106
116
  description: 'The POS devices card, where a reader is added to a register',
107
117
  sample: `${origin}${SAMPLE_POS_PAGE}#pos-devices`
118
+ },
119
+ refunded: {
120
+ name: 'order.refunded',
121
+ description: 'What was refunded to the card, shipping and tax included',
122
+ sample: '$123.45'
123
+ },
124
+ cancelReason: {
125
+ name: 'order.cancelReason',
126
+ description: 'Who canceled the order, and why, as a sentence',
127
+ sample: 'We canceled your order because the Test Org workspace was deleted.'
128
+ },
129
+ refundedNow: {
130
+ name: 'order.refundedNow',
131
+ description: 'What this refund returned to the card, tax included',
132
+ sample: '$324.75'
133
+ },
134
+ paid: {
135
+ name: 'order.total',
136
+ description: 'What was paid at the register, tax included',
137
+ sample: '$324.75'
138
+ },
139
+ kept: {
140
+ name: 'order.kept',
141
+ description: 'What a return did not refund: the original shipping and any restocking fee',
142
+ sample: '$25.00'
143
+ },
144
+ signUpUrl: {
145
+ name: 'order.signUpUrl',
146
+ description: 'Where to create an account with this address',
147
+ sample: `${origin}/signup`
108
148
  }
109
149
  };
110
150
  }
@@ -303,6 +343,250 @@ export function posHardwareSystemEmailTemplates(origin) {
303
343
  ],
304
344
  footerReason: footer,
305
345
  source: SOURCE
346
+ },
347
+ {
348
+ key: POS_HARDWARE_EMAIL_KEYS.canceled,
349
+ name: 'Card reader order canceled and refunded',
350
+ description: 'Sent when a card reader order from the POS hardware shop is canceled ' + 'and refunded in full before it shipped: by the team from the staff ' + 'Hardware orders page when they choose to email the buyer, or because ' + 'the workspace that bought it was deleted or the account that placed ' + 'it was closed. Sent once per order.',
351
+ deliveredBy: 'resend',
352
+ defaultSubject: 'Your card reader order {{order.number}} was canceled and refunded',
353
+ mergeTokens: [
354
+ t.org,
355
+ t.site,
356
+ t.number,
357
+ t.items,
358
+ t.refunded,
359
+ t.cancelReason
360
+ ],
361
+ defaultBody: [
362
+ {
363
+ block: 'text',
364
+ text: '{{site.name}} · Order {{order.number}}',
365
+ variant: 'eyebrow'
366
+ },
367
+ {
368
+ block: 'text',
369
+ text: 'Your hardware order was canceled and refunded',
370
+ variant: 'heading'
371
+ },
372
+ {
373
+ block: 'text',
374
+ text: '{{order.cancelReason}} It had not shipped yet, so we refunded the full amount, shipping and tax included, to the card you paid with.',
375
+ variant: 'body'
376
+ },
377
+ {
378
+ block: 'text',
379
+ text: '{{order.items}}\nRefunded: {{order.refunded}}',
380
+ variant: 'details'
381
+ },
382
+ {
383
+ block: 'text',
384
+ text: 'What happens next',
385
+ variant: 'subheading'
386
+ },
387
+ {
388
+ block: 'text',
389
+ text: 'Nothing will ship, and there is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. If a parcel from this order arrives anyway, contact support before opening it and we will arrange its return.',
390
+ variant: 'body'
391
+ },
392
+ {
393
+ block: 'button',
394
+ label: 'Contact support',
395
+ href: '{{brand.supportUrl}}'
396
+ },
397
+ {
398
+ block: 'text',
399
+ text: 'Order {{order.number}} for {{org.name}}.',
400
+ variant: 'caption'
401
+ }
402
+ ],
403
+ footerReason: footer,
404
+ source: SOURCE
405
+ },
406
+ {
407
+ key: POS_HARDWARE_EMAIL_KEYS.refunded,
408
+ name: 'Card reader bought in person: refunded',
409
+ description: 'Sent when the team refunds card reader hardware someone bought in ' + 'person at the platform’s own store, from the staff Hardware orders ' + 'page, when they choose to email the buyer. Sent once per refund.',
410
+ deliveredBy: 'resend',
411
+ defaultSubject: 'Your refund for card reader order {{order.number}}',
412
+ mergeTokens: [
413
+ t.number,
414
+ t.items,
415
+ t.refundedNow,
416
+ t.refunded,
417
+ t.paid
418
+ ],
419
+ defaultBody: [
420
+ {
421
+ block: 'text',
422
+ text: 'Order {{order.number}}',
423
+ variant: 'eyebrow'
424
+ },
425
+ {
426
+ block: 'text',
427
+ text: 'We refunded your card reader purchase',
428
+ variant: 'heading'
429
+ },
430
+ {
431
+ block: 'text',
432
+ text: 'We refunded {{order.refundedNow}} for the card reader hardware you bought from {{brand.productName}} in person, to the card you paid with.',
433
+ variant: 'body'
434
+ },
435
+ {
436
+ block: 'text',
437
+ text: '{{order.items}}\nRefunded now: {{order.refundedNow}}\nRefunded in total: {{order.refunded}}\nPaid: {{order.total}}',
438
+ variant: 'details'
439
+ },
440
+ {
441
+ block: 'text',
442
+ text: 'What happens next',
443
+ variant: 'subheading'
444
+ },
445
+ {
446
+ block: 'text',
447
+ text: 'There is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. If the amount is not what you expected, contact support and quote the order number.',
448
+ variant: 'body'
449
+ },
450
+ {
451
+ block: 'button',
452
+ label: 'Contact support',
453
+ href: '{{brand.supportUrl}}'
454
+ },
455
+ {
456
+ block: 'text',
457
+ text: 'Order {{order.number}}, bought in person from {{brand.productName}}.',
458
+ variant: 'caption'
459
+ }
460
+ ],
461
+ footerReason: 'You’re receiving this because you bought card reader hardware from ' + '{{brand.productName}} in person and a refund was made on it.',
462
+ source: SOURCE
463
+ },
464
+ {
465
+ key: POS_HARDWARE_EMAIL_KEYS.returnRefunded,
466
+ name: 'Card reader order returned: refunded',
467
+ description: 'Sent when the team refunds a card reader order that was shipped to ' + 'the buyer and sent back after they asked to return it, from the staff ' + 'Hardware orders page, when they choose to email the buyer. Sent once ' + 'per refund.',
468
+ deliveredBy: 'resend',
469
+ defaultSubject: 'We refunded your returned card reader order {{order.number}}',
470
+ mergeTokens: [
471
+ t.org,
472
+ t.number,
473
+ t.items,
474
+ t.refundedNow,
475
+ t.kept,
476
+ t.total,
477
+ t.ordersUrl
478
+ ],
479
+ defaultBody: [
480
+ {
481
+ block: 'text',
482
+ text: 'Order {{order.number}}',
483
+ variant: 'eyebrow'
484
+ },
485
+ {
486
+ block: 'text',
487
+ text: 'Your return is refunded',
488
+ variant: 'heading'
489
+ },
490
+ {
491
+ block: 'text',
492
+ text: 'We received the card reader hardware you sent back and refunded {{order.refundedNow}} to the card you paid with: the price of the items and the tax on them.',
493
+ variant: 'body'
494
+ },
495
+ {
496
+ block: 'text',
497
+ text: '{{order.items}}\nRefunded: {{order.refundedNow}}\nNot refunded: {{order.kept}}\nPaid: {{order.total}}',
498
+ variant: 'details'
499
+ },
500
+ {
501
+ block: 'text',
502
+ text: 'What was not refunded',
503
+ variant: 'subheading'
504
+ },
505
+ {
506
+ block: 'text',
507
+ text: 'The original shipping is not refunded on a return, and any restocking fee charged for the return comes off the refund, as the hardware terms of sale say.',
508
+ variant: 'body'
509
+ },
510
+ {
511
+ block: 'text',
512
+ text: 'What happens next',
513
+ variant: 'subheading'
514
+ },
515
+ {
516
+ block: 'text',
517
+ text: 'There is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. The order shows as Refunded on the Hardware card.',
518
+ variant: 'body'
519
+ },
520
+ {
521
+ block: 'button',
522
+ label: 'Open the Hardware card',
523
+ href: '{{order.ordersUrl}}'
524
+ },
525
+ {
526
+ block: 'text',
527
+ text: 'If the amount is not what you expected, contact support and quote order {{order.number}}.',
528
+ variant: 'caption'
529
+ }
530
+ ],
531
+ footerReason: 'You’re receiving this because you ordered card reader hardware from ' + '{{brand.productName}} for {{org.name}} and returned it.',
532
+ source: SOURCE
533
+ },
534
+ {
535
+ key: POS_HARDWARE_EMAIL_KEYS.invited,
536
+ name: 'Card reader bought in person: create your account',
537
+ description: 'Sent to someone who bought a card reader in person from the platform ' + 'with no account yet, inviting them to sign up with the same address ' + 'so the order shows up in their workspace on its own.',
538
+ deliveredBy: 'resend',
539
+ defaultSubject: 'Your card reader from {{brand.productName}} is waiting for your account',
540
+ mergeTokens: [
541
+ t.number,
542
+ t.items,
543
+ t.paid,
544
+ t.signUpUrl
545
+ ],
546
+ defaultBody: [
547
+ {
548
+ block: 'text',
549
+ text: 'Order {{order.number}}',
550
+ variant: 'eyebrow'
551
+ },
552
+ {
553
+ block: 'text',
554
+ text: 'Your card reader is ready for your account',
555
+ variant: 'heading'
556
+ },
557
+ {
558
+ block: 'text',
559
+ text: 'Thanks for buying from us in person. Create your {{brand.productName}} account with this email address and the order shows up in your workspace on its own, ready to set up. There is nothing to accept.',
560
+ variant: 'body'
561
+ },
562
+ {
563
+ block: 'text',
564
+ text: '{{order.items}}\nPaid: {{order.total}}',
565
+ variant: 'details'
566
+ },
567
+ {
568
+ block: 'text',
569
+ text: 'What happens next',
570
+ variant: 'subheading'
571
+ },
572
+ {
573
+ block: 'text',
574
+ text: '1. Create your account with this email address.\n2. Create your workspace and your store.\n3. Open Products → Point of sale, where the order is waiting, and add the reader to a register with the pairing code it shows.',
575
+ variant: 'details'
576
+ },
577
+ {
578
+ block: 'button',
579
+ label: 'Create your account',
580
+ href: '{{order.signUpUrl}}'
581
+ },
582
+ {
583
+ block: 'text',
584
+ text: 'Taking card payments at the register comes with a plan that includes the point of sale. If you did not buy a card reader from {{brand.productName}}, you can ignore this email.',
585
+ variant: 'caption'
586
+ }
587
+ ],
588
+ footerReason: 'You’re receiving this because you bought card reader hardware from ' + '{{brand.productName}} in person and gave this address.',
589
+ source: SOURCE
306
590
  }
307
591
  ];
308
592
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/shared/util/email/src/lib/pos-hardware-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * A CARD READER BOUGHT FROM THE PLATFORM, AS SYSTEM EMAILS (AGL-4038).\n *\n * The commerce plugin's POS hardware shop sends these to the person who\n * placed the order: the order received, the parcel shipped with its\n * tracking, and the parcel delivered with the way to set the reader up. The\n * platform is the seller, so they are SYSTEM emails in the platform's brand\n * (or the workspace's white label), not a store's own emails to its buyers.\n *\n * They live here, beside the catalog, for the reason `domain-emails.ts`\n * gives: system emails have no plugin seam, and the staff System emails page\n * reads this registry before any plugin loads.\n *\n * Amounts and dates arrive formatted; a template never does arithmetic.\n *=========================================*/\n\nimport type {\n SystemEmailMergeToken,\n SystemEmailTemplateDefinition,\n} from './system-email-catalog'\n\nexport const POS_HARDWARE_EMAIL_KEYS = {\n received: 'pos-hardware-order-received',\n shipped: 'pos-hardware-order-shipped',\n delivered: 'pos-hardware-order-delivered',\n} as const\n\nconst SOURCE = 'libs/plugins/commerce/src/lib/server/pos-hardware-notify.ts'\n\n/**\n * The sample site's Point of sale page in the console, for the designer's\n * preview of the two links. It is a page a merchant opens, not a storage path,\n * so it is written as one value rather than spelled out beside each link.\n */\nconst SAMPLE_POS_PAGE = ['/test-org', 'hosts', 'test-bakery', 'products', 'pos'].join('/')\n\nfunction tokens(origin: string): Record<string, SystemEmailMergeToken> {\n return {\n org: { name: 'org.name', description: 'The workspace that placed the order', sample: 'Test Org' },\n site: { name: 'site.name', description: 'The site the order was placed from', sample: 'Test Bakery' },\n number: { name: 'order.number', description: 'The hardware order number', sample: 'HW-3F9A21' },\n items: {\n name: 'order.items',\n description: 'What was ordered, one line per item',\n sample: 'Stripe Reader S710 × 1\\nCharging dock for the S700 and S710 × 1',\n },\n total: { name: 'order.total', description: 'What was charged, shipping and tax included', sample: '$123.45' },\n shipTo: {\n name: 'order.shipTo',\n description: 'The name and address it ships to',\n sample: 'Alex Test\\n12 Main St\\nSpringfield, IL 62701',\n },\n shipping: { name: 'order.shippingMethod', description: 'The shipping speed chosen', sample: 'Standard shipping' },\n carrier: { name: 'order.carrier', description: 'The carrier delivering the parcel', sample: 'UPS' },\n trackingNumber: { name: 'order.trackingNumber', description: 'The parcel’s tracking number', sample: '1Z999AA10123456784' },\n trackingUrl: {\n name: 'order.trackingUrl',\n description: 'The carrier’s tracking page for the parcel',\n sample: 'https://www.ups.com/track?tracknum=1Z999AA10123456784',\n },\n ordersUrl: {\n name: 'order.ordersUrl',\n description: 'The Hardware card, where the order and its status are',\n sample: `${origin}${SAMPLE_POS_PAGE}#pos-hardware`,\n },\n setupUrl: {\n name: 'order.setupUrl',\n description: 'The POS devices card, where a reader is added to a register',\n sample: `${origin}${SAMPLE_POS_PAGE}#pos-devices`,\n },\n }\n}\n\nexport function posHardwareSystemEmailTemplates(\n origin: string,\n): SystemEmailTemplateDefinition[] {\n const t = tokens(origin)\n const footer =\n 'You’re receiving this because you ordered card reader hardware for ' +\n '{{site.name}} from {{brand.productName}}.'\n return [\n {\n key: POS_HARDWARE_EMAIL_KEYS.received,\n name: 'Card reader order received',\n description:\n 'Sent to the person who ordered card readers or accessories from the ' +\n 'POS hardware shop, once the payment goes through.',\n deliveredBy: 'resend',\n defaultSubject: 'We have your card reader order {{order.number}}',\n mergeTokens: [t.org, t.site, t.number, t.items, t.total, t.shipTo, t.shipping, t.ordersUrl],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware order is in', variant: 'heading' },\n { block: 'text', text: 'Thanks for your order. We place it with Stripe, which makes the readers and ships them straight to you. We will email you again with tracking as soon as it ships.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nShipping: {{order.shippingMethod}}\\nTotal charged: {{order.total}}', variant: 'details' },\n { block: 'text', text: 'Shipping to', variant: 'subheading' },\n { block: 'text', text: '{{order.shipTo}}', variant: 'details' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: 'While the order is being prepared you can follow it on the Hardware card in your point of sale settings. If something is wrong with the address, contact support before it ships: {{brand.supportUrl}}', variant: 'body' },\n { block: 'button', label: 'See your order', href: '{{order.ordersUrl}}' },\n { block: 'text', text: 'Order {{order.number}} for {{org.name}}.', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.shipped,\n name: 'Card reader order shipped',\n description:\n 'Sent when a card reader order from the POS hardware shop ships, with ' +\n 'the carrier and a tracking link.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader order {{order.number}} has shipped',\n mergeTokens: [\n t.org, t.site, t.number, t.items, t.shipTo, t.carrier, t.trackingNumber, t.trackingUrl, t.ordersUrl,\n ],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware is on its way', variant: 'heading' },\n { block: 'text', text: 'Your order left Stripe’s warehouse and is with {{order.carrier}}. Someone may need to sign for it, so keep an eye on the tracking page for the delivery day.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nCarrier: {{order.carrier}}\\nTracking number: {{order.trackingNumber}}', variant: 'details' },\n { block: 'button', label: 'Track your parcel', href: '{{order.trackingUrl}}' },\n { block: 'text', text: 'Before it arrives', variant: 'subheading' },\n { block: 'text', text: 'Pick the spot where the reader will live: it needs power and Wi-Fi, or a cellular signal for the S710. Once it is delivered, you add it to a register on the POS devices card in a minute.', variant: 'body' },\n { block: 'text', text: 'Shipping to: {{order.shipTo}}', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.delivered,\n name: 'Card reader order delivered',\n description:\n 'Sent when a card reader order from the POS hardware shop is delivered, ' +\n 'with the way to set the reader up at a register.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader order {{order.number}} was delivered',\n mergeTokens: [t.org, t.site, t.number, t.items, t.setupUrl, t.ordersUrl],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware has arrived', variant: 'heading' },\n { block: 'text', text: 'Your order was delivered. Here is how to start taking payments with it.', variant: 'body' },\n { block: 'text', text: '{{order.items}}', variant: 'details' },\n { block: 'text', text: 'Set up your reader', variant: 'subheading' },\n { block: 'text', text: '1. Charge it and switch it on.\\n2. Connect it to Wi-Fi from the reader’s Settings.\\n3. On the reader, generate a pairing code.\\n4. On the POS devices card, choose Add card reader and enter the code.', variant: 'details' },\n { block: 'button', label: 'Set up your reader', href: '{{order.setupUrl}}' },\n { block: 'text', text: 'The M2 pairs by Bluetooth from the {{brand.productName}} POS app instead. If anything arrived damaged, contact support: {{brand.supportUrl}}', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n ]\n}\n"],"names":["POS_HARDWARE_EMAIL_KEYS","received","shipped","delivered","SOURCE","SAMPLE_POS_PAGE","join","tokens","origin","org","name","description","sample","site","number","items","total","shipTo","shipping","carrier","trackingNumber","trackingUrl","ordersUrl","setupUrl","posHardwareSystemEmailTemplates","t","footer","key","deliveredBy","defaultSubject","mergeTokens","defaultBody","block","text","variant","label","href","footerReason","source"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/shared/util/email/src/lib/pos-hardware-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * A CARD READER BOUGHT FROM THE PLATFORM, AS SYSTEM EMAILS (AGL-4038).\n *\n * The commerce plugin's POS hardware shop sends these to the person who\n * placed the order: the order received, the parcel shipped with its\n * tracking, the parcel delivered with the way to set the reader up, and the\n * order canceled and refunded before it shipped (by staff, or because the\n * workspace was deleted or the buyer's account closed), a reader bought in\n * person refunded by staff — and, for a reader bought in\n * person at the platform's own store by someone with no account yet, the\n * invitation to sign up with that address so the order joins their\n * workspace on its own. The\n * platform is the seller, so they are SYSTEM emails in the platform's brand\n * (or the workspace's white label), not a store's own emails to its buyers.\n *\n * They live here, beside the catalog, for the reason `domain-emails.ts`\n * gives: system emails have no plugin seam, and the staff System emails page\n * reads this registry before any plugin loads.\n *\n * Amounts and dates arrive formatted; a template never does arithmetic.\n *=========================================*/\n\nimport type {\n SystemEmailMergeToken,\n SystemEmailTemplateDefinition,\n} from './system-email-catalog'\n\nexport const POS_HARDWARE_EMAIL_KEYS = {\n received: 'pos-hardware-order-received',\n shipped: 'pos-hardware-order-shipped',\n delivered: 'pos-hardware-order-delivered',\n canceled: 'pos-hardware-order-canceled',\n refunded: 'pos-hardware-order-refunded',\n invited: 'pos-hardware-sign-up-invite',\n returnRefunded: 'pos-hardware-return-refunded',\n} as const\n\nconst SOURCE = 'libs/plugins/commerce/src/lib/server/pos-hardware-notify.ts'\n\n/**\n * The sample site's Point of sale page in the console, for the designer's\n * preview of the two links. It is a page a merchant opens, not a storage path,\n * so it is written as one value rather than spelled out beside each link.\n */\nconst SAMPLE_POS_PAGE = ['/test-org', 'hosts', 'test-bakery', 'products', 'pos'].join('/')\n\nfunction tokens(origin: string): Record<string, SystemEmailMergeToken> {\n return {\n org: { name: 'org.name', description: 'The workspace that placed the order', sample: 'Test Org' },\n site: { name: 'site.name', description: 'The site the order was placed from', sample: 'Test Bakery' },\n number: { name: 'order.number', description: 'The hardware order number', sample: 'HW-3F9A21' },\n items: {\n name: 'order.items',\n description: 'What was ordered, one line per item',\n sample: 'Stripe Reader S710 × 1\\nCharging dock for the S700 and S710 × 1',\n },\n total: { name: 'order.total', description: 'What was charged, shipping and tax included', sample: '$123.45' },\n shipTo: {\n name: 'order.shipTo',\n description: 'The name and address it ships to',\n sample: 'Alex Test\\n12 Main St\\nSpringfield, IL 62701',\n },\n shipping: { name: 'order.shippingMethod', description: 'The shipping speed chosen', sample: 'Standard shipping' },\n carrier: { name: 'order.carrier', description: 'The carrier delivering the parcel', sample: 'UPS' },\n trackingNumber: { name: 'order.trackingNumber', description: 'The parcel’s tracking number', sample: '1Z999AA10123456784' },\n trackingUrl: {\n name: 'order.trackingUrl',\n description: 'The carrier’s tracking page for the parcel',\n sample: 'https://www.ups.com/track?tracknum=1Z999AA10123456784',\n },\n ordersUrl: {\n name: 'order.ordersUrl',\n description: 'The Hardware card, where the order and its status are',\n sample: `${origin}${SAMPLE_POS_PAGE}#pos-hardware`,\n },\n setupUrl: {\n name: 'order.setupUrl',\n description: 'The POS devices card, where a reader is added to a register',\n sample: `${origin}${SAMPLE_POS_PAGE}#pos-devices`,\n },\n refunded: {\n name: 'order.refunded',\n description: 'What was refunded to the card, shipping and tax included',\n sample: '$123.45',\n },\n cancelReason: {\n name: 'order.cancelReason',\n description: 'Who canceled the order, and why, as a sentence',\n sample: 'We canceled your order because the Test Org workspace was deleted.',\n },\n refundedNow: {\n name: 'order.refundedNow',\n description: 'What this refund returned to the card, tax included',\n sample: '$324.75',\n },\n paid: {\n name: 'order.total',\n description: 'What was paid at the register, tax included',\n sample: '$324.75',\n },\n kept: {\n name: 'order.kept',\n description: 'What a return did not refund: the original shipping and any restocking fee',\n sample: '$25.00',\n },\n signUpUrl: {\n name: 'order.signUpUrl',\n description: 'Where to create an account with this address',\n sample: `${origin}/signup`,\n },\n }\n}\n\nexport function posHardwareSystemEmailTemplates(\n origin: string,\n): SystemEmailTemplateDefinition[] {\n const t = tokens(origin)\n const footer =\n 'You’re receiving this because you ordered card reader hardware for ' +\n '{{site.name}} from {{brand.productName}}.'\n return [\n {\n key: POS_HARDWARE_EMAIL_KEYS.received,\n name: 'Card reader order received',\n description:\n 'Sent to the person who ordered card readers or accessories from the ' +\n 'POS hardware shop, once the payment goes through.',\n deliveredBy: 'resend',\n defaultSubject: 'We have your card reader order {{order.number}}',\n mergeTokens: [t.org, t.site, t.number, t.items, t.total, t.shipTo, t.shipping, t.ordersUrl],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware order is in', variant: 'heading' },\n { block: 'text', text: 'Thanks for your order. We place it with Stripe, which makes the readers and ships them straight to you. We will email you again with tracking as soon as it ships.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nShipping: {{order.shippingMethod}}\\nTotal charged: {{order.total}}', variant: 'details' },\n { block: 'text', text: 'Shipping to', variant: 'subheading' },\n { block: 'text', text: '{{order.shipTo}}', variant: 'details' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: 'While the order is being prepared you can follow it on the Hardware card in your point of sale settings. If something is wrong with the address, contact support before it ships: {{brand.supportUrl}}', variant: 'body' },\n { block: 'button', label: 'See your order', href: '{{order.ordersUrl}}' },\n { block: 'text', text: 'Order {{order.number}} for {{org.name}}.', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.shipped,\n name: 'Card reader order shipped',\n description:\n 'Sent when a card reader order from the POS hardware shop ships, with ' +\n 'the carrier and a tracking link.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader order {{order.number}} has shipped',\n mergeTokens: [\n t.org, t.site, t.number, t.items, t.shipTo, t.carrier, t.trackingNumber, t.trackingUrl, t.ordersUrl,\n ],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware is on its way', variant: 'heading' },\n { block: 'text', text: 'Your order left Stripe’s warehouse and is with {{order.carrier}}. Someone may need to sign for it, so keep an eye on the tracking page for the delivery day.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nCarrier: {{order.carrier}}\\nTracking number: {{order.trackingNumber}}', variant: 'details' },\n { block: 'button', label: 'Track your parcel', href: '{{order.trackingUrl}}' },\n { block: 'text', text: 'Before it arrives', variant: 'subheading' },\n { block: 'text', text: 'Pick the spot where the reader will live: it needs power and Wi-Fi, or a cellular signal for the S710. Once it is delivered, you add it to a register on the POS devices card in a minute.', variant: 'body' },\n { block: 'text', text: 'Shipping to: {{order.shipTo}}', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.delivered,\n name: 'Card reader order delivered',\n description:\n 'Sent when a card reader order from the POS hardware shop is delivered, ' +\n 'with the way to set the reader up at a register.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader order {{order.number}} was delivered',\n mergeTokens: [t.org, t.site, t.number, t.items, t.setupUrl, t.ordersUrl],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware has arrived', variant: 'heading' },\n { block: 'text', text: 'Your order was delivered. Here is how to start taking payments with it.', variant: 'body' },\n { block: 'text', text: '{{order.items}}', variant: 'details' },\n { block: 'text', text: 'Set up your reader', variant: 'subheading' },\n { block: 'text', text: '1. Charge it and switch it on.\\n2. Connect it to Wi-Fi from the reader’s Settings.\\n3. On the reader, generate a pairing code.\\n4. On the POS devices card, choose Add card reader and enter the code.', variant: 'details' },\n { block: 'button', label: 'Set up your reader', href: '{{order.setupUrl}}' },\n { block: 'text', text: 'The M2 pairs by Bluetooth from the {{brand.productName}} POS app instead. If anything arrived damaged, contact support: {{brand.supportUrl}}', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.canceled,\n name: 'Card reader order canceled and refunded',\n description:\n 'Sent when a card reader order from the POS hardware shop is canceled ' +\n 'and refunded in full before it shipped: by the team from the staff ' +\n 'Hardware orders page when they choose to email the buyer, or because ' +\n 'the workspace that bought it was deleted or the account that placed ' +\n 'it was closed. Sent once per order.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader order {{order.number}} was canceled and refunded',\n mergeTokens: [t.org, t.site, t.number, t.items, t.refunded, t.cancelReason],\n defaultBody: [\n { block: 'text', text: '{{site.name}} · Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your hardware order was canceled and refunded', variant: 'heading' },\n { block: 'text', text: '{{order.cancelReason}} It had not shipped yet, so we refunded the full amount, shipping and tax included, to the card you paid with.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nRefunded: {{order.refunded}}', variant: 'details' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: 'Nothing will ship, and there is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. If a parcel from this order arrives anyway, contact support before opening it and we will arrange its return.', variant: 'body' },\n { block: 'button', label: 'Contact support', href: '{{brand.supportUrl}}' },\n { block: 'text', text: 'Order {{order.number}} for {{org.name}}.', variant: 'caption' },\n ],\n footerReason: footer,\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.refunded,\n name: 'Card reader bought in person: refunded',\n description:\n 'Sent when the team refunds card reader hardware someone bought in ' +\n 'person at the platform’s own store, from the staff Hardware orders ' +\n 'page, when they choose to email the buyer. Sent once per refund.',\n deliveredBy: 'resend',\n defaultSubject: 'Your refund for card reader order {{order.number}}',\n mergeTokens: [t.number, t.items, t.refundedNow, t.refunded, t.paid],\n defaultBody: [\n { block: 'text', text: 'Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'We refunded your card reader purchase', variant: 'heading' },\n { block: 'text', text: 'We refunded {{order.refundedNow}} for the card reader hardware you bought from {{brand.productName}} in person, to the card you paid with.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nRefunded now: {{order.refundedNow}}\\nRefunded in total: {{order.refunded}}\\nPaid: {{order.total}}', variant: 'details' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: 'There is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. If the amount is not what you expected, contact support and quote the order number.', variant: 'body' },\n { block: 'button', label: 'Contact support', href: '{{brand.supportUrl}}' },\n { block: 'text', text: 'Order {{order.number}}, bought in person from {{brand.productName}}.', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because you bought card reader hardware from ' +\n '{{brand.productName}} in person and a refund was made on it.',\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.returnRefunded,\n name: 'Card reader order returned: refunded',\n description:\n 'Sent when the team refunds a card reader order that was shipped to ' +\n 'the buyer and sent back after they asked to return it, from the staff ' +\n 'Hardware orders page, when they choose to email the buyer. Sent once ' +\n 'per refund.',\n deliveredBy: 'resend',\n defaultSubject: 'We refunded your returned card reader order {{order.number}}',\n mergeTokens: [t.org, t.number, t.items, t.refundedNow, t.kept, t.total, t.ordersUrl],\n defaultBody: [\n { block: 'text', text: 'Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your return is refunded', variant: 'heading' },\n { block: 'text', text: 'We received the card reader hardware you sent back and refunded {{order.refundedNow}} to the card you paid with: the price of the items and the tax on them.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nRefunded: {{order.refundedNow}}\\nNot refunded: {{order.kept}}\\nPaid: {{order.total}}', variant: 'details' },\n { block: 'text', text: 'What was not refunded', variant: 'subheading' },\n { block: 'text', text: 'The original shipping is not refunded on a return, and any restocking fee charged for the return comes off the refund, as the hardware terms of sale say.', variant: 'body' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: 'There is nothing you need to do. Most banks show the refund on the card within 5 to 10 business days. The order shows as Refunded on the Hardware card.', variant: 'body' },\n { block: 'button', label: 'Open the Hardware card', href: '{{order.ordersUrl}}' },\n { block: 'text', text: 'If the amount is not what you expected, contact support and quote order {{order.number}}.', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because you ordered card reader hardware from ' +\n '{{brand.productName}} for {{org.name}} and returned it.',\n source: SOURCE,\n },\n {\n key: POS_HARDWARE_EMAIL_KEYS.invited,\n name: 'Card reader bought in person: create your account',\n description:\n 'Sent to someone who bought a card reader in person from the platform ' +\n 'with no account yet, inviting them to sign up with the same address ' +\n 'so the order shows up in their workspace on its own.',\n deliveredBy: 'resend',\n defaultSubject: 'Your card reader from {{brand.productName}} is waiting for your account',\n mergeTokens: [t.number, t.items, t.paid, t.signUpUrl],\n defaultBody: [\n { block: 'text', text: 'Order {{order.number}}', variant: 'eyebrow' },\n { block: 'text', text: 'Your card reader is ready for your account', variant: 'heading' },\n { block: 'text', text: 'Thanks for buying from us in person. Create your {{brand.productName}} account with this email address and the order shows up in your workspace on its own, ready to set up. There is nothing to accept.', variant: 'body' },\n { block: 'text', text: '{{order.items}}\\nPaid: {{order.total}}', variant: 'details' },\n { block: 'text', text: 'What happens next', variant: 'subheading' },\n { block: 'text', text: '1. Create your account with this email address.\\n2. Create your workspace and your store.\\n3. Open Products → Point of sale, where the order is waiting, and add the reader to a register with the pairing code it shows.', variant: 'details' },\n { block: 'button', label: 'Create your account', href: '{{order.signUpUrl}}' },\n { block: 'text', text: 'Taking card payments at the register comes with a plan that includes the point of sale. If you did not buy a card reader from {{brand.productName}}, you can ignore this email.', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because you bought card reader hardware from ' +\n '{{brand.productName}} in person and gave this address.',\n source: SOURCE,\n },\n ]\n}\n"],"names":["POS_HARDWARE_EMAIL_KEYS","received","shipped","delivered","canceled","refunded","invited","returnRefunded","SOURCE","SAMPLE_POS_PAGE","join","tokens","origin","org","name","description","sample","site","number","items","total","shipTo","shipping","carrier","trackingNumber","trackingUrl","ordersUrl","setupUrl","cancelReason","refundedNow","paid","kept","signUpUrl","posHardwareSystemEmailTemplates","t","footer","key","deliveredBy","defaultSubject","mergeTokens","defaultBody","block","text","variant","label","href","footerReason","source"],"mappings":"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"}
@@ -58,6 +58,7 @@ import { BRAND } from "@aglyn/shared-data-enums/aglyn";
58
58
  import { EMAIL_NODE_ROOT_ID } from "./email-render.js";
59
59
  import { domainSystemEmailTemplates } from "./domain-emails.js";
60
60
  import { posHardwareSystemEmailTemplates } from "./pos-hardware-emails.js";
61
+ import { posCellularSystemEmailTemplates } from "./pos-cellular-emails.js";
61
62
  import { RISK_NOTICE_SYSTEM_EMAIL_TEMPLATES } from "./risk-notice-emails.js";
62
63
  import { retentionSystemEmailTemplates } from "./retention-emails.js";
63
64
  import { SITE_CARE_SYSTEM_EMAIL_TEMPLATES } from "./site-care-emails.js";
@@ -2733,7 +2734,10 @@ const BASE_SYSTEM_EMAIL_TEMPLATES = [
2733
2734
  ...domainSystemEmailTemplates(SAMPLE_CONSOLE_ORIGIN),
2734
2735
  // Card readers bought from the commerce plugin's POS hardware shop
2735
2736
  // (AGL-4038), whose keys and copy live in `pos-hardware-emails.ts`.
2736
- ...posHardwareSystemEmailTemplates(SAMPLE_CONSOLE_ORIGIN)
2737
+ ...posHardwareSystemEmailTemplates(SAMPLE_CONSOLE_ORIGIN),
2738
+ // 4G for a workspace's card readers turned off for an unpaid month
2739
+ // (AGL-4038), whose key and copy live in `pos-cellular-emails.ts`.
2740
+ ...posCellularSystemEmailTemplates(SAMPLE_CONSOLE_ORIGIN)
2737
2741
  ].map((entry)=>_extends({}, entry, {
2738
2742
  mergeTokens: [
2739
2743
  ...entry.mergeTokens,