webfast 0.1.86 → 0.1.88

Sign up to get free protection for your applications and to get access to all the features.
@@ -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",