webfast 0.1.86 → 0.1.88

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.
@@ -0,0 +1,52 @@
1
+ module.exports = {
2
+ dependOn : [`modules.request.get`],
3
+ name : 'payment-sync',
4
+ run : async function(program,name) {
5
+ console.log(`Running ${name}`);
6
+
7
+ // Lets make a mockup for providers
8
+ const routesPath = program.path.join(__dirname,`providers`);
9
+ let moduleData = await program.modules.walkDirectory(routesPath);
10
+
11
+ // Set Module
12
+ let setModule = {
13
+ ts : Date.now()
14
+ }
15
+
16
+ // loop Throuh module data
17
+ for (let moduleIndex in moduleData) {
18
+ // Get the module
19
+ let module = moduleData[moduleIndex];
20
+ // Create module in setModule
21
+ try {
22
+ // We have set module
23
+ // read startup file
24
+ const mainModulePath = program.path.join(routesPath,`${module.name}`);
25
+ const startupPath = program.path.join(mainModulePath,`startup.js`);
26
+
27
+ // Check if program set path
28
+ if (program.set.path == undefined) {
29
+ continue;
30
+ }
31
+ const configRead = JSON.parse(program.fs.readFileSync(program.path.join(program.set.path,`payment.config.json`),`UTF-8`));
32
+ // Read
33
+ const json = configRead[module.name];
34
+ if (json == undefined) {
35
+ throw new Error(`NO JSON data found payment config ${module.name}`);
36
+ }
37
+ json.path = mainModulePath;
38
+ json.name = module.name;
39
+ setModule[module.name] = await require(startupPath)(program,json);
40
+ } catch (err) {
41
+ console.error(`Error Setting Module Data`,module.name);
42
+ console.error(err);
43
+ }
44
+ }
45
+
46
+ // Put in program modules
47
+ //program.modules.request = setModule;
48
+
49
+ // Here we can do whatever like grab modules for generator and represent them here
50
+ return setModule;
51
+ }
52
+ }
@@ -0,0 +1,132 @@
1
+ module.exports = async function(program,json) {
2
+ console.log(`Init Create with json data`);
3
+ return async function(program,order,payment,price,currency) {
4
+ console.log(`Create Payment`);
5
+ //const price = Number(order.price).toFixed(2);
6
+ // Get order info data
7
+ let pipeline = [
8
+ {
9
+ $match: {
10
+ uuid: order.package
11
+ }
12
+ }
13
+ ];
14
+ let package = await program.modules.data.aggregate(program,process.env.dbName, 'pricing', pipeline);
15
+ if (package.length == 0) {
16
+ throw new Error(`No Package found for payment`);
17
+ } else {
18
+ package = package[0];
19
+ }
20
+
21
+ // create redirect url
22
+ let webhookURL = program.modules.payment.mollie.webhookURL;
23
+ // create new payment uuid
24
+ const paymentUUID = program.uuid.v4();
25
+
26
+ const redirectURL = webhookURL.replace(`:orderId`,paymentUUID).replace(`:action`,`redirect`);
27
+ const cancelURL = webhookURL.replace(`:orderId`,paymentUUID).replace(`:action`,`cancel`);
28
+ const pageRedirect = webhookURL.replace(`:orderId`,paymentUUID).replace(`:action`,`page-redirect`);
29
+ webhookURL = webhookURL.replace(`:orderId`,paymentUUID).replace(`:action`,`update`);
30
+
31
+ const paramsArray = {
32
+ amount : {
33
+ currency : String(currency).toUpperCase(),
34
+ value : String(Number(price/100).toFixed(2))
35
+ },
36
+ description : `eSimCo. ${package.name.toUpperCase()}`,
37
+ redirectUrl : redirectURL,
38
+ cancelUrl : cancelURL,
39
+ webhookUrl : webhookURL,
40
+ locale : 'en_US',
41
+ method : payment.provider
42
+ }
43
+
44
+ // We have now method etc. let's build up the call
45
+ const getURL = `${json.url}/v2/payments`
46
+ const request = await program.modules.payment.mollie.post(program,getURL,paramsArray,{
47
+ 'Authorization': `Bearer ${json.key}`,
48
+ 'content-type': 'application/json'
49
+ })
50
+
51
+ // WE made request
52
+ request.uuid = paymentUUID;
53
+ request.package = order.package;
54
+ request.user = order.user;
55
+ request.order = order.uuid;
56
+
57
+ // Now save to request DB
58
+ const create = await program.modules.data.insert(process.env.dbName,`payment`,request);
59
+
60
+ // Now upate
61
+ let newState = order.state;
62
+ newState[`waiting`] = Date.now();
63
+
64
+ console.log(`Updated`);
65
+
66
+ console.log(`Made Request`,request);
67
+
68
+ // Now send response
69
+ let redirect = {
70
+ type : true,
71
+ url : request._links.checkout.href,
72
+ requestID : program.uuid.v4(),
73
+ full : true
74
+ }
75
+
76
+ // Check url
77
+ redirect.url = pageRedirect;
78
+
79
+ // Send Payment info per bot and link for order
80
+ console.log(`Send Payment info link per bot`);
81
+ // create payment url
82
+ const orderURL = `${process.env.webURL.slice(0,-1)}/concepts/esimco/order#${request.order}__redirect`;
83
+ // create order url redirect url
84
+ const paymentRedirect = `${process.env.url.slice(0,-1)}/webhooks/orders/${request.uuid}/bot-redirect`;
85
+
86
+ // Create message
87
+ let payIcon = `!`;
88
+ if (request.amount.currency.toUpperCase() == `USD`) {
89
+ payIcon = `$`;
90
+ }
91
+ if (request.amount.currency.toUpperCase() == `EUR`) {
92
+ payIcon = `€`;
93
+ }
94
+ const textMessage = `<b>⚠️ Your order is created but unpaid!</b>\n<span class="tg-spoiler">Order ID: <b>${request.order}</b></span>\n\nTo receive your order we would like to ask you to fullfill the payment for the remaining amount of <span class="tg-spoiler"><b>${payIcon} ${request.amount.value}</b></span>.\n\nClick on <u>Pay Now</u> to fullfill your payment or click <u>view order</u> to view your order.`
95
+ try {
96
+ let telegramSend = await program.modules.telegram.functions.send(program,textMessage,request.user,[
97
+ [
98
+ //{ text: 'View Order', web_app : { url : orderURL}},
99
+ { text: 'Pay Order', web_app : { url : paymentRedirect}}
100
+ ]
101
+ ]);
102
+
103
+ // Now we have message id set that to the order
104
+
105
+ // Add update to message order thingy
106
+
107
+ const updated =await program.modules.data.update(process.env.dbName,`order`,{
108
+ uuid : order.uuid
109
+ },{
110
+ $set: {
111
+ state : newState,
112
+ payment : paymentUUID,
113
+ messages : [telegramSend.result.uuid]
114
+ }
115
+ });
116
+ console.log(`Telegram Send`);
117
+ } catch (err) {
118
+ console.error(err);
119
+ console.error(`Error with sending to client`);
120
+ }
121
+
122
+
123
+ const sendArray = {
124
+ func : `redirect`,
125
+ data : {
126
+ event : redirect
127
+ },
128
+ js : `delete web.fast.tmp.sending;`
129
+ };
130
+ return sendArray;
131
+ }
132
+ }
@@ -0,0 +1,360 @@
1
+ module.exports = async function(program,json) {
2
+ console.log(`Pocess Startup`);
3
+ // Process startup for mollie
4
+ if (!json.active) {
5
+ return false;
6
+ }
7
+
8
+ if (json.url[json.url.length-1] == `/`) {
9
+ json.url = json.url.slice(0, -1)
10
+ }
11
+
12
+ // When active startup process by indexing functions
13
+ const functionPath = program.path.join(json.path,`functions`);
14
+ console.log(`Function Path`);
15
+ let restArray = {
16
+ create : await require(program.path.join(__dirname,`create.js`))(program,json),
17
+ get : async function(url,params) {
18
+ console.log(`GET`);
19
+
20
+ // Process params for url
21
+ let count = 0;
22
+ for (let param in params) {
23
+ console.log(`Param ${param}`);
24
+ if (count == 0) {
25
+ url += `?`;
26
+ } else {
27
+ url += `&`
28
+ }
29
+ url += `${param}=${params[param]}`;
30
+ count++;
31
+ }
32
+
33
+ const data = await program.modules.request.get(program, url, undefined, {
34
+ 'Authorization': `Bearer ${json.key}`
35
+ })
36
+
37
+ return data;
38
+ },
39
+ post : async function(program,url,body,headers) {
40
+ console.log(`POST`);
41
+
42
+ const requestPOST = await program.modules.request.post(program,url,body,headers);
43
+ return requestPOST;
44
+ }
45
+ }
46
+
47
+ // Start sync
48
+ //https://api.frankfurter.app/latest?to=EUR%2CUSD
49
+ restArray.currencySync = async function() {
50
+ const data = await program.modules.request.get(program, `https://api.frankfurter.app/latest`);
51
+ // process
52
+ console.log(`Process Data`);
53
+ data.ts = Date.now();
54
+ program.tmp.currency = data;
55
+ }
56
+ restArray.int = setInterval(function(){
57
+ console.log(`Set INterval`);
58
+ restArray.currencySync();
59
+ console.log(Date.now(),program.tmp.currency);
60
+ },14 * 60 * 1000)
61
+
62
+ // Sync Onces
63
+ await restArray.currencySync();
64
+
65
+ // In init we want to do the get request
66
+ const getURL = `${json.url}/v2/methods/all`
67
+ const requestUSD = await restArray.get(getURL,{
68
+ locale : "en_US",
69
+ 'amount[value]' : "100.00",
70
+ 'amount[currency]' : "USD",
71
+ "include" : "pricing"
72
+ })
73
+
74
+ const requestEU = await restArray.get(getURL,{
75
+ locale : "en_US",
76
+ 'amount[value]' : "100.00",
77
+ 'amount[currency]' : "EUR",
78
+ "include" : "pricing"
79
+ })
80
+
81
+ // Process both
82
+ // Check who bigger then other
83
+ let mainLoop;
84
+ let subLoop;
85
+ if (requestEU.count > requestUSD.count) {
86
+ mainLoop = requestEU._embedded.methods;
87
+ subLoop = requestUSD._embedded.methods;
88
+ } else {
89
+ mainLoop = requestUSD._embedded.methods;
90
+ subLoop = requestEU._embedded.methods;
91
+ }
92
+
93
+ // Make paymentArray
94
+ let payar = {}
95
+
96
+ // Set to arrays
97
+ // Loop Through main
98
+ const loopthrough = [mainLoop,subLoop];
99
+ for (let l in loopthrough) {
100
+ let currentLoop = loopthrough[l];
101
+ for (let nm in currentLoop) {
102
+ const itemData = currentLoop[nm];
103
+
104
+ // Set data
105
+ if (itemData.status == undefined) {
106
+ continue;
107
+ }
108
+ if (payar[itemData.id] == undefined) {
109
+ payar[itemData.id] = {
110
+ desc : itemData.description,
111
+ status : itemData.status,
112
+ res : itemData.resource,
113
+ images : itemData.image,
114
+ currency : {},
115
+ pricing : {
116
+ items : itemData.pricing
117
+ }
118
+ }
119
+ }
120
+
121
+ // Now loop through pricing to see max and min
122
+ let allPricing = [];
123
+
124
+ let maxPers = 0;
125
+ let minPers = 0;
126
+ let maxFix = 0;
127
+ let minFix = 0;
128
+ let pricingCurrency = [];
129
+ for (let prI in itemData.pricing) {
130
+ // get item
131
+ const pricing = itemData.pricing[prI];
132
+
133
+ let setPricing = {};
134
+
135
+ for (let key in pricing) {
136
+ switch (key) {
137
+ case `variable`:
138
+ const thePerc = Number(pricing[key]);
139
+ if (thePerc > maxPers) {
140
+ maxPers = thePerc;
141
+ }
142
+ if (thePerc < minPers || minPers == 0) {
143
+ minPers = thePerc;
144
+ }
145
+ setPricing.percentage = thePerc;
146
+ break;
147
+ case `fixed`:
148
+ const fixPrice = Number(pricing[key].value);
149
+ // Set fix price
150
+ if (fixPrice > maxFix) {
151
+ maxFix = fixPrice;
152
+ }
153
+ if (fixPrice < minFix || minFix == 0) {
154
+ minFix = fixPrice;
155
+ }
156
+ pricing[key].value = Number(pricing[key].value);
157
+ setPricing[key] = pricing[key];
158
+
159
+ // check if in array
160
+ if (pricingCurrency.indexOf(pricing[key].currency) == -1) {
161
+ pricingCurrency.push(pricing[key].currency)
162
+ }
163
+ break;
164
+ default:
165
+ console.log(`Set Just: ${key}`);
166
+ setPricing[key] = pricing[key];
167
+ }
168
+ }
169
+ allPricing.push(setPricing);
170
+ }
171
+ console.log(`We have all pricing per item now`);
172
+ itemData.pricing = {
173
+ all : allPricing,
174
+ perc : {
175
+ min : minPers,
176
+ max : maxPers
177
+ },
178
+ fix : {
179
+ min : minFix,
180
+ max : maxFix
181
+ },
182
+ currencies : pricingCurrency
183
+ }
184
+ payar[itemData.id].pricing = itemData.pricing;
185
+
186
+ // Now grab currency
187
+ const currency = {
188
+ max : itemData.maximumAmount.value,
189
+ min : itemData.minimumAmount.value
190
+ };
191
+
192
+ if (payar[itemData.id].currency[itemData.minimumAmount.currency] == undefined) {
193
+ payar[itemData.id].currency[itemData.minimumAmount.currency] = currency;
194
+ } else {
195
+ console.error(`Currency already set`);
196
+ }
197
+ }
198
+ }
199
+
200
+ restArray.methods = payar;
201
+
202
+ // Create dynamic app get for receiving data
203
+ const fullPath = `${process.env.url.slice(0,-1)}/webhooks/orders/:orderId/:action`;
204
+ // setup dynamic routing
205
+ restArray.webhookURL = fullPath;
206
+ async function functionRequest(req,res,type) {
207
+ const orderId = req.params.orderId;
208
+ const action = req.params.action;
209
+ console.log(`Received data for payment`,type);
210
+
211
+ // Get body Data
212
+ const body = req.body;
213
+
214
+ // First grab order
215
+ let pipeline = [
216
+ {
217
+ $match: {
218
+ uuid: orderId
219
+ }
220
+ }
221
+ ];
222
+
223
+ let payment = await program.modules.data.aggregate(program,process.env.dbName, 'payment', pipeline);
224
+ if (payment.length == 0) {
225
+ res.status(500);
226
+ res.send(`FALSE`);
227
+ } else {
228
+ payment = payment[0];
229
+ }
230
+
231
+ console.log(`We have payment data`);
232
+
233
+ // Check if cancel
234
+ let order = await program.modules.data.aggregate(program,process.env.dbName, 'order', [
235
+ {
236
+ $match: {
237
+ uuid: payment.order
238
+ }
239
+ }
240
+ ]);
241
+ order = order[0];
242
+
243
+ // We have order add action to state
244
+ const typeOf = typeof order.state;
245
+ if (typeOf != `object`) {
246
+ order.state = [];
247
+ }
248
+ order.state[action] = Date.now();
249
+
250
+
251
+ // Get id
252
+ if (type == `post`) {
253
+ const paymentID = body.id;
254
+
255
+ // Now check payment
256
+ const getURL = `${json.url}/v2/payments/${paymentID}`
257
+ const validate = await restArray.get(getURL);
258
+
259
+ // Okay we have new data
260
+ const status = validate.status;
261
+
262
+ order.state[status] = Date.now();
263
+
264
+ console.log(`To Validate Payment`);
265
+
266
+ // Add completed to state if finished
267
+ if (status == `paid`) {
268
+ const paidDate = new Date(validate.paidAt);
269
+ const unixTimestamp = Math.floor(paidDate.getTime() / 1000);
270
+ order.state[`completed`] = unixTimestamp;
271
+
272
+ // Update
273
+ const updatedFinal =await program.modules.data.update(process.env.dbName,`order`,{
274
+ uuid : orderId
275
+ },{
276
+ $set: {
277
+ payed : unixTimestamp,
278
+ paymentDetails : validate.details,
279
+ countryCode : validate.countryCode,
280
+ mode : validate.mode,
281
+ state : true,
282
+ paid : Date.now()
283
+ }
284
+ });
285
+ console.log(`Final Update`,updatedFinal);
286
+
287
+ // Check also for message now
288
+ // Grab message
289
+ try {
290
+ const lastMessageId = order.messages[0];
291
+ let messageData = await program.modules.data.aggregate(program,process.env.dbName, 'send', [{$match: {uuid: lastMessageId}}]);
292
+ if (messageData.length == 0) {
293
+ // No message send
294
+ console.error(`No Message Send`);
295
+ } else {
296
+ messageData = messageData[0];
297
+ }
298
+
299
+ const packageID = order.package;
300
+
301
+ let packageLine = [{$match: {uuid:packageID}},{$project: {name: 1,description: 1, price:1}}];
302
+ let packageData = await program.modules.data.aggregate(program,process.env.dbName, 'pricing', packageLine);
303
+
304
+ // Okay we have message data
305
+ const orderURL = `${process.env.webURL.slice(0,-1)}/concepts/esimco/order#${payment.uuid}__redirect`;
306
+ const howToURL = `${process.env.webURL.slice(0,-1)}/concepts/esimco/order#${payment.uuid}__how-to`;
307
+ const referralURL = `${process.env.webURL.slice(0,-1)}/concepts/esimco/order#${payment.uuid}__referral`;
308
+
309
+ const textMessage = `<b>✅ Your payment is received!</b>\n<span class="tg-spoiler">Order ID: <b>${order.uuid}</b></span>\n\nWe are now matching your order and payment. You will receive your ordered prodcut in a few minutes: <b>${String(packageData[0].description).toUpperCase()}</b>`
310
+ try {
311
+ let telegramSend = await program.modules.telegram.functions.send(program,textMessage,order.user,[
312
+ [
313
+ { text: 'View Order', web_app : { url : orderURL}},
314
+ { text: 'How to?', web_app : { url : howToURL}},
315
+ { text: 'Referral', web_app : { url : referralURL}}
316
+ ]
317
+ ],messageData.message_id);
318
+
319
+ console.log(`Sending telegram`);
320
+ } catch(err) {
321
+ console.error(err);
322
+ console.error(`Error updating message`);
323
+ }
324
+
325
+ } catch (err) {
326
+ console.error(err);
327
+ console.error(`Something with message`);
328
+ }
329
+ }
330
+ }
331
+
332
+
333
+ const updated =await program.modules.data.update(process.env.dbName,`order`,{
334
+ uuid : order.uuid
335
+ },{
336
+ $set: {
337
+ state : order.state
338
+ }
339
+ });
340
+
341
+ // Updated state in order
342
+ // Now redirect doesn't matter in what
343
+ const fullPath = `${process.env.webURL.slice(0,-1)}/concepts/esimco/order#${order.uuid}__redirect`;
344
+ if (type == `post`) {
345
+ res.send(`OK`);
346
+ res.status(200);
347
+ } else if (action == `page-redirect` || action == `bot-redirect`) {
348
+ res.redirect(payment._links.checkout.href)
349
+ } else {
350
+ res.redirect(fullPath);
351
+ }
352
+ }
353
+ program.express.app.get(`/webhooks/orders/:orderId/:action`, async function(req,res){
354
+ return await functionRequest(req,res,`get`);
355
+ })
356
+ program.express.app.post(`/webhooks/orders/:orderId/:action`, async function(req,res){
357
+ return await functionRequest(req,res,`post`);
358
+ })
359
+ return restArray;
360
+ }
@@ -15,6 +15,10 @@ module.exports = async function(program, url, body,headers) {
15
15
  body: JSON.stringify(body),
16
16
  };
17
17
 
18
+ if (body == undefined) {
19
+ delete theOptions.body;
20
+ }
21
+
18
22
  // Using standard fetch function
19
23
  const response = await fetch(url, theOptions);
20
24
  // Get response body
@@ -24,7 +28,7 @@ module.exports = async function(program, url, body,headers) {
24
28
  const respHeaders = response.headers;
25
29
 
26
30
  if (!response.ok) {
27
- throw new Error(`HTTP error! Status: ${response.status}`);
31
+ throw new Error(respBody);
28
32
  }
29
33
 
30
34
  const responseData = respBody;
@@ -33,7 +37,7 @@ module.exports = async function(program, url, body,headers) {
33
37
  // Return response data or true to indicate success
34
38
  return responseData || true;
35
39
  } catch (err) {
36
- console.error('Error in post:', err.message);
40
+ console.error('Error in get:', err.message);
37
41
  return false;
38
42
  }
39
43
  };
@@ -24,7 +24,17 @@ module.exports = async function(program, url, body,headers) {
24
24
  const respHeaders = response.headers;
25
25
 
26
26
  if (!response.ok) {
27
+ if (respBody.parameters != undefined) {
28
+ // Probably some wait
29
+ if (respBody.parameters.retry_after != undefined) {
30
+ const timeOUtAmount = respBody.parameters.retry_after * 1000*60; // for 1 minute if retry_ is 1 minute
31
+ await setTimeout(async function(){
32
+ return await program.modules.request.post(program,url,body,headers);
33
+ },timeOUtAmount);
34
+ }
35
+ } else {
27
36
  throw new Error(`HTTP error! Status: ${response.status}`);
37
+ }
28
38
  }
29
39
 
30
40
  const responseData = respBody;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webfast",
3
- "version": "0.1.86",
3
+ "version": "0.1.88",
4
4
  "description": "WebFast! Bot Application, including TON mini-apps for makign it easy and fast to build ini-apps",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -35,7 +35,15 @@
35
35
  "model",
36
36
  "mini app",
37
37
  "webflow",
38
- "lowcode"
38
+ "lowcode",
39
+ "mollie",
40
+ "payment",
41
+ "ideal",
42
+ "creditcard",
43
+ "applepay",
44
+ "googlepay",
45
+ "mollie pay",
46
+ "payments"
39
47
  ],
40
48
  "author": "Kai Gartner",
41
49
  "license": "ISC",