@live-change/stripe-service 0.8.109 → 0.8.110

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/index.js CHANGED
@@ -4,6 +4,7 @@ const app = App.app()
4
4
  import definition from './definition.js'
5
5
 
6
6
  import "./payment.js"
7
+ import "./stripeEvents.js"
7
8
  import "./webhook.js"
8
9
 
9
10
  export default definition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/stripe-service",
3
- "version": "0.8.109",
3
+ "version": "0.8.110",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,14 +21,14 @@
21
21
  "url": "https://www.viamage.com/"
22
22
  },
23
23
  "dependencies": {
24
- "@live-change/framework": "^0.8.109",
25
- "@live-change/relations-plugin": "^0.8.109",
24
+ "@live-change/framework": "^0.8.110",
25
+ "@live-change/relations-plugin": "^0.8.110",
26
26
  "lru-cache": "^7.12.0",
27
27
  "pluralize": "^8.0.0",
28
28
  "progress-stream": "^2.0.0",
29
29
  "prosemirror-model": "^1.18.1",
30
30
  "stripe": "^17.2.1"
31
31
  },
32
- "gitHead": "075bf3759fae6c40fb8e44d77d9f12c5c175e098",
32
+ "gitHead": "8af31d640f43b00b2874f2c70fa4d4486541adfe",
33
33
  "type": "module"
34
34
  }
package/payment.js CHANGED
@@ -4,7 +4,7 @@ const app = App.app()
4
4
  import definition from './definition.js'
5
5
  import config from './config.js'
6
6
 
7
- import stripe from 'stripe'
7
+ import stripe from "./stripeClient.js"
8
8
 
9
9
  const itemsArray = {
10
10
  type: Array,
@@ -54,10 +54,18 @@ const paymentParameters = {
54
54
  cancelUrl: {
55
55
  type: String,
56
56
  validation: ['nonEmpty']
57
+ },
58
+ payerType: {
59
+ type: String,
60
+ validation: ['nonEmpty']
61
+ },
62
+ payer: {
63
+ type: String,
64
+ validation: ['nonEmpty']
57
65
  }
58
66
  }
59
67
 
60
- definition.model({
68
+ const Payment = definition.model({
61
69
  name: "Payment",
62
70
  entity:{
63
71
  },
@@ -65,7 +73,7 @@ definition.model({
65
73
  ...paymentParameters,
66
74
  state: {
67
75
  type: String,
68
- options: ['created', 'succeeded', 'failed', 'refunded']
76
+ options: ['created', 'pending', 'succeeded', 'failed', 'refunded']
69
77
  },
70
78
  stripeSession: {
71
79
  type: String
@@ -75,21 +83,31 @@ definition.model({
75
83
  }
76
84
  })
77
85
 
86
+ export { Payment}
87
+
78
88
  definition.trigger({
79
89
  name: 'startPayment',
80
90
  properties: {
81
91
  ...paymentParameters
82
92
  },
83
- async execute({ items, causeType, cause, successUrl, cancelUrl }, { client, service }, emit) {
84
- console.log("STRIPE SECRET KEY", config.secretKey)
93
+ waitForEvents:true,
94
+ async execute({ items, causeType, cause, successUrl, cancelUrl, payerType, payer }, { service }, emit) {
85
95
  const payment = app.generateUid()
86
- const stripeClient = stripe(config.secretKey)
87
96
  console.log("URLS", {
88
97
  success_url: successUrl ?? (config.checkoutSuccessUrl + '/' + payment),
89
98
  cancel_url: cancelUrl ?? (config.checkoutCancelUrl + '/' + payment)
90
99
  })
91
- const session = await stripeClient.checkout.sessions.create({
100
+ const metadata = {
101
+ type: 'payment',
102
+ payment
103
+ }
104
+ const session = await stripe.checkout.sessions.create({
92
105
  payment_method_types: ['card'],
106
+ client_reference_id: 'payment:'+payment,
107
+ // customer: // store stripe customer id ?
108
+ // customer_creation: 'always'
109
+ /// TODO:
110
+ // customer_email: /// get from contacts
93
111
  line_items: items.map(item => ({
94
112
  price_data: {
95
113
  currency: item.currency,
@@ -102,6 +120,13 @@ definition.trigger({
102
120
  },
103
121
  quantity: item.quantity
104
122
  })),
123
+ invoice_creation: {
124
+ enabled: true
125
+ },
126
+ metadata,
127
+ payment_intent_data: {
128
+ metadata
129
+ },
105
130
  mode: 'payment',
106
131
  success_url: successUrl ?? (config.checkoutSuccessUrl + '/' + payment),
107
132
  cancel_url: cancelUrl ?? (config.checkoutCancelUrl + '/' + payment)
@@ -110,7 +135,7 @@ definition.trigger({
110
135
  type: 'PaymentCreated',
111
136
  payment,
112
137
  data: {
113
- items, causeType, cause,
138
+ items, causeType, cause, payerType, payer,
114
139
  stripeSession: session.id,
115
140
  state: 'created'
116
141
  }
@@ -122,4 +147,3 @@ definition.trigger({
122
147
  }
123
148
  }
124
149
  })
125
-
@@ -0,0 +1,8 @@
1
+ import stripe from 'stripe'
2
+
3
+ import config from './config.js'
4
+
5
+ console.log("STRIPE SECRET KEY", config.secretKey)
6
+ const stripeClient = stripe(config.secretKey)
7
+
8
+ export default stripeClient
@@ -0,0 +1,323 @@
1
+ import App from '@live-change/framework'
2
+ const app = App.app()
3
+
4
+ import definition from './definition.js'
5
+ import config from './config.js'
6
+
7
+ import stripe from "./stripeClient.js"
8
+
9
+ import { Payment } from './payment.js'
10
+
11
+
12
+ /// TODO: obsługa zdarzeń:
13
+ /// dla stanu płatności:
14
+ /// charge.succeeded
15
+ /// charge.refunded
16
+
17
+
18
+ definition.trigger({
19
+ name: 'stripeEvent.checkout.session.completed',
20
+ properties: {
21
+ data: {
22
+ type: Object,
23
+ properties: {
24
+ object: {
25
+ type: Object,
26
+ properties: {
27
+ client_reference_id: {
28
+ type: String,
29
+ validation: ['nonEmpty']
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ },
36
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
37
+ //console.log('stripeEvent.checkout.session.completed', object)
38
+ const id = object.client_reference_id
39
+ const referenceType = id.slice(0, id.indexOf(':'))
40
+ const referenceId = id.slice(id.indexOf(':') + 1)
41
+ if(referenceType === 'payment') {
42
+ const payment = await Payment.get(referenceId)
43
+ if(!payment) throw new Error('Payment '+referenceId+' not found')
44
+ if(object.payment_status === 'paid') {
45
+ await triggerService({
46
+ service: definition.name,
47
+ type: 'stripe_updatePayment'
48
+ }, {
49
+ payment: referenceId,
50
+ state: 'succeeded'
51
+ })
52
+ const triggerData = {
53
+ payment: referenceId,
54
+ causeType: payment.causeType,
55
+ cause: payment.cause,
56
+ payerType: payment.payerType,
57
+ payer: payment.payer,
58
+ items: payment.items
59
+ }
60
+ await trigger({
61
+ type: 'paymentSucceeded_'+payment.causeType,
62
+ }, triggerData)
63
+ await trigger({
64
+ type: 'paymentSucceeded',
65
+ }, triggerData)
66
+ } else if(object.payment_status === 'unpaid') {
67
+ await triggerService({
68
+ service: definition.name,
69
+ type: 'stripe_updatePayment'
70
+ }, {
71
+ payment: referenceId,
72
+ state: 'pending'
73
+ })
74
+ }
75
+ } else {
76
+ // Ignore
77
+ }
78
+
79
+ }
80
+ })
81
+
82
+
83
+ definition.trigger({
84
+ name: 'stripeEvent.checkout.session.expired',
85
+ properties: {
86
+ data: {
87
+ type: Object,
88
+ properties: {
89
+ object: {
90
+ type: Object,
91
+ properties: {
92
+ client_reference_id: {
93
+ type: String,
94
+ validation: ['nonEmpty']
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ },
101
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
102
+ ///console.log('stripeEvent.checkout.session.expired', object)
103
+ const id = object.client_reference_id
104
+ const referenceType = id.slice(0, id.indexOf(':'))
105
+ const referenceId = id.slice(id.indexOf(':') + 1)
106
+ if(referenceType === 'payment') {
107
+ const payment = await Payment.get(referenceId)
108
+ if(!payment) throw new Error('Payment '+referenceId+' not found')
109
+ await triggerService({
110
+ type: 'stripe_updatePayment'
111
+ }, {
112
+ payment: referenceId,
113
+ state: 'failed'
114
+ })
115
+ const triggerData = {
116
+ payment: referenceId,
117
+ causeType: payment.causeType,
118
+ cause: payment.cause,
119
+ payerType: payment.payerType,
120
+ payer: payment.payer,
121
+ items: payment.items
122
+ }
123
+ await trigger({
124
+ type: 'paymentFailed_'+payment.causeType,
125
+ }, triggerData)
126
+ await trigger({
127
+ type: 'paymentFailed',
128
+ }, triggerData)
129
+ } else {
130
+ // Ignore
131
+ }
132
+
133
+ }
134
+ })
135
+
136
+
137
+ definition.trigger({
138
+ name: 'stripeEvent.checkout.session.async_payment_succeeded',
139
+ properties: {
140
+ data: {
141
+ type: Object,
142
+ properties: {
143
+ object: {
144
+ type: Object,
145
+ properties: {
146
+ client_reference_id: {
147
+ type: String,
148
+ validation: ['nonEmpty']
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ },
155
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
156
+ //console.log('stripeEvent.checkout.session.async_payment_succeeded', object)
157
+ const id = object.client_reference_id
158
+ const referenceType = id.slice(0, id.indexOf(':'))
159
+ const referenceId = id.slice(id.indexOf(':') + 1)
160
+ if(referenceType === 'payment') {
161
+ const payment = await Payment.get(referenceId)
162
+ if(!payment) throw new Error('Payment '+referenceId+' not found')
163
+ if(object.payment_status === 'paid') {
164
+ await triggerService({
165
+ type: 'stripe_updatePayment'
166
+ }, {
167
+ payment: referenceId,
168
+ state: 'succeeded'
169
+ })
170
+ const triggerData = {
171
+ payment: referenceId,
172
+ causeType: payment.causeType,
173
+ cause: payment.cause,
174
+ payerType: payment.payerType,
175
+ payer: payment.payer,
176
+ items: payment.items
177
+ }
178
+ await trigger({
179
+ type: 'paymentSucceeded_'+payment.causeType,
180
+ }, triggerData)
181
+ await trigger({
182
+ type: 'paymentSucceeded',
183
+ }, triggerData)
184
+ } else if(object.payment_status === 'unpaid') {
185
+ await triggerService({
186
+ type: 'stripe_updatePayment'
187
+ }, {
188
+ payment: referenceId,
189
+ state: 'pending'
190
+ })
191
+ }
192
+ } else {
193
+ // Ignore
194
+ }
195
+
196
+ }
197
+ })
198
+
199
+
200
+ definition.trigger({
201
+ name: 'stripeEvent.checkout.session.async_payment_failed',
202
+ properties: {
203
+ data: {
204
+ type: Object,
205
+ properties: {
206
+ object: {
207
+ type: Object,
208
+ properties: {
209
+ client_reference_id: {
210
+ type: String,
211
+ validation: ['nonEmpty']
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+ },
218
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
219
+ //console.log('stripeEvent.checkout.session.async_payment_failed', object)
220
+ const id = object.client_reference_id
221
+ const referenceType = id.slice(0, id.indexOf(':'))
222
+ const referenceId = id.slice(id.indexOf(':') + 1)
223
+ if(referenceType === 'payment') {
224
+ const payment = await Payment.get(referenceId)
225
+ if(!payment) throw new Error('Payment '+referenceId+' not found')
226
+ await triggerService({
227
+ type: 'stripe_updatePayment'
228
+ }, {
229
+ payment: referenceId,
230
+ state: 'failed'
231
+ })
232
+ const triggerData = {
233
+ payment: referenceId,
234
+ causeType: payment.causeType,
235
+ cause: payment.cause,
236
+ payerType: payment.payerType,
237
+ payer: payment.payer,
238
+ items: payment.items
239
+ }
240
+ await trigger({
241
+ type: 'paymentFailed_'+payment.causeType,
242
+ }, triggerData)
243
+ await trigger({
244
+ type: 'paymentFailed',
245
+ }, triggerData)
246
+ } else {
247
+ // Ignore
248
+ }
249
+
250
+ }
251
+ })
252
+
253
+ definition.trigger({
254
+ name: 'stripeEvent.charge.succeeded',
255
+ properties: {
256
+ data: {
257
+ type: Object,
258
+ properties: {
259
+ object: {
260
+ type: Object
261
+ }
262
+ }
263
+ }
264
+ },
265
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
266
+ console.log('charge.succeeded', JSON.stringify(object, null, 2))
267
+ if(object.metadata?.type === 'payment') {
268
+ const payment = await Payment.get(object.metadata.payment)
269
+ const triggerData = {
270
+ payment: payment.id,
271
+ causeType: payment.causeType,
272
+ cause: payment.cause,
273
+ payerType: payment.payerType,
274
+ payer: payment.payer,
275
+ items: payment.items
276
+ }
277
+ await trigger({
278
+ type: 'chargeCollected_'+payment.causeType
279
+ }, triggerData)
280
+ await trigger({
281
+ type: 'chargeCollected'
282
+ }, triggerData)
283
+ } else {
284
+ // Ignore
285
+ }
286
+ }
287
+ })
288
+
289
+ definition.trigger({
290
+ name: 'stripeEvent.charge.refunded',
291
+ properties: {
292
+ data: {
293
+ type: Object,
294
+ properties: {
295
+ object: {
296
+ type: Object
297
+ }
298
+ }
299
+ }
300
+ },
301
+ async execute({ data: { object } }, { triggerService, trigger }, emit) {
302
+ console.log('charge.refunded', JSON.stringify(object, null, 2))
303
+ if(object.metadata?.type === 'payment') {
304
+ const payment = await Payment.get(object.metadata.payment)
305
+ const triggerData = {
306
+ payment: payment.id,
307
+ causeType: payment.causeType,
308
+ cause: payment.cause,
309
+ payerType: payment.payerType,
310
+ payer: payment.payer,
311
+ items: payment.items
312
+ }
313
+ await trigger({
314
+ type: 'chargeRefunded_'+payment.causeType,
315
+ }, triggerData)
316
+ await trigger({
317
+ type: 'chargeRefunded',
318
+ }, triggerData)
319
+ } else {
320
+ // Ignore
321
+ }
322
+ }
323
+ })
package/webhook.js CHANGED
@@ -1,11 +1,15 @@
1
1
  import App from '@live-change/framework'
2
2
  const app = App.app()
3
3
  import definition from './definition.js'
4
+ import config from './config.js'
4
5
 
5
6
  import crypto from "crypto"
6
7
  import express from "express"
7
8
  import stripe from "stripe"
8
9
 
10
+
11
+
12
+
9
13
  definition.endpoint({
10
14
  name: 'webhook',
11
15
  create() {
@@ -18,11 +22,14 @@ definition.endpoint({
18
22
  })
19
23
  expressApp.post('/', express.raw({type: 'application/json'}), async (request, response) => {
20
24
  try {
21
- const event = stripe.webhooks.constructEvent(request.body, sig, config.webhookSecret)
22
- console.log("STRIPE WEBHOOK", event)
23
- await app.triggerService({
24
- service: 'stripe',
25
- type: `stripe.${event.type}`
25
+ const signature = request.headers['stripe-signature']
26
+ const event = stripe.webhooks.constructEvent(request.body, signature, config.webhookSecret)
27
+ console.log("STRIPE WEBHOOK", event.type )//,JSON.stringify(event))
28
+ await app.trigger({
29
+ // service: 'stripe',
30
+ type: `stripeEvent.${event.type}`
31
+ }, {
32
+ ...event
26
33
  })
27
34
  response.json({ received: true })
28
35
  } catch (err) {