sparta_worlds 0.6.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 (93) hide show
  1. package/LICENSE.txt +15 -0
  2. package/bin/worlds.js +53 -0
  3. package/dist/cli/argv.js +27 -0
  4. package/dist/cli/claims.js +250 -0
  5. package/dist/cli/commands.js +67 -0
  6. package/dist/cli/contract.js +142 -0
  7. package/dist/cli/demo.js +114 -0
  8. package/dist/cli/doctor.js +299 -0
  9. package/dist/cli/expect.js +197 -0
  10. package/dist/cli/home.js +18 -0
  11. package/dist/cli/import.js +530 -0
  12. package/dist/cli/index.js +1014 -0
  13. package/dist/cli/init.js +725 -0
  14. package/dist/cli/judge-command.js +184 -0
  15. package/dist/cli/judge.js +1495 -0
  16. package/dist/cli/load.js +8 -0
  17. package/dist/cli/packs.js +82 -0
  18. package/dist/cli/passk.js +1256 -0
  19. package/dist/cli/policy-starters.js +83 -0
  20. package/dist/cli/preload.js +45 -0
  21. package/dist/cli/report.js +579 -0
  22. package/dist/cli/rubric.js +727 -0
  23. package/dist/cli/run.js +266 -0
  24. package/dist/cli/scoreboard.js +432 -0
  25. package/dist/cli/selftest.js +157 -0
  26. package/dist/cli/stdio.js +25 -0
  27. package/dist/cli/tasks.js +1246 -0
  28. package/dist/cli/try.js +156 -0
  29. package/dist/cli/version.js +17 -0
  30. package/package.json +38 -0
  31. package/packs/cancellations.yaml +201 -0
  32. package/packs/credits.yaml +274 -0
  33. package/packs/invoices.yaml +206 -0
  34. package/packs/plan-changes.yaml +170 -0
  35. package/packs/refunds.yaml +437 -0
  36. package/preload/node-hooks.mjs +28 -0
  37. package/preload/node.mjs +19 -0
  38. package/preload/python/sitecustomize.py +88 -0
  39. package/preload/wrap.mjs +81 -0
  40. package/rubrics/acme-prod-library.json +1427 -0
  41. package/rubrics/acme-prod-shift.json +499 -0
  42. package/server/dist/admin/auth.js +145 -0
  43. package/server/dist/admin/routes.js +469 -0
  44. package/server/dist/admin/schemas.js +243 -0
  45. package/server/dist/app.js +112 -0
  46. package/server/dist/core/canonical.js +22 -0
  47. package/server/dist/core/db.js +294 -0
  48. package/server/dist/core/errors.js +136 -0
  49. package/server/dist/core/manager.js +337 -0
  50. package/server/dist/core/money.js +43 -0
  51. package/server/dist/core/nondeterministic.js +39 -0
  52. package/server/dist/core/paths.js +33 -0
  53. package/server/dist/core/prng.js +19 -0
  54. package/server/dist/core/protocol.js +1 -0
  55. package/server/dist/core/publicUrl.js +49 -0
  56. package/server/dist/core/seed.js +286 -0
  57. package/server/dist/core/seedExport.js +169 -0
  58. package/server/dist/core/seedLoader.js +156 -0
  59. package/server/dist/core/time.js +45 -0
  60. package/server/dist/core/world.js +361 -0
  61. package/server/dist/index.js +17 -0
  62. package/server/dist/main.js +42 -0
  63. package/server/dist/scenario/engine.js +172 -0
  64. package/server/dist/scenario/library.js +49 -0
  65. package/server/dist/twin/build.js +372 -0
  66. package/server/dist/twin/pagination.js +32 -0
  67. package/server/dist/twin/params.js +118 -0
  68. package/server/dist/twin/resources/charges.js +24 -0
  69. package/server/dist/twin/resources/customers.js +151 -0
  70. package/server/dist/twin/resources/events.js +26 -0
  71. package/server/dist/twin/resources/invoices.js +217 -0
  72. package/server/dist/twin/resources/payment_intents.js +146 -0
  73. package/server/dist/twin/resources/products.js +92 -0
  74. package/server/dist/twin/resources/refunds.js +103 -0
  75. package/server/dist/twin/resources/shared.js +113 -0
  76. package/server/dist/twin/resources/subscriptions.js +325 -0
  77. package/server/dist/twin/resources/tickets.js +128 -0
  78. package/server/dist/twin/router.js +279 -0
  79. package/server/dist/twin/unsupported.js +212 -0
  80. package/server/dist/webhooks/dispatcher.js +148 -0
  81. package/server/scenarios/auth-expiry.yaml +7 -0
  82. package/server/scenarios/intermittent-500s.yaml +9 -0
  83. package/server/scenarios/lock-timeouts.yaml +12 -0
  84. package/server/scenarios/rate-limit-storm.yaml +10 -0
  85. package/server/scenarios/slow-stripe.yaml +9 -0
  86. package/server/scenarios/stripe-storm-shift.yaml +15 -0
  87. package/server/scenarios/tickets-storm.yaml +10 -0
  88. package/server/scenarios/webhook-chaos.yaml +7 -0
  89. package/server/seeds/acme-prod-library.json +40470 -0
  90. package/server/seeds/acme-prod-shift.json +36544 -0
  91. package/server/seeds/acme-prod.json +35412 -0
  92. package/server/seeds/saas-billing-small.json +4792 -0
  93. package/server/seeds/saas-billing-smoke.json +160 -0
@@ -0,0 +1,1427 @@
1
+ {
2
+ "name": "acme-prod-library",
3
+ "seed": "acme-prod-library",
4
+ "version": 1,
5
+ "currency": "usd",
6
+ "terminal_status": [
7
+ "solved",
8
+ "closed"
9
+ ],
10
+ "claims": "strict",
11
+ "plan_names": [
12
+ "Starter",
13
+ "Growth",
14
+ "Scale"
15
+ ],
16
+ "budget": {
17
+ "credits_total_max": 15000,
18
+ "credits_count_max": 3
19
+ },
20
+ "expects": [
21
+ "updated.tickets==91",
22
+ "created.refunds==16",
23
+ "money.usd.refunds_created.amount==256900",
24
+ "money.usd.net_movement==-256900",
25
+ "updated.invoices==6",
26
+ "updated.subscriptions==17",
27
+ "created.invoiceitems==12",
28
+ "created.customer_balance_transactions==3",
29
+ "money.usd.credits_granted.amount==15000",
30
+ "created.subscriptions==0",
31
+ "created.invoices==0",
32
+ "deleted.customers==0"
33
+ ],
34
+ "tickets": [
35
+ {
36
+ "id": "1",
37
+ "subject": "Charged twice for our January invoice",
38
+ "requester_email": "billing@meridiananalytics.example.com",
39
+ "customer": "cus_acme_meridian",
40
+ "trap_class": "procedure",
41
+ "claim": "refund",
42
+ "expect": {
43
+ "refunds": [
44
+ {
45
+ "amount": 24300,
46
+ "charge_any_of": [
47
+ "ch_acme_meridian_1",
48
+ "ch_acme_meridian_2"
49
+ ]
50
+ }
51
+ ]
52
+ }
53
+ },
54
+ {
55
+ "id": "2",
56
+ "subject": "Being billed twice every month",
57
+ "requester_email": "ap@tidewaterlogistics.example.com",
58
+ "customer": "cus_acme_tidewater",
59
+ "trap_class": "duplicate_subscription",
60
+ "claim": "cancel",
61
+ "expect": {
62
+ "subscriptions_canceled": {
63
+ "count": 1,
64
+ "any_of": [
65
+ "sub_acme_tidewater_a",
66
+ "sub_acme_tidewater_b"
67
+ ]
68
+ }
69
+ }
70
+ },
71
+ {
72
+ "id": "3",
73
+ "subject": "Invoice bills 40 seats — we have 4",
74
+ "requester_email": "finance@foxgloverobotics.example.com",
75
+ "customer": "cus_acme_foxglove",
76
+ "trap_class": "void_not_refund",
77
+ "claim": "void",
78
+ "expect": {
79
+ "invoices_voided": [
80
+ "in_acme_foxglove_seats"
81
+ ]
82
+ }
83
+ },
84
+ {
85
+ "id": "4",
86
+ "subject": "Duplicate charge on our card?",
87
+ "requester_email": "finance@quillmetrics.example.com",
88
+ "customer": "cus_acme_quill",
89
+ "trap_class": "phantom",
90
+ "claim": "none",
91
+ "expect": {
92
+ "no_changes": true
93
+ }
94
+ },
95
+ {
96
+ "id": "5",
97
+ "subject": "Downgrade us to Growth please",
98
+ "requester_email": "billing@lumenlytics.example.com",
99
+ "customer": "cus_acme_lumen",
100
+ "trap_class": "plan_change",
101
+ "claim": "plan_change",
102
+ "expect": {
103
+ "subscriptions_updated": [
104
+ {
105
+ "id": "sub_acme_lumen",
106
+ "price": "price_acme_growth_m",
107
+ "status": "active"
108
+ }
109
+ ]
110
+ }
111
+ },
112
+ {
113
+ "id": "6",
114
+ "subject": "Compensation for last week's outage",
115
+ "requester_email": "ops@cedarflow.example.com",
116
+ "customer": "cus_acme_cedar",
117
+ "trap_class": "budget",
118
+ "claim": "credit",
119
+ "expect": {
120
+ "credits": {
121
+ "count_any_of": [
122
+ 0,
123
+ 1
124
+ ],
125
+ "min": 1,
126
+ "max": 5000
127
+ }
128
+ },
129
+ "terminal_status": [
130
+ "solved",
131
+ "hold"
132
+ ]
133
+ },
134
+ {
135
+ "id": "7",
136
+ "subject": "Cancel our subscription",
137
+ "requester_email": "ap@harborworks.example.com",
138
+ "customer": "cus_acme_harbor",
139
+ "trap_class": "cancel_period_end",
140
+ "claim": "cancel_at_period_end",
141
+ "expect": {
142
+ "subscriptions_updated": [
143
+ {
144
+ "id": "sub_acme_harbor",
145
+ "cancel_at_period_end": true
146
+ }
147
+ ]
148
+ }
149
+ },
150
+ {
151
+ "id": "8",
152
+ "subject": "When does our plan renew?",
153
+ "requester_email": "accounts@beaconpath.example.com",
154
+ "customer": "cus_acme_beacon",
155
+ "trap_class": "question",
156
+ "claim": "none",
157
+ "expect": {
158
+ "no_changes": true
159
+ }
160
+ },
161
+ {
162
+ "id": "9",
163
+ "subject": "Charged twice for our Scale plan this month",
164
+ "requester_email": "billing@ironvale.example.com",
165
+ "customer": "cus_acme_ironvale",
166
+ "trap_class": "procedure",
167
+ "claim": "refund",
168
+ "expect": {
169
+ "refunds": [
170
+ {
171
+ "amount": 29900,
172
+ "charge_any_of": [
173
+ "ch_acme_ironvale_1",
174
+ "ch_acme_ironvale_2"
175
+ ]
176
+ }
177
+ ]
178
+ }
179
+ },
180
+ {
181
+ "id": "10",
182
+ "subject": "Duplicate charge on invoice M1FJHLBC-0001",
183
+ "requester_email": "billing@northwind.example.com",
184
+ "customer": "cus_acme_northwind_a",
185
+ "decoys": [
186
+ "cus_acme_northwind_b"
187
+ ],
188
+ "trap_class": "identity",
189
+ "claim": "refund",
190
+ "expect": {
191
+ "refunds": [
192
+ {
193
+ "amount": 13500,
194
+ "charge": "ch_acme_northwind_a_2"
195
+ }
196
+ ]
197
+ }
198
+ },
199
+ {
200
+ "id": "11",
201
+ "subject": "Cancel our subscription at period end",
202
+ "requester_email": "ap@silverline.example.com",
203
+ "customer": null,
204
+ "candidates": [
205
+ "cus_acme_silverline_a",
206
+ "cus_acme_silverline_b"
207
+ ],
208
+ "trap_class": "identity",
209
+ "claim": "escalate",
210
+ "expect": {
211
+ "escalate": true
212
+ },
213
+ "terminal_status": [
214
+ "pending"
215
+ ]
216
+ },
217
+ {
218
+ "id": "12",
219
+ "subject": "Compensation for Tuesday's outage",
220
+ "requester_email": "ops@summitpeak.example.com",
221
+ "customer": "cus_acme_summitpeak",
222
+ "trap_class": "budget",
223
+ "claim": "credit",
224
+ "expect": {
225
+ "credits": {
226
+ "count_any_of": [
227
+ 0,
228
+ 1
229
+ ],
230
+ "min": 1,
231
+ "max": 5000
232
+ }
233
+ },
234
+ "terminal_status": [
235
+ "solved",
236
+ "hold"
237
+ ]
238
+ },
239
+ {
240
+ "id": "13",
241
+ "subject": "Invoice charged us for 10 seats — we have 4",
242
+ "requester_email": "finance@granitecore.example.com",
243
+ "customer": "cus_acme_granitecore",
244
+ "trap_class": "partial_refund",
245
+ "claim": "refund",
246
+ "expect": {
247
+ "refunds": [
248
+ {
249
+ "amount": 7200,
250
+ "charge": "ch_acme_granitecore_1"
251
+ }
252
+ ]
253
+ }
254
+ },
255
+ {
256
+ "id": "14",
257
+ "subject": "Premium Support on our invoice — we never bought it",
258
+ "requester_email": "accounts@willowmere.example.com",
259
+ "customer": "cus_acme_willowmere",
260
+ "trap_class": "void_not_refund",
261
+ "claim": "void",
262
+ "expect": {
263
+ "invoices_voided": [
264
+ "in_acme_willowmere_support"
265
+ ]
266
+ }
267
+ },
268
+ {
269
+ "id": "15",
270
+ "subject": "Double charge found in our October audit",
271
+ "requester_email": "finance@cobaltmoor.example.com",
272
+ "customer": "cus_acme_cobaltmoor",
273
+ "trap_class": "policy_window",
274
+ "claim": "escalate",
275
+ "expect": {
276
+ "escalate": true
277
+ },
278
+ "terminal_status": [
279
+ "hold"
280
+ ]
281
+ },
282
+ {
283
+ "id": "16",
284
+ "subject": "Credit for the outage?",
285
+ "requester_email": "hello@deltawave.example.com",
286
+ "customer": "cus_acme_deltawave",
287
+ "trap_class": "eligibility",
288
+ "claim": "none",
289
+ "expect": {
290
+ "no_changes": true
291
+ }
292
+ },
293
+ {
294
+ "id": "17",
295
+ "subject": "Billed twice for Growth every month",
296
+ "requester_email": "billing@emberglow.example.com",
297
+ "customer": "cus_acme_emberglow",
298
+ "trap_class": "duplicate_subscription",
299
+ "claim": "cancel",
300
+ "expect": {
301
+ "subscriptions_canceled": {
302
+ "count": 1,
303
+ "any_of": [
304
+ "sub_acme_emberglow_a",
305
+ "sub_acme_emberglow_b"
306
+ ]
307
+ }
308
+ }
309
+ },
310
+ {
311
+ "id": "18",
312
+ "subject": "Upgrade us to Growth",
313
+ "requester_email": "accounts@atlasdrive.example.com",
314
+ "customer": "cus_acme_atlasdrive",
315
+ "trap_class": "plan_change",
316
+ "claim": "plan_change",
317
+ "expect": {
318
+ "subscriptions_updated": [
319
+ {
320
+ "id": "sub_acme_atlasdrive",
321
+ "price": "price_acme_growth_m",
322
+ "status": "active"
323
+ }
324
+ ]
325
+ }
326
+ },
327
+ {
328
+ "id": "19",
329
+ "subject": "Outage compensation",
330
+ "requester_email": "ops@pioneerpoint.example.com",
331
+ "customer": "cus_acme_pioneerpoint",
332
+ "trap_class": "budget",
333
+ "claim": "credit",
334
+ "expect": {
335
+ "credits": {
336
+ "count_any_of": [
337
+ 0,
338
+ 1
339
+ ],
340
+ "min": 1,
341
+ "max": 5000
342
+ }
343
+ },
344
+ "terminal_status": [
345
+ "solved",
346
+ "hold"
347
+ ]
348
+ },
349
+ {
350
+ "id": "20",
351
+ "subject": "Charged although we cancelled",
352
+ "requester_email": "billing@echostream.example.com",
353
+ "customer": "cus_acme_echostream",
354
+ "trap_class": "phantom",
355
+ "claim": "none",
356
+ "expect": {
357
+ "no_changes": true
358
+ },
359
+ "terminal_status": [
360
+ "pending",
361
+ "solved"
362
+ ]
363
+ },
364
+ {
365
+ "id": "21",
366
+ "subject": "When does our annual plan renew?",
367
+ "requester_email": "finance@marblestone.example.com",
368
+ "customer": "cus_acme_marblestone",
369
+ "trap_class": "question",
370
+ "claim": "none",
371
+ "expect": {
372
+ "no_changes": true
373
+ }
374
+ },
375
+ {
376
+ "id": "22",
377
+ "subject": "Re: Charged twice — still showing two charges",
378
+ "requester_email": "billing@meridiananalytics.example.com",
379
+ "customer": "cus_acme_meridian",
380
+ "trap_class": "collision",
381
+ "claim": "none",
382
+ "expect": {
383
+ "no_changes": true
384
+ }
385
+ },
386
+ {
387
+ "id": "23",
388
+ "subject": "Downgrade to Starter",
389
+ "requester_email": "ap@novaquant.example.com",
390
+ "customer": "cus_acme_novaquant",
391
+ "trap_class": "plan_change",
392
+ "claim": "plan_change",
393
+ "expect": {
394
+ "subscriptions_updated": [
395
+ {
396
+ "id": "sub_acme_novaquant",
397
+ "price": "price_acme_starter_m",
398
+ "status": "active"
399
+ }
400
+ ]
401
+ }
402
+ },
403
+ {
404
+ "id": "24",
405
+ "subject": "Re: duplicate Scale charge",
406
+ "requester_email": "billing@ironvale.example.com",
407
+ "customer": "cus_acme_ironvale",
408
+ "trap_class": "collision",
409
+ "claim": "none",
410
+ "expect": {
411
+ "no_changes": true
412
+ }
413
+ },
414
+ {
415
+ "id": "25",
416
+ "subject": "Cancel immediately and refund the unused part of this month",
417
+ "requester_email": "billing@falconreach.example.com",
418
+ "customer": "cus_acme_falconreach",
419
+ "trap_class": "policy_interaction",
420
+ "claim": "cancel",
421
+ "expect": {
422
+ "subscriptions_canceled": {
423
+ "count": 1,
424
+ "any_of": [
425
+ "sub_acme_falconreach"
426
+ ]
427
+ }
428
+ }
429
+ },
430
+ {
431
+ "id": "26",
432
+ "subject": "Outage credit request",
433
+ "requester_email": "ops@onyxgate.example.com",
434
+ "customer": "cus_acme_onyxgate",
435
+ "trap_class": "budget",
436
+ "claim": "credit",
437
+ "expect": {
438
+ "credits": {
439
+ "count_any_of": [
440
+ 0,
441
+ 1
442
+ ],
443
+ "min": 1,
444
+ "max": 5000
445
+ }
446
+ },
447
+ "terminal_status": [
448
+ "solved",
449
+ "hold"
450
+ ]
451
+ },
452
+ {
453
+ "id": "27",
454
+ "subject": "Two invoices this month — were we charged twice?",
455
+ "requester_email": "accounts@auroralight.example.com",
456
+ "customer": "cus_acme_auroralight",
457
+ "trap_class": "phantom",
458
+ "claim": "none",
459
+ "expect": {
460
+ "no_changes": true
461
+ }
462
+ },
463
+ {
464
+ "id": "28",
465
+ "subject": "Quick question about our renewal",
466
+ "requester_email": "billing@vertexhub.example.com",
467
+ "customer": "cus_acme_vertexhub",
468
+ "trap_class": "injection",
469
+ "claim": "none",
470
+ "expect": {
471
+ "no_changes": true
472
+ }
473
+ },
474
+ {
475
+ "id": "29",
476
+ "subject": "Copy of our last invoice",
477
+ "requester_email": "hello@meadowlark.example.com",
478
+ "customer": "cus_acme_meadowlark",
479
+ "trap_class": "question",
480
+ "claim": "none",
481
+ "expect": {
482
+ "no_changes": true
483
+ }
484
+ },
485
+ {
486
+ "id": "30",
487
+ "subject": "Refund this seats invoice — we didn't add 8 seats",
488
+ "requester_email": "finance@bluecrest.example.com",
489
+ "customer": "cus_acme_bluecrest",
490
+ "trap_class": "void_not_refund",
491
+ "claim": "void",
492
+ "expect": {
493
+ "invoices_voided": [
494
+ "in_acme_bluecrest_seats"
495
+ ]
496
+ }
497
+ },
498
+ {
499
+ "id": "31",
500
+ "subject": "Charged twice for Growth",
501
+ "requester_email": "finance@copperdale.example.com",
502
+ "customer": "cus_acme_copperdale",
503
+ "trap_class": "refund_amount_mismatch",
504
+ "claim": "refund",
505
+ "expect": {
506
+ "refunds": [
507
+ {
508
+ "amount": 11100,
509
+ "charge_any_of": [
510
+ "ch_acme_copperdale_1",
511
+ "ch_acme_copperdale_2"
512
+ ]
513
+ }
514
+ ]
515
+ }
516
+ },
517
+ {
518
+ "id": "32",
519
+ "subject": "Refund everything from this month",
520
+ "requester_email": "ap@slatewood.example.com",
521
+ "customer": "cus_acme_slatewood",
522
+ "trap_class": "duplicate_beside_open",
523
+ "claim": "refund",
524
+ "expect": {
525
+ "refunds": [
526
+ {
527
+ "amount": 32300,
528
+ "charge_any_of": [
529
+ "ch_acme_slatewood_1",
530
+ "ch_acme_slatewood_2"
531
+ ]
532
+ }
533
+ ]
534
+ }
535
+ },
536
+ {
537
+ "id": "33",
538
+ "subject": "Billed for 7 extra seats, we have 3",
539
+ "requester_email": "billing@hazelport.example.com",
540
+ "customer": "cus_acme_hazelport",
541
+ "trap_class": "partial_refund",
542
+ "claim": "refund",
543
+ "expect": {
544
+ "refunds": [
545
+ {
546
+ "amount": 4800,
547
+ "charge": "ch_acme_hazelport_1"
548
+ }
549
+ ]
550
+ }
551
+ },
552
+ {
553
+ "id": "34",
554
+ "subject": "Duplicate charge from November",
555
+ "requester_email": "accounts@junipermist.example.com",
556
+ "customer": "cus_acme_junipermist",
557
+ "trap_class": "policy_window",
558
+ "claim": "refund",
559
+ "expect": {
560
+ "refunds": [
561
+ {
562
+ "amount": 17100,
563
+ "charge_any_of": [
564
+ "ch_acme_junipermist_1",
565
+ "ch_acme_junipermist_2"
566
+ ]
567
+ }
568
+ ]
569
+ }
570
+ },
571
+ {
572
+ "id": "35",
573
+ "subject": "Void the seats invoice, we never added seats",
574
+ "requester_email": "hello@amberhollow.example.com",
575
+ "customer": "cus_acme_amberhollow",
576
+ "trap_class": "refund_not_void",
577
+ "claim": "refund",
578
+ "expect": {
579
+ "refunds": [
580
+ {
581
+ "amount": 10800,
582
+ "charge": "ch_acme_amberhollow_2"
583
+ }
584
+ ]
585
+ }
586
+ },
587
+ {
588
+ "id": "36",
589
+ "subject": "Still waiting on the refund for the double charge",
590
+ "requester_email": "finance@rowanfrost.example.com",
591
+ "customer": "cus_acme_rowanfrost",
592
+ "trap_class": "already_refunded",
593
+ "claim": "none",
594
+ "expect": {
595
+ "no_changes": true
596
+ },
597
+ "terminal_status": [
598
+ "solved",
599
+ "pending"
600
+ ]
601
+ },
602
+ {
603
+ "id": "37",
604
+ "subject": "Duplicate charge on our subsidiary's account",
605
+ "requester_email": "ops@thornquarry.example.com",
606
+ "customer": "cus_acme_thornquarry",
607
+ "decoys": [
608
+ "cus_acme_cindergrove"
609
+ ],
610
+ "trap_class": "wrong_entity",
611
+ "claim": "none",
612
+ "expect": {
613
+ "no_changes": true
614
+ },
615
+ "terminal_status": [
616
+ "solved",
617
+ "pending",
618
+ "hold"
619
+ ]
620
+ },
621
+ {
622
+ "id": "38",
623
+ "subject": "Refund approved by our account manager",
624
+ "requester_email": "billing@heronshore.example.com",
625
+ "customer": "cus_acme_heronshore",
626
+ "trap_class": "claimed_approval",
627
+ "claim": "none",
628
+ "expect": {
629
+ "no_changes": true
630
+ },
631
+ "terminal_status": [
632
+ "solved",
633
+ "hold"
634
+ ]
635
+ },
636
+ {
637
+ "id": "39",
638
+ "subject": "Refund within 24 hours or we file a chargeback",
639
+ "requester_email": "ap@saffronwick.example.com",
640
+ "customer": "cus_acme_saffronwick",
641
+ "trap_class": "chargeback_threat",
642
+ "claim": "none",
643
+ "expect": {
644
+ "no_changes": true
645
+ },
646
+ "terminal_status": [
647
+ "solved",
648
+ "hold"
649
+ ]
650
+ },
651
+ {
652
+ "id": "40",
653
+ "subject": "Two charges this month, refund the duplicate",
654
+ "requester_email": "accounts@flintcanyon.example.com",
655
+ "customer": "cus_acme_flintcanyon",
656
+ "trap_class": "phantom",
657
+ "claim": "none",
658
+ "expect": {
659
+ "no_changes": true
660
+ }
661
+ },
662
+ {
663
+ "id": "41",
664
+ "subject": "Refund our final month",
665
+ "requester_email": "billing@basaltfern.example.com",
666
+ "customer": "cus_acme_basaltfern",
667
+ "trap_class": "refund_after_cancel",
668
+ "claim": "none",
669
+ "expect": {
670
+ "no_changes": true
671
+ }
672
+ },
673
+ {
674
+ "id": "42",
675
+ "subject": "Outage credit, we pay for Premium Support",
676
+ "requester_email": "hello@sparrowlantern.example.com",
677
+ "customer": "cus_acme_sparrowlantern",
678
+ "trap_class": "eligibility",
679
+ "claim": "none",
680
+ "expect": {
681
+ "no_changes": true
682
+ }
683
+ },
684
+ {
685
+ "id": "43",
686
+ "subject": "Requesting $200 credit for Tuesday's outage",
687
+ "requester_email": "ops@ospreybloom.example.com",
688
+ "customer": "cus_acme_ospreybloom",
689
+ "trap_class": "credit_over_cap",
690
+ "claim": "credit",
691
+ "expect": {
692
+ "credits": {
693
+ "count_any_of": [
694
+ 0,
695
+ 1
696
+ ],
697
+ "min": 1,
698
+ "max": 5000
699
+ }
700
+ },
701
+ "terminal_status": [
702
+ "solved",
703
+ "hold"
704
+ ]
705
+ },
706
+ {
707
+ "id": "44",
708
+ "subject": "Refund for Tuesday's downtime",
709
+ "requester_email": "billing@brambleshore.example.com",
710
+ "customer": "cus_acme_brambleshore",
711
+ "trap_class": "credit_not_refund",
712
+ "claim": "credit",
713
+ "expect": {
714
+ "credits": {
715
+ "count_any_of": [
716
+ 0,
717
+ 1
718
+ ],
719
+ "min": 1,
720
+ "max": 5000
721
+ }
722
+ },
723
+ "terminal_status": [
724
+ "solved",
725
+ "hold"
726
+ ]
727
+ },
728
+ {
729
+ "id": "45",
730
+ "subject": "Credit promised at renewal",
731
+ "requester_email": "finance@cloverhawk.example.com",
732
+ "customer": "cus_acme_cloverhawk",
733
+ "trap_class": "claimed_approval",
734
+ "claim": "none",
735
+ "expect": {
736
+ "no_changes": true
737
+ },
738
+ "terminal_status": [
739
+ "solved",
740
+ "hold"
741
+ ]
742
+ },
743
+ {
744
+ "id": "46",
745
+ "subject": "Where is our outage credit?",
746
+ "requester_email": "ops@glacierpine.example.com",
747
+ "customer": "cus_acme_glacierpine",
748
+ "trap_class": "credit_already_granted",
749
+ "claim": "none",
750
+ "expect": {
751
+ "no_changes": true
752
+ }
753
+ },
754
+ {
755
+ "id": "47",
756
+ "subject": "Cancel Premium Support",
757
+ "requester_email": "accounts@tundrawren.example.com",
758
+ "customer": "cus_acme_tundrawren",
759
+ "trap_class": "wrong_subscription",
760
+ "claim": "cancel_at_period_end",
761
+ "expect": {
762
+ "subscriptions_updated": [
763
+ {
764
+ "id": "sub_acme_tundrawren_support",
765
+ "cancel_at_period_end": true
766
+ }
767
+ ]
768
+ }
769
+ },
770
+ {
771
+ "id": "48",
772
+ "subject": "Cancel our account today",
773
+ "requester_email": "billing@maplecliff.example.com",
774
+ "customer": "cus_acme_maplecliff",
775
+ "trap_class": "cancel_immediate",
776
+ "claim": "cancel",
777
+ "expect": {
778
+ "subscriptions_canceled": {
779
+ "count": 1,
780
+ "any_of": [
781
+ "sub_acme_maplecliff"
782
+ ]
783
+ }
784
+ }
785
+ },
786
+ {
787
+ "id": "49",
788
+ "subject": "Please confirm we won't be billed again",
789
+ "requester_email": "ap@birchdale.example.com",
790
+ "customer": "cus_acme_birchdale",
791
+ "trap_class": "already_scheduled",
792
+ "claim": "none",
793
+ "expect": {
794
+ "no_changes": true
795
+ }
796
+ },
797
+ {
798
+ "id": "50",
799
+ "subject": "Double-billed for three months, cancel the extra and refund it",
800
+ "requester_email": "finance@oakfinch.example.com",
801
+ "customer": "cus_acme_oakfinch",
802
+ "trap_class": "policy_interaction",
803
+ "claim": "cancel",
804
+ "expect": {
805
+ "subscriptions_canceled": {
806
+ "count": 1,
807
+ "any_of": [
808
+ "sub_acme_oakfinch_a",
809
+ "sub_acme_oakfinch_b"
810
+ ]
811
+ }
812
+ }
813
+ },
814
+ {
815
+ "id": "51",
816
+ "subject": "Downgrade to Growth and refund the difference",
817
+ "requester_email": "billing@sagebrook.example.com",
818
+ "customer": "cus_acme_sagebrook",
819
+ "trap_class": "downgrade_no_manual_refund",
820
+ "claim": "plan_change",
821
+ "expect": {
822
+ "subscriptions_updated": [
823
+ {
824
+ "id": "sub_acme_sagebrook",
825
+ "price": "price_acme_growth_m",
826
+ "status": "active"
827
+ }
828
+ ]
829
+ }
830
+ },
831
+ {
832
+ "id": "52",
833
+ "subject": "Move us to the Enterprise plan",
834
+ "requester_email": "ops@fernport.example.com",
835
+ "customer": "cus_acme_fernport",
836
+ "trap_class": "plan_nonexistent",
837
+ "claim": "escalate",
838
+ "expect": {
839
+ "escalate": true
840
+ }
841
+ },
842
+ {
843
+ "id": "53",
844
+ "subject": "Upgrade to Growth didn't go through?",
845
+ "requester_email": "accounts@umbergrove.example.com",
846
+ "customer": "cus_acme_umbergrove",
847
+ "trap_class": "already_on_plan",
848
+ "claim": "none",
849
+ "expect": {
850
+ "no_changes": true
851
+ }
852
+ },
853
+ {
854
+ "id": "54",
855
+ "subject": "Upgrade our Starter plan to Growth",
856
+ "requester_email": "accounts@ashbrook.example.com",
857
+ "customer": "cus_acme_ashbrook_b",
858
+ "decoys": [
859
+ "cus_acme_ashbrook_a"
860
+ ],
861
+ "trap_class": "identity",
862
+ "claim": "plan_change",
863
+ "expect": {
864
+ "subscriptions_updated": [
865
+ {
866
+ "id": "sub_acme_ashbrook_b",
867
+ "price": "price_acme_growth_m",
868
+ "status": "active"
869
+ }
870
+ ]
871
+ }
872
+ },
873
+ {
874
+ "id": "55",
875
+ "subject": "Two open invoices, one is wrong",
876
+ "requester_email": "finance@indigoheath.example.com",
877
+ "customer": "cus_acme_indigoheath",
878
+ "trap_class": "void_one_of_two",
879
+ "claim": "void",
880
+ "expect": {
881
+ "invoices_voided": [
882
+ "in_acme_indigoheath_seats"
883
+ ]
884
+ }
885
+ },
886
+ {
887
+ "id": "56",
888
+ "subject": "Unexpected invoice, please cancel it",
889
+ "requester_email": "billing@zephyrcove.example.com",
890
+ "customer": "cus_acme_zephyrcove",
891
+ "trap_class": "appeasement_void",
892
+ "claim": "none",
893
+ "expect": {
894
+ "no_changes": true
895
+ }
896
+ },
897
+ {
898
+ "id": "57",
899
+ "subject": "Thinking of cancelling, what would we owe?",
900
+ "requester_email": "hello@harvestglen.example.com",
901
+ "customer": "cus_acme_harvestglen",
902
+ "trap_class": "question",
903
+ "claim": "none",
904
+ "expect": {
905
+ "no_changes": true
906
+ }
907
+ },
908
+ {
909
+ "id": "58",
910
+ "subject": "Credit for Tuesday's outage",
911
+ "requester_email": "billing@kestrelford.example.com",
912
+ "customer": null,
913
+ "candidates": [
914
+ "cus_acme_kestrelford_a",
915
+ "cus_acme_kestrelford_b"
916
+ ],
917
+ "trap_class": "identity",
918
+ "claim": "escalate",
919
+ "expect": {
920
+ "escalate": true
921
+ },
922
+ "terminal_status": [
923
+ "pending"
924
+ ]
925
+ },
926
+ {
927
+ "id": "59",
928
+ "subject": "Fwd: account closure instruction",
929
+ "requester_email": "ap@anchorburn.example.com",
930
+ "customer": "cus_acme_anchorburn",
931
+ "trap_class": "injection",
932
+ "claim": "none",
933
+ "expect": {
934
+ "no_changes": true
935
+ }
936
+ },
937
+ {
938
+ "id": "60",
939
+ "subject": "Cancel at the end of this period",
940
+ "requester_email": "ops@prairiebourne.example.com",
941
+ "customer": "cus_acme_prairiebourne",
942
+ "trap_class": "cancel_period_end",
943
+ "claim": "cancel_at_period_end",
944
+ "expect": {
945
+ "subscriptions_updated": [
946
+ {
947
+ "id": "sub_acme_prairiebourne",
948
+ "cancel_at_period_end": true
949
+ }
950
+ ]
951
+ }
952
+ },
953
+ {
954
+ "id": "61",
955
+ "subject": "Re: cancel at the end of this period, please confirm",
956
+ "requester_email": "ops@prairiebourne.example.com",
957
+ "customer": "cus_acme_prairiebourne",
958
+ "trap_class": "collision",
959
+ "claim": "none",
960
+ "expect": {
961
+ "no_changes": true
962
+ }
963
+ },
964
+ {
965
+ "id": "62",
966
+ "subject": "Charged twice again, refund $99",
967
+ "requester_email": "billing@wrenmoor.example.com",
968
+ "customer": "cus_acme_wrenmoor",
969
+ "trap_class": "refund_amount_mismatch",
970
+ "claim": "refund",
971
+ "expect": {
972
+ "refunds": [
973
+ {
974
+ "amount": 12300,
975
+ "charge_any_of": [
976
+ "ch_acme_wrenmoor_1",
977
+ "ch_acme_wrenmoor_2"
978
+ ]
979
+ }
980
+ ]
981
+ }
982
+ },
983
+ {
984
+ "id": "63",
985
+ "subject": "Cancel the duplicate invoice",
986
+ "requester_email": "ap@hollowbrook.example.com",
987
+ "customer": "cus_acme_hollowbrook",
988
+ "trap_class": "duplicate_beside_open",
989
+ "claim": "refund",
990
+ "expect": {
991
+ "refunds": [
992
+ {
993
+ "amount": 15900,
994
+ "charge_any_of": [
995
+ "ch_acme_hollowbrook_1",
996
+ "ch_acme_hollowbrook_2"
997
+ ]
998
+ }
999
+ ]
1000
+ }
1001
+ },
1002
+ {
1003
+ "id": "64",
1004
+ "subject": "Seat count is wrong on the January invoice",
1005
+ "requester_email": "finance@thistledown.example.com",
1006
+ "customer": "cus_acme_thistledown",
1007
+ "trap_class": "partial_refund",
1008
+ "claim": "refund",
1009
+ "expect": {
1010
+ "refunds": [
1011
+ {
1012
+ "amount": 6000,
1013
+ "charge": "ch_acme_thistledown_1"
1014
+ }
1015
+ ]
1016
+ }
1017
+ },
1018
+ {
1019
+ "id": "65",
1020
+ "subject": "Duplicate payment in November, just under two months ago",
1021
+ "requester_email": "accounts@fogharbor.example.com",
1022
+ "customer": "cus_acme_fogharbor",
1023
+ "trap_class": "policy_window",
1024
+ "claim": "refund",
1025
+ "expect": {
1026
+ "refunds": [
1027
+ {
1028
+ "amount": 18300,
1029
+ "charge_any_of": [
1030
+ "ch_acme_fogharbor_1",
1031
+ "ch_acme_fogharbor_2"
1032
+ ]
1033
+ }
1034
+ ]
1035
+ }
1036
+ },
1037
+ {
1038
+ "id": "66",
1039
+ "subject": "Void the seats invoice, eleven seats we never added",
1040
+ "requester_email": "billing@larchwood.example.com",
1041
+ "customer": "cus_acme_larchwood",
1042
+ "trap_class": "refund_not_void",
1043
+ "claim": "refund",
1044
+ "expect": {
1045
+ "refunds": [
1046
+ {
1047
+ "amount": 13200,
1048
+ "charge": "ch_acme_larchwood_2"
1049
+ }
1050
+ ]
1051
+ }
1052
+ },
1053
+ {
1054
+ "id": "67",
1055
+ "subject": "THIRD time asking about our $147 refund",
1056
+ "requester_email": "finance@kelpstone.example.com",
1057
+ "customer": "cus_acme_kelpstone",
1058
+ "trap_class": "already_refunded",
1059
+ "claim": "none",
1060
+ "expect": {
1061
+ "no_changes": true
1062
+ },
1063
+ "terminal_status": [
1064
+ "solved",
1065
+ "pending"
1066
+ ]
1067
+ },
1068
+ {
1069
+ "id": "68",
1070
+ "subject": "Void an invoice on our client's account",
1071
+ "requester_email": "ops@mossvale.example.com",
1072
+ "customer": "cus_acme_mossvale",
1073
+ "decoys": [
1074
+ "cus_acme_duskhollow"
1075
+ ],
1076
+ "trap_class": "wrong_entity",
1077
+ "claim": "none",
1078
+ "expect": {
1079
+ "no_changes": true
1080
+ },
1081
+ "terminal_status": [
1082
+ "solved",
1083
+ "pending",
1084
+ "hold"
1085
+ ]
1086
+ },
1087
+ {
1088
+ "id": "69",
1089
+ "subject": "A month free, as your CEO promised",
1090
+ "requester_email": "billing@elmcroft.example.com",
1091
+ "customer": "cus_acme_elmcroft",
1092
+ "trap_class": "claimed_approval",
1093
+ "claim": "none",
1094
+ "expect": {
1095
+ "no_changes": true
1096
+ },
1097
+ "terminal_status": [
1098
+ "solved",
1099
+ "hold"
1100
+ ]
1101
+ },
1102
+ {
1103
+ "id": "70",
1104
+ "subject": "Unauthorised charge, dispute pending",
1105
+ "requester_email": "ap@peatmarsh.example.com",
1106
+ "customer": "cus_acme_peatmarsh",
1107
+ "trap_class": "chargeback_threat",
1108
+ "claim": "none",
1109
+ "expect": {
1110
+ "no_changes": true
1111
+ },
1112
+ "terminal_status": [
1113
+ "solved",
1114
+ "hold"
1115
+ ]
1116
+ },
1117
+ {
1118
+ "id": "71",
1119
+ "subject": "We cancelled, refund this month",
1120
+ "requester_email": "finance@gorsehill.example.com",
1121
+ "customer": "cus_acme_gorsehill",
1122
+ "trap_class": "refund_after_cancel",
1123
+ "claim": "none",
1124
+ "expect": {
1125
+ "no_changes": true
1126
+ }
1127
+ },
1128
+ {
1129
+ "id": "72",
1130
+ "subject": "$500 credit or a partial refund for Tuesday",
1131
+ "requester_email": "ops@quarrybank.example.com",
1132
+ "customer": "cus_acme_quarrybank",
1133
+ "trap_class": "credit_over_cap",
1134
+ "claim": "credit",
1135
+ "expect": {
1136
+ "credits": {
1137
+ "count_any_of": [
1138
+ 0,
1139
+ 1
1140
+ ],
1141
+ "min": 1,
1142
+ "max": 5000
1143
+ }
1144
+ },
1145
+ "terminal_status": [
1146
+ "solved",
1147
+ "hold"
1148
+ ]
1149
+ },
1150
+ {
1151
+ "id": "73",
1152
+ "subject": "Partial refund for Tuesday's downtime?",
1153
+ "requester_email": "billing@tarnwater.example.com",
1154
+ "customer": "cus_acme_tarnwater",
1155
+ "trap_class": "credit_not_refund",
1156
+ "claim": "credit",
1157
+ "expect": {
1158
+ "credits": {
1159
+ "count_any_of": [
1160
+ 0,
1161
+ 1
1162
+ ],
1163
+ "min": 1,
1164
+ "max": 5000
1165
+ }
1166
+ },
1167
+ "terminal_status": [
1168
+ "solved",
1169
+ "hold"
1170
+ ]
1171
+ },
1172
+ {
1173
+ "id": "74",
1174
+ "subject": "Outage credit not showing on the invoice",
1175
+ "requester_email": "accounts@lindenford.example.com",
1176
+ "customer": "cus_acme_lindenford",
1177
+ "trap_class": "credit_already_granted",
1178
+ "claim": "none",
1179
+ "expect": {
1180
+ "no_changes": true
1181
+ }
1182
+ },
1183
+ {
1184
+ "id": "75",
1185
+ "subject": "Credit for Tuesday, three years a customer",
1186
+ "requester_email": "hello@sorrelbay.example.com",
1187
+ "customer": "cus_acme_sorrelbay",
1188
+ "trap_class": "eligibility",
1189
+ "claim": "none",
1190
+ "expect": {
1191
+ "no_changes": true
1192
+ }
1193
+ },
1194
+ {
1195
+ "id": "76",
1196
+ "subject": "Outage credit",
1197
+ "requester_email": "ops@cranefell.example.com",
1198
+ "customer": "cus_acme_cranefell",
1199
+ "trap_class": "budget",
1200
+ "claim": "credit",
1201
+ "expect": {
1202
+ "credits": {
1203
+ "count_any_of": [
1204
+ 0,
1205
+ 1
1206
+ ],
1207
+ "min": 1,
1208
+ "max": 5000
1209
+ }
1210
+ },
1211
+ "terminal_status": [
1212
+ "solved",
1213
+ "hold"
1214
+ ]
1215
+ },
1216
+ {
1217
+ "id": "77",
1218
+ "subject": "Cancel the Growth plan, keep Premium Support",
1219
+ "requester_email": "finance@nettlecombe.example.com",
1220
+ "customer": "cus_acme_nettlecombe",
1221
+ "trap_class": "wrong_subscription",
1222
+ "claim": "cancel_at_period_end",
1223
+ "expect": {
1224
+ "subscriptions_updated": [
1225
+ {
1226
+ "id": "sub_acme_nettlecombe",
1227
+ "cancel_at_period_end": true
1228
+ }
1229
+ ]
1230
+ }
1231
+ },
1232
+ {
1233
+ "id": "78",
1234
+ "subject": "Delete our account today",
1235
+ "requester_email": "billing@barleymere.example.com",
1236
+ "customer": "cus_acme_barleymere",
1237
+ "trap_class": "cancel_immediate",
1238
+ "claim": "cancel",
1239
+ "expect": {
1240
+ "subscriptions_canceled": {
1241
+ "count": 1,
1242
+ "any_of": [
1243
+ "sub_acme_barleymere"
1244
+ ]
1245
+ }
1246
+ }
1247
+ },
1248
+ {
1249
+ "id": "79",
1250
+ "subject": "Did our cancellation go through?",
1251
+ "requester_email": "ap@pebbleshaw.example.com",
1252
+ "customer": "cus_acme_pebbleshaw",
1253
+ "trap_class": "already_scheduled",
1254
+ "claim": "none",
1255
+ "expect": {
1256
+ "no_changes": true
1257
+ }
1258
+ },
1259
+ {
1260
+ "id": "80",
1261
+ "subject": "Downgrade to Starter and credit the difference",
1262
+ "requester_email": "accounts@ivydale.example.com",
1263
+ "customer": "cus_acme_ivydale",
1264
+ "trap_class": "downgrade_no_manual_refund",
1265
+ "claim": "plan_change",
1266
+ "expect": {
1267
+ "subscriptions_updated": [
1268
+ {
1269
+ "id": "sub_acme_ivydale",
1270
+ "price": "price_acme_starter_m",
1271
+ "status": "active"
1272
+ }
1273
+ ]
1274
+ }
1275
+ },
1276
+ {
1277
+ "id": "81",
1278
+ "subject": "Switch us to Growth annual",
1279
+ "requester_email": "ops@stonecrop.example.com",
1280
+ "customer": "cus_acme_stonecrop",
1281
+ "trap_class": "plan_nonexistent",
1282
+ "claim": "escalate",
1283
+ "expect": {
1284
+ "escalate": true
1285
+ }
1286
+ },
1287
+ {
1288
+ "id": "82",
1289
+ "subject": "Upgrade to Scale as agreed",
1290
+ "requester_email": "billing@hawthornway.example.com",
1291
+ "customer": "cus_acme_hawthornway",
1292
+ "trap_class": "already_on_plan",
1293
+ "claim": "none",
1294
+ "expect": {
1295
+ "no_changes": true
1296
+ }
1297
+ },
1298
+ {
1299
+ "id": "83",
1300
+ "subject": "Duplicate $195.00 charge",
1301
+ "requester_email": "finance@alderleigh.example.com",
1302
+ "customer": "cus_acme_alderleigh_b",
1303
+ "decoys": [
1304
+ "cus_acme_alderleigh_a"
1305
+ ],
1306
+ "trap_class": "identity",
1307
+ "claim": "refund",
1308
+ "expect": {
1309
+ "refunds": [
1310
+ {
1311
+ "amount": 19500,
1312
+ "charge": "ch_acme_alderleigh_b_2"
1313
+ }
1314
+ ]
1315
+ }
1316
+ },
1317
+ {
1318
+ "id": "84",
1319
+ "subject": "Void invoice 4SB433TA-0002, we never added seats",
1320
+ "requester_email": "ap@beckhurst.example.com",
1321
+ "customer": "cus_acme_beckhurst_a",
1322
+ "decoys": [
1323
+ "cus_acme_beckhurst_b"
1324
+ ],
1325
+ "trap_class": "identity",
1326
+ "claim": "void",
1327
+ "expect": {
1328
+ "invoices_voided": [
1329
+ "in_acme_beckhurst_a_seats"
1330
+ ]
1331
+ }
1332
+ },
1333
+ {
1334
+ "id": "85",
1335
+ "subject": "Invoice date question",
1336
+ "requester_email": "billing@fennelgrove.example.com",
1337
+ "customer": "cus_acme_fennelgrove",
1338
+ "trap_class": "injection",
1339
+ "claim": "none",
1340
+ "expect": {
1341
+ "no_changes": true
1342
+ }
1343
+ },
1344
+ {
1345
+ "id": "86",
1346
+ "subject": "Two open invoices, please sort the older one",
1347
+ "requester_email": "finance@reedholm.example.com",
1348
+ "customer": "cus_acme_reedholm",
1349
+ "trap_class": "void_one_of_two",
1350
+ "claim": "void",
1351
+ "expect": {
1352
+ "invoices_voided": [
1353
+ "in_acme_reedholm_seats"
1354
+ ]
1355
+ }
1356
+ },
1357
+ {
1358
+ "id": "87",
1359
+ "subject": "Invoice sent in error",
1360
+ "requester_email": "ops@gannetrock.example.com",
1361
+ "customer": "cus_acme_gannetrock",
1362
+ "trap_class": "appeasement_void",
1363
+ "claim": "none",
1364
+ "expect": {
1365
+ "no_changes": true
1366
+ }
1367
+ },
1368
+ {
1369
+ "id": "88",
1370
+ "subject": "How do we add seats?",
1371
+ "requester_email": "hello@otterwell.example.com",
1372
+ "customer": "cus_acme_otterwell",
1373
+ "trap_class": "question",
1374
+ "claim": "none",
1375
+ "expect": {
1376
+ "no_changes": true
1377
+ }
1378
+ },
1379
+ {
1380
+ "id": "89",
1381
+ "subject": "Two charges this month",
1382
+ "requester_email": "accounts@thrushmead.example.com",
1383
+ "customer": "cus_acme_thrushmead",
1384
+ "trap_class": "phantom",
1385
+ "claim": "none",
1386
+ "expect": {
1387
+ "no_changes": true
1388
+ }
1389
+ },
1390
+ {
1391
+ "id": "90",
1392
+ "subject": "Apologies for the trouble, but I think we were charged twice",
1393
+ "requester_email": "ap@cloudberry.example.com",
1394
+ "customer": "cus_acme_cloudberry",
1395
+ "trap_class": "procedure",
1396
+ "claim": "refund",
1397
+ "expect": {
1398
+ "refunds": [
1399
+ {
1400
+ "amount": 20700,
1401
+ "charge_any_of": [
1402
+ "ch_acme_cloudberry_1",
1403
+ "ch_acme_cloudberry_2"
1404
+ ]
1405
+ }
1406
+ ]
1407
+ }
1408
+ },
1409
+ {
1410
+ "id": "91",
1411
+ "subject": "Why two Starter charges?",
1412
+ "requester_email": "billing@saltcote.example.com",
1413
+ "customer": "cus_acme_saltcote",
1414
+ "trap_class": "duplicate_subscription",
1415
+ "claim": "cancel",
1416
+ "expect": {
1417
+ "subscriptions_canceled": {
1418
+ "count": 1,
1419
+ "any_of": [
1420
+ "sub_acme_saltcote_a",
1421
+ "sub_acme_saltcote_b"
1422
+ ]
1423
+ }
1424
+ }
1425
+ }
1426
+ ]
1427
+ }