backend-manager 5.0.85 → 5.0.87

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 (40) hide show
  1. package/CLAUDE.md +53 -1
  2. package/package.json +1 -1
  3. package/src/cli/commands/base-command.js +5 -1
  4. package/src/cli/commands/serve.js +1 -2
  5. package/src/manager/cron/daily/ghostii-auto-publisher.js +10 -19
  6. package/src/manager/events/firestore/payments-webhooks/on-write.js +351 -56
  7. package/src/manager/events/firestore/payments-webhooks/transitions/index.js +148 -0
  8. package/src/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-completed.js +16 -0
  9. package/src/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-failed.js +15 -0
  10. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-requested.js +15 -0
  11. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js +18 -0
  12. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/payment-failed.js +15 -0
  13. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/payment-recovered.js +14 -0
  14. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/plan-changed.js +16 -0
  15. package/src/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-cancelled.js +16 -0
  16. package/src/manager/index.js +26 -36
  17. package/src/manager/libraries/{stripe.js → payment-processors/stripe.js} +57 -2
  18. package/src/manager/libraries/payment-processors/test.js +141 -0
  19. package/src/manager/routes/app/get.js +5 -22
  20. package/src/manager/routes/payments/intent/post.js +38 -23
  21. package/src/manager/routes/payments/intent/processors/stripe.js +112 -44
  22. package/src/manager/routes/payments/intent/processors/test.js +139 -76
  23. package/src/manager/routes/payments/webhook/post.js +14 -5
  24. package/src/manager/routes/payments/webhook/processors/stripe.js +75 -9
  25. package/src/manager/schemas/payments/intent/post.js +1 -1
  26. package/src/test/test-accounts.js +10 -1
  27. package/templates/backend-manager-config.json +16 -4
  28. package/test/events/payments/journey-payments-cancel.js +6 -0
  29. package/test/events/payments/journey-payments-failure.js +114 -0
  30. package/test/events/payments/journey-payments-suspend.js +6 -0
  31. package/test/events/payments/journey-payments-trial.js +12 -0
  32. package/test/events/payments/journey-payments-upgrade.js +17 -0
  33. package/test/fixtures/stripe/checkout-session-completed.json +130 -0
  34. package/test/fixtures/stripe/invoice-payment-failed.json +148 -0
  35. package/test/fixtures/stripe/invoice-subscription-payment-failed.json +28 -0
  36. package/test/helpers/stripe-parse-webhook.js +447 -0
  37. package/test/helpers/stripe-to-unified.js +59 -59
  38. package/test/routes/payments/intent.js +3 -3
  39. package/test/routes/payments/webhook.js +2 -2
  40. package/src/manager/libraries/test.js +0 -27
@@ -45,6 +45,9 @@ module.exports = {
45
45
  assert.ok(response.data.url, 'Should return URL');
46
46
 
47
47
  state.intentId = response.data.id;
48
+
49
+ // Derive webhook event ID from intent ID (same timestamp)
50
+ state.eventId = response.data.id.replace('_test-cs-', '_test-evt-');
48
51
  },
49
52
  },
50
53
 
@@ -83,6 +86,20 @@ module.exports = {
83
86
  },
84
87
  },
85
88
 
89
+ {
90
+ name: 'webhook-transition-new-subscription',
91
+ async run({ firestore, assert, state, waitFor }) {
92
+ await waitFor(async () => {
93
+ const doc = await firestore.get(`payments-webhooks/${state.eventId}`);
94
+ return doc?.status === 'completed';
95
+ }, 15000, 500);
96
+
97
+ const webhookDoc = await firestore.get(`payments-webhooks/${state.eventId}`);
98
+ assert.ok(webhookDoc, 'Webhook doc should exist');
99
+ assert.equal(webhookDoc.transition, 'new-subscription', 'Transition should be new-subscription');
100
+ },
101
+ },
102
+
86
103
  {
87
104
  name: 'intent-doc-created',
88
105
  async run({ firestore, assert, state }) {
@@ -0,0 +1,130 @@
1
+ {
2
+ "id": "cs_test_a1N31jwL64dmiOkxYQryCc69EmaczRofyGcsTQgjJOaKLpmfLDm87x4cY1",
3
+ "object": "checkout.session",
4
+ "adaptive_pricing": {
5
+ "enabled": true
6
+ },
7
+ "after_expiration": null,
8
+ "allow_promotion_codes": null,
9
+ "amount_subtotal": 3000,
10
+ "amount_total": 3000,
11
+ "automatic_tax": {
12
+ "enabled": false,
13
+ "liability": null,
14
+ "provider": null,
15
+ "status": null
16
+ },
17
+ "billing_address_collection": null,
18
+ "branding_settings": {
19
+ "background_color": "#ffffff",
20
+ "border_style": "rounded",
21
+ "button_color": "#6b5fe8",
22
+ "display_name": "ITW Staging",
23
+ "font_family": "default",
24
+ "icon": {
25
+ "file": "file_1PVKbpDEGraYraOkAsWXvanJ",
26
+ "type": "file"
27
+ },
28
+ "logo": {
29
+ "file": "file_1PVKbrDEGraYraOk3dgbXv6O",
30
+ "type": "file"
31
+ }
32
+ },
33
+ "cancel_url": "https://httpbin.org/post",
34
+ "client_reference_id": null,
35
+ "client_secret": null,
36
+ "collected_information": null,
37
+ "consent": null,
38
+ "consent_collection": null,
39
+ "created": 1771624428,
40
+ "currency": "usd",
41
+ "currency_conversion": null,
42
+ "custom_fields": [],
43
+ "custom_text": {
44
+ "after_submit": null,
45
+ "shipping_address": null,
46
+ "submit": null,
47
+ "terms_of_service_acceptance": null
48
+ },
49
+ "customer": null,
50
+ "customer_account": null,
51
+ "customer_creation": "if_required",
52
+ "customer_details": {
53
+ "address": {
54
+ "city": "South San Francisco",
55
+ "country": "US",
56
+ "line1": "354 Oyster Point Blvd",
57
+ "line2": null,
58
+ "postal_code": "94080",
59
+ "state": "CA"
60
+ },
61
+ "business_name": null,
62
+ "email": "stripe@example.com",
63
+ "individual_name": null,
64
+ "name": "Jenny Rosen",
65
+ "phone": null,
66
+ "tax_exempt": "none",
67
+ "tax_ids": []
68
+ },
69
+ "customer_email": null,
70
+ "discounts": [],
71
+ "expires_at": 1771710828,
72
+ "invoice": null,
73
+ "invoice_creation": {
74
+ "enabled": false,
75
+ "invoice_data": {
76
+ "account_tax_ids": null,
77
+ "custom_fields": null,
78
+ "description": null,
79
+ "footer": null,
80
+ "issuer": null,
81
+ "metadata": {},
82
+ "rendering_options": null
83
+ }
84
+ },
85
+ "livemode": false,
86
+ "locale": null,
87
+ "metadata": {},
88
+ "mode": "payment",
89
+ "origin_context": null,
90
+ "payment_intent": "pi_3T31dxDEGraYraOk0Lm5iB2n",
91
+ "payment_link": null,
92
+ "payment_method_collection": "if_required",
93
+ "payment_method_configuration_details": {
94
+ "id": "pmc_1OmUeLDEGraYraOkK8MQcAeS",
95
+ "parent": null
96
+ },
97
+ "payment_method_options": {
98
+ "card": {
99
+ "request_three_d_secure": "automatic"
100
+ }
101
+ },
102
+ "payment_method_types": [
103
+ "card",
104
+ "link",
105
+ "cashapp"
106
+ ],
107
+ "payment_status": "paid",
108
+ "permissions": null,
109
+ "phone_number_collection": {
110
+ "enabled": false
111
+ },
112
+ "recovered_from": null,
113
+ "saved_payment_method_options": null,
114
+ "setup_intent": null,
115
+ "shipping_address_collection": null,
116
+ "shipping_cost": null,
117
+ "shipping_options": [],
118
+ "status": "complete",
119
+ "submit_type": null,
120
+ "subscription": null,
121
+ "success_url": "https://httpbin.org/post",
122
+ "total_details": {
123
+ "amount_discount": 0,
124
+ "amount_shipping": 0,
125
+ "amount_tax": 0
126
+ },
127
+ "ui_mode": "hosted",
128
+ "url": null,
129
+ "wallet_options": null
130
+ }
@@ -0,0 +1,148 @@
1
+ {
2
+ "id": "in_1T31IoDEGraYraOkwNNohtXq",
3
+ "object": "invoice",
4
+ "account_country": "US",
5
+ "account_name": "ITW Staging",
6
+ "account_tax_ids": null,
7
+ "amount_due": 2000,
8
+ "amount_overpaid": 0,
9
+ "amount_paid": 0,
10
+ "amount_remaining": 2000,
11
+ "amount_shipping": 0,
12
+ "application": null,
13
+ "attempt_count": 1,
14
+ "attempted": true,
15
+ "auto_advance": false,
16
+ "automatic_tax": {
17
+ "disabled_reason": null,
18
+ "enabled": false,
19
+ "liability": null,
20
+ "provider": null,
21
+ "status": null
22
+ },
23
+ "automatically_finalizes_at": null,
24
+ "billing_reason": "manual",
25
+ "collection_method": "charge_automatically",
26
+ "created": 1771623118,
27
+ "currency": "usd",
28
+ "custom_fields": null,
29
+ "customer": "cus_U13Pt9XQOMdoQC",
30
+ "customer_account": null,
31
+ "customer_address": null,
32
+ "customer_email": null,
33
+ "customer_name": null,
34
+ "customer_phone": null,
35
+ "customer_shipping": null,
36
+ "customer_tax_exempt": "none",
37
+ "customer_tax_ids": [],
38
+ "default_payment_method": null,
39
+ "default_source": null,
40
+ "default_tax_rates": [],
41
+ "description": "(created by Stripe CLI)",
42
+ "discounts": [],
43
+ "due_date": null,
44
+ "effective_at": 1771623118,
45
+ "ending_balance": 0,
46
+ "footer": null,
47
+ "from_invoice": null,
48
+ "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1JFu2ZDEGraYraOk/test_YWNjdF8xSkZ1MlpERUdyYVlyYU9rLF9VMTNQYVlDRFlJcXlxbUtYZlBSSFNocno3d09LYTBGLDE2MjE2MzkyMg0200VZxEnWzY?s=ap",
49
+ "invoice_pdf": "https://pay.stripe.com/invoice/acct_1JFu2ZDEGraYraOk/test_YWNjdF8xSkZ1MlpERUdyYVlyYU9rLF9VMTNQYVlDRFlJcXlxbUtYZlBSSFNocno3d09LYTBGLDE2MjE2MzkyMg0200VZxEnWzY/pdf?s=ap",
50
+ "issuer": {
51
+ "type": "self"
52
+ },
53
+ "last_finalization_error": null,
54
+ "latest_revision": null,
55
+ "lines": {
56
+ "object": "list",
57
+ "data": [
58
+ {
59
+ "id": "il_1T31InDEGraYraOkdxUQqzZX",
60
+ "object": "line_item",
61
+ "amount": 2000,
62
+ "currency": "usd",
63
+ "description": "(created by Stripe CLI)",
64
+ "discount_amounts": [],
65
+ "discountable": true,
66
+ "discounts": [],
67
+ "invoice": "in_1T31IoDEGraYraOkwNNohtXq",
68
+ "livemode": false,
69
+ "metadata": {},
70
+ "parent": {
71
+ "invoice_item_details": {
72
+ "invoice_item": "ii_1T31InDEGraYraOk7AKHJH1R",
73
+ "proration": false,
74
+ "proration_details": {
75
+ "credited_items": null
76
+ },
77
+ "subscription": null
78
+ },
79
+ "subscription_item_details": null,
80
+ "type": "invoice_item_details"
81
+ },
82
+ "period": {
83
+ "end": 1771623117,
84
+ "start": 1771623117
85
+ },
86
+ "pretax_credit_amounts": [],
87
+ "pricing": {
88
+ "price_details": {
89
+ "price": "price_1T31InDEGraYraOkyU7YKWOU",
90
+ "product": "prod_U13P3zGuNnCD1p"
91
+ },
92
+ "type": "price_details",
93
+ "unit_amount_decimal": "2000"
94
+ },
95
+ "quantity": 1,
96
+ "subtotal": 2000,
97
+ "taxes": []
98
+ }
99
+ ],
100
+ "has_more": false,
101
+ "total_count": 1,
102
+ "url": "/v1/invoices/in_1T31IoDEGraYraOkwNNohtXq/lines"
103
+ },
104
+ "livemode": false,
105
+ "metadata": {},
106
+ "next_payment_attempt": null,
107
+ "number": "VKHSKUV5-0001",
108
+ "on_behalf_of": null,
109
+ "parent": null,
110
+ "payment_settings": {
111
+ "default_mandate": null,
112
+ "payment_method_options": null,
113
+ "payment_method_types": null
114
+ },
115
+ "period_end": 1771623118,
116
+ "period_start": 1771623118,
117
+ "post_payment_credit_notes_amount": 0,
118
+ "pre_payment_credit_notes_amount": 0,
119
+ "receipt_number": null,
120
+ "rendering": {
121
+ "amount_tax_display": null,
122
+ "pdf": {
123
+ "page_size": "letter"
124
+ },
125
+ "template": null,
126
+ "template_version": null
127
+ },
128
+ "shipping_cost": null,
129
+ "shipping_details": null,
130
+ "starting_balance": 0,
131
+ "statement_descriptor": null,
132
+ "status": "open",
133
+ "status_transitions": {
134
+ "finalized_at": 1771623118,
135
+ "marked_uncollectible_at": null,
136
+ "paid_at": null,
137
+ "voided_at": null
138
+ },
139
+ "subtotal": 2000,
140
+ "subtotal_excluding_tax": 2000,
141
+ "test_clock": null,
142
+ "total": 2000,
143
+ "total_discount_amounts": [],
144
+ "total_excluding_tax": 2000,
145
+ "total_pretax_credit_amounts": [],
146
+ "total_taxes": [],
147
+ "webhooks_delivered_at": null
148
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "id": "in_test_sub_payment_failed",
3
+ "object": "invoice",
4
+ "amount_due": 999,
5
+ "amount_paid": 0,
6
+ "amount_remaining": 999,
7
+ "attempt_count": 1,
8
+ "attempted": true,
9
+ "billing_reason": "subscription_cycle",
10
+ "collection_method": "charge_automatically",
11
+ "created": 1771623118,
12
+ "currency": "usd",
13
+ "customer": "cus_test_sub_fail",
14
+ "livemode": false,
15
+ "metadata": {},
16
+ "parent": {
17
+ "subscription_details": {
18
+ "subscription": "sub_test_failed_sub",
19
+ "metadata": {
20
+ "uid": "test-uid-sub-fail"
21
+ }
22
+ },
23
+ "type": "subscription_details"
24
+ },
25
+ "status": "open",
26
+ "subtotal": 999,
27
+ "total": 999
28
+ }