quickpos 1.0.3 → 1.0.5

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,112 @@
1
+ const PaparaClient = require('./lib/papara');
2
+ const express = require('express');
3
+ const bodyParser = require('body-parser');
4
+ const app = express();
5
+ app.use(bodyParser.json());
6
+
7
+ const papara = new PaparaClient({
8
+ apiKey: 'xxxx',
9
+ merchantSecretKey: 'xxxx'
10
+ }, true);
11
+
12
+ app.post('/callback', async (req, res) => {
13
+ try {
14
+ const result = await papara.handleCallback(req.body);
15
+ console.log(result);
16
+ /*
17
+ {
18
+ status: 'success',
19
+ orderId: '1234',
20
+ uuid: '39061b51-7688-4287-9f90-5b1aa4a25178',
21
+ amount: 1,
22
+ currency: 0,
23
+ paymentMethod: 0
24
+ }
25
+ */
26
+ res.send('OK');
27
+ } catch (error) {
28
+ res.status(400).send(error.message);
29
+ }
30
+ });
31
+
32
+ app.listen(80, () => console.log('Server started'));
33
+
34
+ // Ödeme oluşturma örneği
35
+ (async () => {
36
+ const payment = await papara.createPayment({
37
+ amount: 1,
38
+ nameSurname: 'Test Customer',
39
+ referenceId: '1234',
40
+ currency: 'USD', // TRY, USD, EUR
41
+ orderDescription: 'Test Payment',
42
+ notificationUrl: 'https://test.dalamangoldtaxi.net/callback',
43
+ redirectUrl: 'https://your-domain.com'
44
+ });
45
+ /*
46
+
47
+
48
+ {
49
+ data: {
50
+ merchant: {
51
+ id: '2f73fd0a-d480-4f6f-a2a3-4c663ffbc26d',
52
+ balances: [Array],
53
+ legalName: 'TEST2',
54
+ iconUrl: null,
55
+ brandName: 'TEST2',
56
+ allowedPaymentTypes: [Array],
57
+ allowingGuestCheckout: true,
58
+ allowingPaparaCheckout: false,
59
+ isCorporateCardsListOnPaparaAppEnabled: true,
60
+ atmDepositEnabled: false
61
+ },
62
+ userName: null,
63
+ relatedTransactions: [],
64
+ totalRefundedAmount: 0,
65
+ id: 'f825a55e-598c-411b-af80-a729fd3c13d1',
66
+ createdAt: '2025-01-03T21:59:38.1511487',
67
+ merchantId: '2f73fd0a-d480-4f6f-a2a3-4c663ffbc26d',
68
+ userId: null,
69
+ paymentMethod: 0,
70
+ paymentMethodDescription: null,
71
+ referenceId: '1234',
72
+ orderDescription: 'Test Payment',
73
+ status: 0,
74
+ statusDescription: null,
75
+ amount: 1,
76
+ fee: 0,
77
+ currency: 0,
78
+ currencyInfo: {
79
+ currencyEnum: 0,
80
+ symbol: '₺',
81
+ code: 'TRY',
82
+ number: 949,
83
+ preferredDisplayCode: 'TL',
84
+ name: 'Türk Lirası',
85
+ isCryptocurrency: false,
86
+ isInternationalMoneyTransferCurrency: false,
87
+ precision: 2,
88
+ iconUrl: 'https://dkto9gpxgolik.cloudfront.net/icons/currencies/try.svg',
89
+ flagUrl: 'https://dkto9gpxgolik.cloudfront.net/icons/currencies/try_flag.png',
90
+ currencyEnumIso: 949,
91
+ isMetalCurrency: false
92
+ },
93
+ notificationUrl: 'https://your-domain.com/callback',
94
+ failNotificationUrl: null,
95
+ notificationDone: false,
96
+ paymentUrl: 'https://test.papara.com/checkout/f825a55e-598c-411b-af80-a729fd3c13d1',
97
+ merchantSecretKey: null,
98
+ remainingRefundAmount: null,
99
+ returningRedirectUrl: 'https://your-domain.com?paymentId=f825a55e-598c-411b-af80-a729fd3c13d1&referenceId=1234&status=0&amount=1&paymentId=f825a55e-598c-411b-af80-a729fd3c13d1&referenceId=1234&status=0&amount=1',
100
+ errorCode: null,
101
+ errorMessage: null,
102
+ turkishNationalId: 0,
103
+ secureType: 1,
104
+ basketUrl: null
105
+ },
106
+ succeeded: true
107
+ }
108
+ */
109
+
110
+ // console.log(payment);
111
+ console.log(payment.data.paymentUrl);
112
+ })();
@@ -0,0 +1,74 @@
1
+ const express = require('express');
2
+ const bodyParser = require('body-parser');
3
+ const QuickPos = require('quickpos');
4
+
5
+ const app = express();
6
+ app.use(bodyParser.json({ limit: '50mb', extended: true }));
7
+ app.use(bodyParser.urlencoded({ extended: true }));
8
+ app.use(require('multer')().none());
9
+
10
+ const quickPos = new QuickPos({
11
+ providers: {
12
+ payeer: {
13
+ m_shop: 'XXXX',
14
+ m_key: 'XXXXXX'
15
+ }
16
+ }
17
+ });
18
+
19
+ app.use(quickPos.middleware());
20
+
21
+ app.use(async (req, res, next) => {
22
+ console.log('Middleware çalıştı');
23
+ console.log(req.method, req.url);
24
+ next();
25
+ });
26
+
27
+ (async () => {
28
+ const payment = await quickPos.providers['payeer'].createPayment({
29
+ orderId: 'S12345',
30
+ amount: '0.01',
31
+ currency: 'RUB',
32
+ description: 'Test payment'
33
+ });
34
+ console.log(payment);
35
+ })();
36
+
37
+ app.post('/status', quickPos.handleCallback('payeer'), async (req, res) => {
38
+ /*
39
+ POST /status
40
+ {
41
+ status: 'success',
42
+ orderId: 'S12345',
43
+ amount: '0.01',
44
+ currency: 'RUB',
45
+ operationId: '2175845325',
46
+ paymentDate: '29.12.2024 20:37:43'
47
+ }
48
+ Ödeme başarılı: {
49
+ status: 'success',
50
+ orderId: 'S12345',
51
+ amount: '0.01',
52
+ currency: 'RUB',
53
+ operationId: 'xxxx',
54
+ paymentDate: '29.12.2024 20:37:43'
55
+ }
56
+ */
57
+ console.log(req.paymentResult);
58
+ try {
59
+ if (req.paymentResult.status === 'success') {
60
+ console.log('Ödeme başarılı:', req.paymentResult);
61
+ } else {
62
+ console.error('Ödeme başarısız:', req.paymentResult);
63
+ }
64
+ } catch (error) {
65
+ console.error('Webhook hatası:', error);
66
+ res.status(400).json({error: error.message});
67
+ }
68
+ });
69
+
70
+
71
+ const PORT = 80;
72
+ app.listen(PORT, () => {
73
+ console.log(`Webhook server running on port ${PORT}`);
74
+ });
package/lib/papara.js ADDED
@@ -0,0 +1,144 @@
1
+ const axios = require('axios');
2
+
3
+ class PaparaClient {
4
+ constructor(config, isTest = false) {
5
+ const requiredFields = ['apiKey', 'merchantSecretKey'];
6
+ for (let field of requiredFields) {
7
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
8
+ }
9
+
10
+ this.URL = isTest ? 'https://merchant-api.test.papara.com' : 'https://merchant.papara.com';
11
+ this.merchantSecretKey = config.merchantSecretKey;
12
+ this.client = axios.create({
13
+ baseURL: this.URL,
14
+ headers: {
15
+ 'ApiKey': config.apiKey,
16
+ 'Content-Type': 'application/json'
17
+ }
18
+ });
19
+
20
+ this.client.interceptors.response.use(response => {
21
+ return response;
22
+ }, error => {
23
+ if (error.response) {
24
+ throw new Error(`Papara API error: ${error.response.data.message}`);
25
+ }
26
+ throw new Error(`Papara API error: ${error.message}`);
27
+ });
28
+ }
29
+
30
+ async createPayment(options) {
31
+ try {
32
+ let currencys = {
33
+ 'TRY': 0,
34
+ 'USD': 1,
35
+ 'EUR': 2
36
+ }
37
+
38
+ const response = await this.client.post('/payments', {
39
+ amount: Number(options.amount),
40
+ nameSurname: options.nameSurname,
41
+ referenceId: options.referenceId,
42
+ currency: currencys[options.currency],
43
+ orderDescription: options.orderDescription,
44
+ notificationUrl: options.notificationUrl,
45
+ redirectUrl: options.redirectUrl
46
+ });
47
+ return response.data;
48
+ } catch (error) {
49
+ throw new Error(`Payment creation error: ${error.message}`);
50
+ }
51
+ }
52
+
53
+ async getAccount() {
54
+ try {
55
+ const response = await this.client.get('/account');
56
+ return response.data;
57
+ } catch (error) {
58
+ throw new Error(`Account info error: ${error.message}`);
59
+ }
60
+ }
61
+
62
+ async getAccountLedger(options) {
63
+ try {
64
+ const response = await this.client.post('/account/ledgers', {
65
+ startDate: options.startDate,
66
+ endDate: options.endDate,
67
+ page: options.page || 1,
68
+ pageSize: options.pageSize || 50
69
+ });
70
+ return response.data;
71
+ } catch (error) {
72
+ throw new Error(`Account ledger error: ${error.message}`);
73
+ }
74
+ }
75
+
76
+ async getPaymentStatus(paymentId) {
77
+ try {
78
+ const response = await this.client.get(`/payments?id=${paymentId}`);
79
+ return response.data;
80
+ } catch (error) {
81
+ throw new Error(`Payment status error: ${error.message}`);
82
+ }
83
+ }
84
+
85
+ async handleCallback(callbackData) {
86
+ try {
87
+ const verification = await this.verifyPaymentCallback(callbackData);
88
+
89
+ if (!verification.status) {
90
+ throw new Error(verification.error.message);
91
+ }
92
+
93
+ return {
94
+ status: 'success',
95
+ orderId: verification.data.referenceId,
96
+ uuid: verification.data.id,
97
+ amount: parseFloat(verification.data.amount),
98
+ currency: verification.data.currency,
99
+ paymentMethod: verification.data.paymentMethod
100
+ };
101
+ } catch (error) {
102
+ throw new Error(`Error in Papara callback handling: ${error.message}`);
103
+ }
104
+ }
105
+
106
+ async verifyPaymentCallback(data) {
107
+ try {
108
+ if (data.status !== 1) {
109
+ return {
110
+ status: false,
111
+ error: {
112
+ code: data?.errorCode,
113
+ message: data?.errorMessage || 'Payment failed'
114
+ }
115
+ };
116
+ }
117
+
118
+ if (data.merchantSecretKey !== this.merchantSecretKey) {
119
+ return {
120
+ status: false,
121
+ error: {
122
+ code: 401,
123
+ message: 'Invalid merchant secret key'
124
+ }
125
+ };
126
+ }
127
+
128
+ return {
129
+ status: true,
130
+ data: data
131
+ };
132
+ } catch (error) {
133
+ return {
134
+ status: false,
135
+ error: {
136
+ code: 500,
137
+ message: error.message
138
+ }
139
+ };
140
+ }
141
+ }
142
+ }
143
+
144
+ module.exports = PaparaClient;
package/lib/payeer.js ADDED
@@ -0,0 +1,110 @@
1
+ const crypto = require('crypto');
2
+ const axios = require('axios');
3
+
4
+ class Payeer {
5
+ constructor(config) {
6
+ this.config = config || {};
7
+ const requiredFields = ['m_shop', 'm_key'];
8
+ for (let field of requiredFields) {
9
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
10
+ }
11
+
12
+ this.m_shop = config.m_shop;
13
+ this.m_key = config.m_key;
14
+ }
15
+
16
+ async createPayment(paymentDetails) {
17
+ try {
18
+ const requiredData = ['orderId', 'amount', 'currency', 'description'];
19
+ for (let data of requiredData) {
20
+ if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`);
21
+ }
22
+
23
+ const m_sign = this.generateSignature(
24
+ paymentDetails.orderId,
25
+ paymentDetails.amount,
26
+ paymentDetails.currency,
27
+ Buffer.from(paymentDetails.description).toString('base64')
28
+ );
29
+
30
+ const paymentUrl = `https://payeer.com/merchant/?m_shop=${this.m_shop}&m_orderid=${paymentDetails.orderId}&m_amount=${paymentDetails.amount}&m_curr=${paymentDetails.currency}&m_desc=${Buffer.from(paymentDetails.description).toString('base64')}&m_sign=${m_sign}&lang=${paymentDetails.lang || 'en'}`;
31
+
32
+ return {
33
+ status: 'success',
34
+ data: {
35
+ url: paymentUrl,
36
+ orderId: paymentDetails.orderId,
37
+ amount: paymentDetails.amount,
38
+ currency: paymentDetails.currency
39
+ }
40
+ };
41
+ } catch (error) {
42
+ throw new Error(`Error in Payeer payment creation: ${error.message}`);
43
+ }
44
+ }
45
+
46
+ async handleCallback(callbackData) {
47
+ try {
48
+ const signHash = this.generatePaymentStatusSignature(callbackData);
49
+
50
+ if (callbackData.m_sign === signHash && callbackData.m_status === 'success') {
51
+ return {
52
+ status: 'success',
53
+ orderId: callbackData.m_orderid,
54
+ amount: callbackData.m_amount,
55
+ currency: callbackData.m_curr,
56
+ operationId: callbackData.m_operation_id,
57
+ paymentDate: callbackData.m_operation_pay_date
58
+ };
59
+ } else {
60
+ throw new Error('Payment validation failed');
61
+ }
62
+ } catch (error) {
63
+ throw new Error(`Error in Payeer callback handling: ${error.message}`);
64
+ }
65
+ }
66
+
67
+ generateSignature(m_orderid, m_amount, m_curr, m_desc) {
68
+ const arHash = [
69
+ this.m_shop,
70
+ m_orderid,
71
+ m_amount,
72
+ m_curr,
73
+ m_desc,
74
+ this.m_key
75
+ ];
76
+
77
+ return crypto.createHash('sha256')
78
+ .update(arHash.join(':'))
79
+ .digest('hex')
80
+ .toUpperCase();
81
+ }
82
+
83
+ generatePaymentStatusSignature(paymentData) {
84
+ const arHash = [
85
+ paymentData.m_operation_id,
86
+ paymentData.m_operation_ps,
87
+ paymentData.m_operation_date,
88
+ paymentData.m_operation_pay_date,
89
+ paymentData.m_shop,
90
+ paymentData.m_orderid,
91
+ paymentData.m_amount,
92
+ paymentData.m_curr,
93
+ paymentData.m_desc,
94
+ paymentData.m_status
95
+ ];
96
+
97
+ if (paymentData.m_params) {
98
+ arHash.push(paymentData.m_params);
99
+ }
100
+
101
+ arHash.push(this.m_key);
102
+
103
+ return crypto.createHash('sha256')
104
+ .update(arHash.join(':'))
105
+ .digest('hex')
106
+ .toUpperCase();
107
+ }
108
+ }
109
+
110
+ module.exports = Payeer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickpos",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "main": "app.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -24,7 +24,9 @@
24
24
  "stripe",
25
25
  "paypal",
26
26
  "shopier",
27
- "cryptomus"
27
+ "cryptomus",
28
+ "payeer",
29
+ "papara"
28
30
  ],
29
31
  "repository": {
30
32
  "type": "git",
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 💳 QuickPos 🚀
2
2
 
3
- QuickPos, farklı ödeme sağlayıcılarını destekleyen güçlü bir ödeme entegrasyon modülüdür. Şu anda PayTR, Shopier, Cryptomus sağlayıcısını desteklemektedir ve gelecekte birçok yeni sağlayıcı ile özellik eklemeyi planlamaktadır. Yol haritamıza göz atarak gelecek özellikleri keşfedebilirsiniz.
3
+ QuickPos, farklı ödeme sağlayıcılarını destekleyen güçlü bir ödeme entegrasyon modülüdür. Şu anda PayTR, Shopier, Cryptomus, Payeer, Papara sağlayıcısını desteklemektedir ve gelecekte birçok yeni sağlayıcı ile özellik eklemeyi planlamaktadır. Yol haritamıza göz atarak gelecek özellikleri keşfedebilirsiniz.
4
4
 
5
5
  ---
6
6
 
@@ -135,6 +135,8 @@ const quickPos = new QuickPos({
135
135
  - PayTR
136
136
  - Shopier
137
137
  - Cryptomus
138
+ - Payeer
139
+ - Papara
138
140
 
139
141
  ---
140
142
 
@@ -152,6 +154,8 @@ const quickPos = new QuickPos({
152
154
  - [x] PayTR entegrasyonu
153
155
  - [x] Shopier entegrasyonu
154
156
  - [x] Cryptomus entegrasyonu
157
+ - [x] Payeer entegrasyonu
158
+ - [x] Papara entegrasyonu
155
159
  - [ ] İyzico entegrasyonu
156
160
  - [ ] Vallet entegrasyonu
157
161
  - [ ] Shipy entegrasyonu