quickpos 1.0.901 → 1.0.902

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,68 @@
1
+ const express = require('express');
2
+ const bodyParser = require('body-parser');
3
+ const QuickPos = require('./app');
4
+
5
+ const app = express();
6
+ app.use(bodyParser.urlencoded({ extended: true }));
7
+ // app.use(require('multer')().none());
8
+
9
+ const quickPos = new QuickPos({
10
+ providers: {
11
+ bufpay: {
12
+ appId: 'xxxx',
13
+ appSecret: 'xxx'
14
+ }
15
+ }
16
+ });
17
+
18
+ app.use(quickPos.middleware());
19
+
20
+ quickPos.providers['bufpay'].createPayment({
21
+ name: 'Product Name',
22
+ payType: 'alipay',
23
+ price: '100.00',
24
+ orderId: 'ORDER123',
25
+ orderUid: 'user@example.com',
26
+ notifyUrl: 'https://your-domain.com/webhook'
27
+ })
28
+ .then(response => console.log(response))
29
+ .catch(error => console.error(error));
30
+
31
+ app.post('/shopierWebhook', quickPos.handleCallback('shopier'), (req, res) => {
32
+ try {
33
+ console.log('Payment result:', req.paymentResult.data.chartDetails);
34
+ /*
35
+ Payment result: {
36
+ status: 'success',
37
+ data: {
38
+ email: 'fastuptime@gmail.com',
39
+ orderId: '313758163',
40
+ currency: 0,
41
+ price: '1',
42
+ buyerName: 'Can',
43
+ buyerSurname: 'Kaya',
44
+ productId: 31857020,
45
+ productCount: 1,
46
+ customerNote: '',
47
+ productList: '31857020',
48
+ chartDetails: [ [Object] ],
49
+ isTest: 1
50
+ }
51
+ }
52
+ */
53
+ if (!(req.body.res && req.body.hash)) {
54
+ return res.status(400).send('missing parameter');
55
+ }
56
+
57
+ // İşlem başarılı
58
+ res.send('success');
59
+ } catch (error) {
60
+ console.error('Webhook error:', error);
61
+ res.status(500).send('error');
62
+ }
63
+ });
64
+
65
+ const PORT = 80;
66
+ app.listen(PORT, () => {
67
+ console.log(`Webhook server running on port ${PORT}`);
68
+ });
package/example.js CHANGED
@@ -9,9 +9,9 @@ app.use(bodyParser.json());
9
9
  const quickPos = new QuickPos({
10
10
  providers: {
11
11
  paytr: {
12
- merchantId: '347042',
13
- merchantKey: 'XxXxx',
14
- merchantSalt: 'XxxXxxX',
12
+ merchantId: 'xx',
13
+ merchantKey: 'xx',
14
+ merchantSalt: 'xxx',
15
15
  mode: 'test',
16
16
  }
17
17
  },
package/lib/bufpay.js ADDED
@@ -0,0 +1,215 @@
1
+ const crypto = require('crypto');
2
+ const axios = require('axios');
3
+
4
+ class BufPay {
5
+ constructor(config) {
6
+ this.config = config || {};
7
+ const requiredFields = ['appId', 'appSecret'];
8
+ for (let field of requiredFields) {
9
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
10
+ }
11
+
12
+ this.appId = config.appId;
13
+ this.appSecret = config.appSecret;
14
+ this.baseUrl = 'https://bufpay.com/api';
15
+ }
16
+
17
+ async createPayment(paymentDetails) {
18
+ try {
19
+ // console.log('Creating payment with details:', JSON.stringify(paymentDetails, null, 2));
20
+
21
+ let requiredData = ['name', 'payType', 'price', 'orderId', 'orderUid', 'notifyUrl'];
22
+ for (let data of requiredData) {
23
+ if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
24
+ }
25
+
26
+ const signature = this.generateToken(
27
+ paymentDetails.name,
28
+ paymentDetails.payType,
29
+ paymentDetails.price,
30
+ paymentDetails.orderId,
31
+ paymentDetails.orderUid,
32
+ paymentDetails.notifyUrl,
33
+ paymentDetails.returnUrl || '',
34
+ paymentDetails.feedbackUrl || '',
35
+ this.appSecret
36
+ );
37
+
38
+ // console.log('Generated signature:', signature);
39
+
40
+ const formData = {
41
+ name: paymentDetails.name,
42
+ pay_type: paymentDetails.payType,
43
+ price: paymentDetails.price,
44
+ order_id: paymentDetails.orderId,
45
+ order_uid: paymentDetails.orderUid,
46
+ notify_url: paymentDetails.notifyUrl,
47
+ return_url: paymentDetails.returnUrl || '',
48
+ feedback_url: paymentDetails.feedbackUrl || '',
49
+ sign: signature
50
+ };
51
+
52
+ // console.log('Sending request with form data:', JSON.stringify(formData, null, 2));
53
+
54
+ const response = await axios({
55
+ method: 'POST',
56
+ url: `${this.baseUrl}/pay/${this.appId}?format=json`,
57
+ headers: {
58
+ 'Content-Type': 'application/x-www-form-urlencoded'
59
+ },
60
+ data: new URLSearchParams(formData).toString()
61
+ });
62
+
63
+ // console.log('Received response:', JSON.stringify(response.data, null, 2));
64
+
65
+ if (!response.data) {
66
+ throw new Error('Empty response received from BufPay API');
67
+ }
68
+
69
+ const responseData = response.data;
70
+
71
+ // Log the full response for debugging
72
+ // console.log('Response status:', responseData.status);
73
+ // console.log('Full response:', JSON.stringify(responseData, null, 2));
74
+
75
+ if (responseData.status === 'success' || responseData.status === 'ok') {
76
+ return {
77
+ status: 'success',
78
+ data: {
79
+ aoid: responseData.aoid,
80
+ pay_type: responseData?.pay_type,
81
+ price: responseData?.price,
82
+ qr_price: responseData?.qr_price,
83
+ qr: responseData?.qr,
84
+ cid: responseData?.cid,
85
+ expires_in: responseData?.expires_in,
86
+ return_url: responseData?.return_url,
87
+ feedback_url: responseData?.feedback_url
88
+ }
89
+ };
90
+ } else {
91
+ return {
92
+ status: 'fail',
93
+ message: responseData?.status
94
+ }
95
+ }
96
+ } catch (error) {
97
+ // console.error('Error details:', error);
98
+
99
+ if (error.response) {
100
+ // console.error('API Response Error:', {
101
+ // status: error.response.status,
102
+ // data: error.response.data,
103
+ // headers: error.response.headers
104
+ // });
105
+ throw new Error(`BufPay API error: ${JSON.stringify(error.response.data)}`);
106
+ } else if (error.request) {
107
+ // console.error('No Response Error:', error.request);
108
+ throw new Error('No response received from BufPay API');
109
+ } else {
110
+ // console.error('Request Setup Error:', error.message);
111
+ throw new Error(`Error in BufPay payment creation: ${error.message}`);
112
+ }
113
+ }
114
+ }
115
+
116
+ generateToken(...params) {
117
+ try {
118
+ const concatenated = params
119
+ .filter(param => param !== undefined && param !== null)
120
+ .map(param => String(param))
121
+ .join('');
122
+
123
+ // console.log('Generating token with params:', concatenated);
124
+
125
+ const token = crypto
126
+ .createHash('md5')
127
+ .update(concatenated, 'utf8')
128
+ .digest('hex')
129
+ .toUpperCase();
130
+
131
+ // console.log('Generated token:', token);
132
+ return token;
133
+ } catch (error) {
134
+ // console.error('Token generation error:', error);
135
+ throw new Error(`Error generating token: ${error.message}`);
136
+ }
137
+ }
138
+
139
+ verifyCallback(callbackData) {
140
+ try {
141
+ console.log('Verifying callback data:', JSON.stringify(callbackData, null, 2));
142
+
143
+ const { aoid, order_id, order_uid, price, pay_price, sign } = callbackData;
144
+
145
+ if (!aoid || !order_id || !order_uid || !price || !pay_price || !sign) {
146
+ console.log('Missing required callback fields');
147
+ return false;
148
+ }
149
+
150
+ const expectedSignature = this.generateToken(
151
+ aoid,
152
+ order_id,
153
+ order_uid,
154
+ price,
155
+ pay_price,
156
+ this.appSecret
157
+ );
158
+
159
+ console.log('Expected signature:', expectedSignature);
160
+ console.log('Received signature:', sign);
161
+
162
+ return sign === expectedSignature;
163
+ } catch (error) {
164
+ console.error('Callback verification error:', error);
165
+ return false;
166
+ }
167
+ }
168
+
169
+ async handleCallback(callbackData) {
170
+ try {
171
+ console.log('Processing callback data:', JSON.stringify(callbackData, null, 2));
172
+
173
+ const isValid = this.verifyCallback(callbackData);
174
+ if (!isValid) {
175
+ throw new Error("BufPay notification failed: invalid signature");
176
+ }
177
+
178
+ if (callbackData.status === 'success') {
179
+ return {
180
+ status: 'success',
181
+ orderId: callbackData.order_id,
182
+ transactionId: callbackData.aoid,
183
+ amount: parseFloat(callbackData.pay_price),
184
+ originalAmount: parseFloat(callbackData.price),
185
+ orderUid: callbackData.order_uid
186
+ };
187
+ } else {
188
+ throw new Error(`Payment failed: ${JSON.stringify(callbackData)}`);
189
+ }
190
+ } catch (error) {
191
+ console.error('Callback handling error:', error);
192
+ throw new Error(`Error in BufPay callback handling: ${error.message}`);
193
+ }
194
+ }
195
+
196
+ async queryPayment(aoid) {
197
+ try {
198
+ console.log('Querying payment with AOID:', aoid);
199
+
200
+ if (!aoid) {
201
+ throw new Error('Transaction ID (AOID) is required');
202
+ }
203
+
204
+ const response = await axios.get(`${this.baseUrl}/query/${aoid}`);
205
+ console.log('Query response:', JSON.stringify(response.data, null, 2));
206
+
207
+ return response.data;
208
+ } catch (error) {
209
+ console.error('Payment query error:', error);
210
+ throw new Error(`Payment query failed: ${error.message}`);
211
+ }
212
+ }
213
+ }
214
+
215
+ module.exports = BufPay;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickpos",
3
- "version": "1.0.901",
3
+ "version": "1.0.902",
4
4
  "main": "app.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"