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.
- package/CLAUDE.md +53 -1
- package/package.json +1 -1
- package/src/cli/commands/base-command.js +5 -1
- package/src/cli/commands/serve.js +1 -2
- package/src/manager/cron/daily/ghostii-auto-publisher.js +10 -19
- package/src/manager/events/firestore/payments-webhooks/on-write.js +351 -56
- package/src/manager/events/firestore/payments-webhooks/transitions/index.js +148 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-completed.js +16 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-failed.js +15 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-requested.js +15 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js +18 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/payment-failed.js +15 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/payment-recovered.js +14 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/plan-changed.js +16 -0
- package/src/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-cancelled.js +16 -0
- package/src/manager/index.js +26 -36
- package/src/manager/libraries/{stripe.js → payment-processors/stripe.js} +57 -2
- package/src/manager/libraries/payment-processors/test.js +141 -0
- package/src/manager/routes/app/get.js +5 -22
- package/src/manager/routes/payments/intent/post.js +38 -23
- package/src/manager/routes/payments/intent/processors/stripe.js +112 -44
- package/src/manager/routes/payments/intent/processors/test.js +139 -76
- package/src/manager/routes/payments/webhook/post.js +14 -5
- package/src/manager/routes/payments/webhook/processors/stripe.js +75 -9
- package/src/manager/schemas/payments/intent/post.js +1 -1
- package/src/test/test-accounts.js +10 -1
- package/templates/backend-manager-config.json +16 -4
- package/test/events/payments/journey-payments-cancel.js +6 -0
- package/test/events/payments/journey-payments-failure.js +114 -0
- package/test/events/payments/journey-payments-suspend.js +6 -0
- package/test/events/payments/journey-payments-trial.js +12 -0
- package/test/events/payments/journey-payments-upgrade.js +17 -0
- package/test/fixtures/stripe/checkout-session-completed.json +130 -0
- package/test/fixtures/stripe/invoice-payment-failed.json +148 -0
- package/test/fixtures/stripe/invoice-subscription-payment-failed.json +28 -0
- package/test/helpers/stripe-parse-webhook.js +447 -0
- package/test/helpers/stripe-to-unified.js +59 -59
- package/test/routes/payments/intent.js +3 -3
- package/test/routes/payments/webhook.js +2 -2
- 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
|
+
}
|