node-paytmpg 5.3.2 → 6.4.2

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.
@@ -1,101 +1,111 @@
1
- module.exports = function (modelName, db) {
2
-
3
- class MultiDbMapper {
4
-
5
- idFieldName
6
- objectData
7
- constructor(objectData) {
8
- MultiDbMapper.sanitizeRequest(objectData)
9
- this.objectData = objectData;
10
- }
11
-
12
-
13
- static async sanitizeRequest(body) {
14
-
15
- if (!body)
16
- return;
17
- if (body.amount)
18
- body.amount = parseFloat(body.amount);
19
- if (body.TXN_AMOUNT)
20
- body.amount = parseFloat(body.TXN_AMOUNT);
21
- }
22
-
23
- async save() {
24
- var response = await MultiDbMapper.db.insert(MultiDbMapper.modelname, this.objectData,this.objectData[MultiDbMapper.idFieldName]);
25
- if ( typeof response == Object && response.ops[0])
26
- response = response.ops[0];
27
- else
28
- response = this.objectData
29
-
30
- MultiDbMapper.sanitizeRequest(response)
31
-
32
- return response;
33
- }
34
-
35
- //callback(err,resp)
36
- static async findOne(query, cb) {
37
-
38
- var response;
39
- try {
40
- response = await MultiDbMapper.db.getOne(MultiDbMapper.modelname, query);
41
- MultiDbMapper.sanitizeRequest(response)
42
- } catch (e) {
43
- if (cb)
44
- return cb(e, undefined)
45
- else
46
- throw e;
47
- }
48
- if (cb)
49
- cb(undefined, response);
50
- else
51
- return response;
52
- }
53
-
54
- static async updateOne(query, newValue, cb) {
55
-
56
- var response;
57
- try {
58
-
59
- response = await MultiDbMapper.db.update(MultiDbMapper.modelname, query, newValue['$set']);
60
-
61
- } catch (e) {
62
- if (cb)
63
- return cb(e, undefined)
64
- else
65
- throw e;
66
- }
67
-
68
- if (cb)
69
- cb(undefined, response);
70
- else
71
- return response;
72
- }
73
-
74
- static async deleteOne(query, cb) {
75
-
76
- var response;
77
- try {
78
-
79
- response = await MultiDbMapper.db.delete(MultiDbMapper.modelname, query);
80
- MultiDbMapper.sanitizeRequest(response)
81
-
82
- } catch (e) {
83
- if (cb)
84
- return cb(e, undefined)
85
- else
86
- throw e;
87
- }
88
- if (cb)
89
- cb(undefined, response)
90
- else
91
- return response;
92
-
93
- }
94
-
95
- }
96
-
97
- MultiDbMapper.modelname = modelName;
98
- MultiDbMapper.db = db;
99
- return MultiDbMapper;
100
- }
101
-
1
+ module.exports = function (modelName, db, sampleData) {
2
+
3
+ if (db && sampleData && db.create) {
4
+ db.create(modelName, sampleData)
5
+ .then(() => {
6
+ console.log('Model Created in db ', modelName);
7
+ })
8
+ .catch((e) => {
9
+ console.log('Error in creating model ', e);
10
+ });
11
+ }
12
+
13
+ class MultiDbMapper {
14
+
15
+ idFieldName
16
+ objectData
17
+ constructor(objectData) {
18
+ MultiDbMapper.sanitizeRequest(objectData)
19
+ this.objectData = objectData;
20
+ }
21
+
22
+
23
+ static async sanitizeRequest(body) {
24
+
25
+ if (!body)
26
+ return;
27
+ if (body.amount)
28
+ body.amount = parseFloat(body.amount);
29
+ if (body.TXN_AMOUNT)
30
+ body.amount = parseFloat(body.TXN_AMOUNT);
31
+ }
32
+
33
+ async save() {
34
+ var response = await MultiDbMapper.db.insert(MultiDbMapper.modelname, this.objectData, this.objectData[MultiDbMapper.idFieldName]);
35
+ if (typeof response == Object && response.ops[0])
36
+ response = response.ops[0];
37
+ else
38
+ response = this.objectData
39
+
40
+ MultiDbMapper.sanitizeRequest(response)
41
+
42
+ return response;
43
+ }
44
+
45
+ //callback(err,resp)
46
+ static async findOne(query, cb) {
47
+
48
+ var response;
49
+ try {
50
+ response = await MultiDbMapper.db.getOne(MultiDbMapper.modelname, query);
51
+ MultiDbMapper.sanitizeRequest(response)
52
+ } catch (e) {
53
+ if (cb)
54
+ return cb(e, undefined)
55
+ else
56
+ throw e;
57
+ }
58
+ if (cb)
59
+ cb(undefined, response);
60
+ else
61
+ return response;
62
+ }
63
+
64
+ static async updateOne(query, newValue, cb) {
65
+
66
+ var response;
67
+ try {
68
+
69
+ response = await MultiDbMapper.db.update(MultiDbMapper.modelname, query, newValue['$set']);
70
+
71
+ } catch (e) {
72
+ if (cb)
73
+ return cb(e, undefined)
74
+ else
75
+ throw e;
76
+ }
77
+
78
+ if (cb)
79
+ cb(undefined, response);
80
+ else
81
+ return response;
82
+ }
83
+
84
+ static async deleteOne(query, cb) {
85
+
86
+ var response;
87
+ try {
88
+
89
+ response = await MultiDbMapper.db.delete(MultiDbMapper.modelname, query);
90
+ MultiDbMapper.sanitizeRequest(response)
91
+
92
+ } catch (e) {
93
+ if (cb)
94
+ return cb(e, undefined)
95
+ else
96
+ throw e;
97
+ }
98
+ if (cb)
99
+ cb(undefined, response)
100
+ else
101
+ return response;
102
+
103
+ }
104
+
105
+ }
106
+
107
+ MultiDbMapper.modelname = modelName;
108
+ MultiDbMapper.db = db;
109
+ return MultiDbMapper;
110
+ }
111
+
@@ -1,93 +1,98 @@
1
- <h2>Payment Start</h2>
2
-
3
- <form action="{{action}}" method="POST">
4
- <ul class="form-list">
5
- {{#if check}}
6
-
7
- <li class="form-list__row">
8
- <label>Name</label>
9
- <input type="text" name="NAME" required="" value="{{NAME}}" {{readonly}} />
10
- </li>
11
- {{else}}
12
- <input type="hidden" name="NAME" required="" value="{{NAME}}" {{readonly}} />
1
+ <div class="checkout-grid">
2
+ <aside class="product-panel card">
3
+ {{#if productImage}}
4
+ <div class="product-preview">
5
+ <img src="{{productImage}}" alt="{{PRODUCT_NAME}}" style="width:100%;height:100%;object-fit:cover" />
6
+ </div>
7
+ {{/if}}
8
+
9
+ <div class="product-price">
10
+ <div class="pill">Product</div>
11
+ <div class="price">{{PRODUCT_NAME}}</div>
12
+ </div>
13
+ {{#if PRODUCT_DESC}}
14
+ <p class="helper" style="margin-top:14px;">{{PRODUCT_DESC}}</p>
15
+ {{/if}}
16
+ </aside>
17
+
18
+ <section class="form-panel card">
19
+ <header class="card__header">
20
+ <div>
21
+ <p class="eyebrow">Payment</p>
22
+ <h2>Review &amp; pay</h2>
23
+ </div>
24
+ <div class="amount-chip">₹ {{TXN_AMOUNT}}</div>
25
+ </header>
13
26
 
14
- {{/if}}
15
- <li class="form-list__row">
16
- <label>E-Mail</label>
17
- <input type="text" name="EMAIL" required="" value="{{EMAIL}}" {{readonly}} />
18
- </li>
27
+ <p class="helper">Your payment is processed over an encrypted channel. Double-check the details before you continue.</p>
19
28
 
20
- <li class="form-list__row">
21
- <label>Phone</label>
22
- <input type="text" name="MOBILE_NO" required="" value="{{MOBILE_NO}}" {{readonly}} />
23
- </li>
29
+ <form action="{{action}}" method="POST" class="form-grid" id="payment-form">
30
+ {{#if check}}
31
+ <label class="field">
32
+ <span class="field__label">Full Name</span>
33
+ <input type="text" name="NAME" required value="{{NAME}}" {{readonly}} />
34
+ </label>
35
+ {{else}}
36
+ <input type="hidden" name="NAME" required value="{{NAME}}" {{readonly}} />
37
+ {{/if}}
24
38
 
39
+ <label class="field">
40
+ <span class="field__label">Email address</span>
41
+ <input type="email" name="EMAIL" required value="{{EMAIL}}" {{readonly}} />
42
+ </label>
25
43
 
26
- <li class="form-list__row">
44
+ <label class="field">
45
+ <span class="field__label">Phone</span>
46
+ <input type="text" name="MOBILE_NO" required value="{{MOBILE_NO}}" {{readonly}} />
47
+ </label>
27
48
 
28
49
  {{#if check}}
29
-
30
- <div>
31
- <label>
32
- Product
33
- </label>
34
- <input type="text" name="PRODUCT_NAME" required="" value="{{PRODUCT_NAME}}" {{readonly}} />
35
- </div>
50
+ <label class="field">
51
+ <span class="field__label">Product</span>
52
+ <input type="text" name="PRODUCT_NAME" required value="{{PRODUCT_NAME}}" {{readonly}} />
53
+ </label>
36
54
  {{else}}
37
- <input type="hidden" name="PRODUCT_NAME" required="" value="{{PRODUCT_NAME}}" {{readonly}} />
55
+ <input type="hidden" name="PRODUCT_NAME" required value="{{PRODUCT_NAME}}" {{readonly}} />
38
56
  {{/if}}
39
57
 
40
- </li>
41
- <li class="form-list__row">
58
+ <label class="field">
59
+ <span class="field__label">Amount</span>
60
+ <input type="text" name="TXN_AMOUNT" required value="{{TXN_AMOUNT}}" {{readonly}} />
61
+ </label>
42
62
 
43
- <div>
44
- <label>
45
- Amount
63
+ <div style="grid-column:1 / -1; display:flex; gap:10px; align-items:center; justify-content:space-between;">
64
+ <label class="checkbox" style="margin:0">
65
+ <input type="checkbox" name="save_cc" checked="checked" />
66
+ <span>I agree to the merchant terms</span>
46
67
  </label>
47
- <input type="text" name="TXN_AMOUNT" required="" value="{{TXN_AMOUNT}}" {{readonly}} />
68
+ <div style="font-size:12px; color:rgba(255,255,255,0.6)">Secure by PCI-DSS</div>
48
69
  </div>
49
70
 
50
- </li>
51
-
52
- {{#if check}}
53
-
54
- <li class="form-list__row form-list__row--agree">
55
- <label>
56
- <input type="checkbox" name="save_cc" checked="checked">
57
- I agree to terms and conditions
58
- </label>
59
- </li>
60
- {{/if}}
61
-
62
- <li>
63
- <button id="show_button" type="submit" class="button">{{BUTTON}}</button>
64
- </li>
65
-
66
- <script>
67
- var button = document.getElementById('show_button')
68
- button.addEventListener('click',hideshow,false);
69
-
70
- function hideshow() {
71
- document.getElementById('show_button').style.display = 'none';
72
- }
73
- </script>
74
-
75
- </ul>
76
-
77
-
78
-
79
- <input type="hidden" name="MID" value="{{MID}}" {{readonly}}>
80
- <input type="hidden" name="WEBSITE" value="{{WEBSITE}}" {{readonly}}>
81
- <input type="hidden" name="ORDER_ID" value="{{ORDER_ID}}" {{readonly}}>
82
- <input type="hidden" name="CUST_ID" value="{{CUST_ID}}" {{readonly}}>
83
- <input type="hidden" name="INDUSTRY_TYPE_ID" value="{{INDUSTRY_TYPE_ID}}" {{readonly}}>
84
- <input type="hidden" name="CHANNEL_ID" value="{{CHANNEL_ID}}" {{readonly}}>
85
- <input type="hidden" name="CALLBACK_URL" value="{{CALLBACK_URL}}" {{readonly}}>
86
- <input type="hidden" name="CHECKSUMHASH" value="{{CHECKSUMHASH}}" {{readonly}}>
87
-
88
-
89
-
90
-
91
-
92
-
93
- </form>
71
+ <button id="pay-button" type="submit" class="button">{{BUTTON}}</button>
72
+
73
+ <input type="hidden" name="MID" value="{{MID}}" {{readonly}} />
74
+ <input type="hidden" name="WEBSITE" value="{{WEBSITE}}" {{readonly}} />
75
+ <input type="hidden" name="ORDER_ID" value="{{ORDER_ID}}" {{readonly}} />
76
+ <input type="hidden" name="CUST_ID" value="{{CUST_ID}}" {{readonly}} />
77
+ <input type="hidden" name="INDUSTRY_TYPE_ID" value="{{INDUSTRY_TYPE_ID}}" {{readonly}} />
78
+ <input type="hidden" name="CHANNEL_ID" value="{{CHANNEL_ID}}" {{readonly}} />
79
+ <input type="hidden" name="CALLBACK_URL" value="{{CALLBACK_URL}}" {{readonly}} />
80
+ <input type="hidden" name="CHECKSUMHASH" value="{{CHECKSUMHASH}}" {{readonly}} />
81
+ </form>
82
+ </section>
83
+ </div>
84
+
85
+ {{!-- <script>
86
+ (function(){
87
+ if (window.__npPayBtnBound) return;
88
+ window.__npPayBtnBound = true;
89
+ const payBtn = document.getElementById('pay-button');
90
+ if (payBtn) {
91
+ payBtn.addEventListener('click', () => {
92
+ payBtn.setAttribute('data-loading', 'true');
93
+ payBtn.setAttribute('disabled', 'disabled');
94
+ setTimeout(() => payBtn.innerText = 'Processing…', 10);
95
+ });
96
+ }
97
+ })();
98
+ </script> --}}
@@ -1,58 +1,53 @@
1
1
  <!DOCTYPE html>
2
- <html>
3
-
2
+ <html lang="en">
4
3
  <head>
5
- <meta charset="UTF-8">
6
- <title>Secure Pay</title>
7
- <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600" rel="stylesheet">
8
-
9
- <meta name="viewport" content="width=device-width, initial-scale=1">
10
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
11
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
12
-
13
- <link rel="stylesheet" href="css/style.css">
14
-
15
-
16
- </head>
17
-
18
- <body>
19
-
20
- <div class="modal">
21
- <div class="modal__container">
22
-
23
- <div class="modal__content">
24
-
25
-
26
-
27
-
28
- {{{body}}}
29
-
30
-
31
-
32
- </div> <!-- END: .modal__content -->
33
- </div> <!-- END: .modal__container -->
34
- </div> <!-- END: .modal -->
35
- <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
36
-
37
- <script src="js/index.js"></script>
38
-
39
-
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>{{brand}} · Secure Checkout</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet" />
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" />
11
+ <link rel="stylesheet" href="css/style.css" />
12
+ <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='3'%20fill='%23ff5722'/%3E%3C/svg%3E" />
13
+ <link rel="shortcut icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='3'%20fill='%23ff5722'/%3E%3C/svg%3E" />
40
14
  <style>
41
-
42
- input:focus {
43
- border-color: {{theme_color}};
44
- }
45
- /*
46
- body,
47
- .form-list__row label {
48
- color: #cc0f0f;
49
- }
50
- input {
51
- color: #cc0f0f;
15
+ :root {
16
+ --color-primary: {{theme.primary}};
17
+ --color-accent: {{theme.accent}};
18
+ --color-surface: {{theme.surface}};
19
+ --color-text: {{theme.text}};
20
+ --color-success: {{theme.success}};
21
+ --color-danger: {{theme.danger}};
22
+ --color-outline: rgba(255,255,255,0.08);
23
+ --radius: 14px;
52
24
  }
53
-
54
- */
55
25
  </style>
26
+ </head>
27
+ <body class="theme-{{themeName}}">
28
+ <div class="shell">
29
+ <header class="shell__header">
30
+ <div class="brand">
31
+ {{#if logo}}
32
+ <span class="brand__mark brand__mark--img"><img src="{{logo}}" alt="{{brand}} logo"></span>
33
+ {{else}}
34
+ <span class="brand__mark">{{brand}}</span>
35
+ {{/if}}
36
+ <div class="brand__text">
37
+ <div class="brand__title">{{brand}}</div>
38
+ <div class="brand__meta">Secure checkout</div>
39
+ </div>
40
+ </div>
41
+ <div class="pill">Encrypted</div>
42
+ </header>
43
+
44
+ <main class="shell__content">
45
+ {{{body}}}
46
+ </main>
47
+
48
+ <footer class="shell__footer">
49
+ <span>Protected by {{brand}}</span>
50
+ </footer>
51
+ </div>
56
52
  </body>
57
-
58
53
  </html>
@@ -1,50 +1,46 @@
1
- <h2>Payment Status</h2>
1
+ <section class="card" style="text-align:center; padding:36px 28px;">
2
+ <div style="display:flex; flex-direction:column; align-items:center; gap:18px;" class="status-{{status}}">
3
+ <div style="width:84px; height:84px; border-radius:999px; display:grid; place-items:center; background:rgba(255,255,255,0.03);">
4
+ <svg class="icon-success" width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M20 6L9 17l-5-5" stroke="#4cff9f" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
5
+ <svg class="icon-fail" width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display:none"><circle cx="12" cy="12" r="9" stroke="#ff9b9b" stroke-width="2.2"/><path d="M12 8v5" stroke="#ff9b9b" stroke-width="2.2" stroke-linecap="round"/><path d="M12 16h.01" stroke="#ff9b9b" stroke-width="2.2" stroke-linecap="round"/></svg>
6
+ </div>
2
7
 
3
- <form action="{{action}}" method="POST">
4
- <ul class="form-list">
5
-
8
+ <div>
9
+ <h2 style="margin:0">Payment</h2>
10
+ <p class="helper" style="margin-top:6px">{{message}}</p>
11
+ </div>
6
12
 
7
- <li class="form-list__row">
8
- <label>Order ID</label>
9
- <input type="text" name="NAME" required="" value="{{orderId}}" {{readonly}}/>
10
- </li>
13
+ <div class="result-grid" style="max-width:560px; width:100%;">
14
+ <div class="result-item">
15
+ <p class="label">Order ID</p>
16
+ <p class="value">{{orderId}}</p>
17
+ </div>
18
+ <div class="result-item">
19
+ <p class="label">Transaction ID</p>
20
+ <p class="value">{{TXNID}}</p>
21
+ </div>
22
+ <div class="result-item">
23
+ <p class="label">Amount</p>
24
+ <p class="value">{{amount}}</p>
25
+ </div>
26
+ <div class="result-item">
27
+ <p class="label">Date &amp; Time</p>
28
+ <p class="value">{{date}}</p>
29
+ </div>
30
+ </div>
11
31
 
12
- <li class="form-list__row">
13
- <label>Status</label>
14
- <input type="text" name="NAME" required="" value="{{status}}" {{readonly}}/>
15
- </li>
16
-
17
- <li class="form-list__row">
18
- <label>E-Mail</label>
19
- <input type="text" name="EMAIL" required="" value="{{email}}" {{readonly}}/>
20
- </li>
21
-
22
- <li class="form-list__row">
23
- <label>Phone</label>
24
- <input type="text" name="MOBILE_NO" required="" value="{{phone}}" {{readonly}}/>
25
- </li>
26
-
27
-
28
- <li class="form-list__row form-list__row--inline">
29
-
30
- <div>
31
- <label>
32
- Amount
33
- </label>
34
- <input type="text" name="TXN_AMOUNT" required="" value="{{amount}}" {{readonly}} />
35
- </div>
36
-
37
- </li>
38
-
39
-
40
-
41
- <li>
42
- <button type="submit" class="button">DONE</button>
43
- </li>
44
- </ul>
45
-
46
-
47
-
48
-
49
-
50
- </form>
32
+ <div style="display:flex; gap:12px; margin-top:8px; width:100%; justify-content:center;">
33
+ <div class="success-buttons" style="display:flex; gap:12px;">
34
+ <a href="{{receiptUrl}}" class="button" style="text-decoration:none;">Download Receipt</a>
35
+ <form action="{{homeAction}}" method="GET" style="display:inline"><button type="submit" class="button">Done</button></form>
36
+ </div>
37
+ <div class="fail-buttons" style="display:flex; gap:12px;">
38
+ <form action="{{retryAction}}" method="POST" style="display:inline">
39
+ <input type="hidden" name="ORDER_ID" value="{{orderId}}" />
40
+ <button type="submit" class="button">Try Again</button>
41
+ </form>
42
+ <form action="{{cancelAction}}" method="GET" style="display:inline"><button type="submit" class="button">Cancel</button></form>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </section>