quickpos 1.0.0 → 1.0.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.
@@ -0,0 +1,77 @@
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.urlencoded({ extended: true }));
7
+ app.use(require('multer')().none());
8
+
9
+ const quickPos = new QuickPos({
10
+ providers: {
11
+ shopier: {
12
+ pat: 'xxxxx',
13
+ username: 'xxxxx',
14
+ key: 'xxxxx'
15
+ }
16
+ }
17
+ });
18
+
19
+ app.use(quickPos.middleware());
20
+
21
+ quickPos.providers['shopier'].postProducts({
22
+ type: 'digital',
23
+ priceData: {
24
+ currency: 'TRY',
25
+ price: '1'
26
+ },
27
+ shippingPayer: 'sellerPays',
28
+ title: 'Add Balance',
29
+ media: [{
30
+ type: 'image',
31
+ placement: 1,
32
+ url: 'https://cdn.shopier.app/pictures_mid/speedsmm_21561f0e-2331-4611-8e93-2b020b1b7f92.png'
33
+ }],
34
+ stockQuantity: 1,
35
+ description: 'Add balance to your account'
36
+ })
37
+ .then(response => console.log(response))
38
+ .catch(error => console.error(error));
39
+
40
+ app.post('/shopierWebhook', quickPos.handleCallback('shopier'), (req, res) => {
41
+ try {
42
+ console.log('Payment result:', req.paymentResult.data.chartDetails);
43
+ /*
44
+ Payment result: {
45
+ status: 'success',
46
+ data: {
47
+ email: 'fastuptime@gmail.com',
48
+ orderId: '313758163',
49
+ currency: 0,
50
+ price: '1',
51
+ buyerName: 'Can',
52
+ buyerSurname: 'Kaya',
53
+ productId: 31857020,
54
+ productCount: 1,
55
+ customerNote: '',
56
+ productList: '31857020',
57
+ chartDetails: [ [Object] ],
58
+ isTest: 1
59
+ }
60
+ }
61
+ */
62
+ if (!(req.body.res && req.body.hash)) {
63
+ return res.status(400).send('missing parameter');
64
+ }
65
+
66
+ // İşlem başarılı
67
+ res.send('success');
68
+ } catch (error) {
69
+ console.error('Webhook error:', error);
70
+ res.status(500).send('error');
71
+ }
72
+ });
73
+
74
+ const PORT = 80;
75
+ app.listen(PORT, () => {
76
+ console.log(`Webhook server running on port ${PORT}`);
77
+ });
package/lib/paytr.js CHANGED
@@ -100,7 +100,8 @@ class PayTR {
100
100
  if (callbackData.status === 'success') {
101
101
  return {
102
102
  status: 'success',
103
- orderId: callbackData.merchant_oid,
103
+ orderId: callbackData.callback_id,
104
+ merchant_oid: callbackData.merchant_oid,
104
105
  amount: parseFloat(callbackData.total_amount) / 100,
105
106
  currency: callbackData.currency,
106
107
  paymentType: callbackData.payment_type
package/lib/shopier.js ADDED
@@ -0,0 +1,125 @@
1
+ const axios = require('axios');
2
+ const crypto = require('crypto');
3
+
4
+ class Shopier {
5
+ constructor(config) {
6
+ this.config = config || {};
7
+ const requiredFields = ['pat', 'username', 'key'];
8
+ for (let field of requiredFields) {
9
+ if (!config[field]) throw new Error(`Missing required field: ${field}`);
10
+ }
11
+
12
+ this.pat = config.pat;
13
+ this.username = config.username;
14
+ this.key = config.key;
15
+ this.baseURL = 'https://api.shopier.com/v1';
16
+ this.axios = axios.create({
17
+ baseURL: this.baseURL,
18
+ headers: {
19
+ 'Authorization': `Bearer ${this.pat}`,
20
+ 'Content-Type': 'application/json'
21
+ }
22
+ });
23
+ }
24
+
25
+ async createPayment(productDetails) {
26
+ try {
27
+ const response = await this.axios.post('/products', {
28
+ type: productDetails.type || 'digital',
29
+ priceData: {
30
+ currency: productDetails.priceData?.currency || 'TRY',
31
+ price: productDetails.priceData?.price
32
+ },
33
+ shippingPayer: productDetails.shippingPayer || 'sellerPays',
34
+ title: productDetails.title,
35
+ media: productDetails.media || [],
36
+ stockQuantity: productDetails.stockQuantity,
37
+ description: productDetails.description
38
+ });
39
+
40
+ return {
41
+ status: 'success',
42
+ data: response.data
43
+ };
44
+ } catch (error) {
45
+ throw this.handleApiError(error);
46
+ }
47
+ }
48
+
49
+ async deleteProductsId(params) {
50
+ try {
51
+ if (!params.id) throw new Error('Product ID is required');
52
+ const response = await this.axios.delete(`/products/${params.id}`);
53
+ return {
54
+ status: 'success',
55
+ data: response.data
56
+ };
57
+ } catch (error) {
58
+ throw this.handleApiError(error);
59
+ }
60
+ }
61
+
62
+ handleApiError(error) {
63
+ if (error.response) {
64
+ return new Error(`Shopier API error: ${error.response.data?.message || error.response.statusText}`);
65
+ }
66
+ if (error.request) {
67
+ return new Error('No response received from Shopier API');
68
+ }
69
+ return new Error(`Error in Shopier operation: ${error.message}`);
70
+ }
71
+
72
+ verifyWebhookHash(payload) {
73
+ if (!payload.res || !payload.hash) {
74
+ throw new Error('Missing webhook parameters');
75
+ }
76
+
77
+ const calculatedHash = crypto
78
+ .createHmac('sha256', this.key)
79
+ .update(payload.res + this.username)
80
+ .digest('hex');
81
+
82
+ return calculatedHash === payload.hash;
83
+ }
84
+
85
+ parseWebhookData(base64Data) {
86
+ try {
87
+ const jsonStr = Buffer.from(base64Data, 'base64').toString();
88
+ return JSON.parse(jsonStr);
89
+ } catch (error) {
90
+ throw new Error('Failed to parse webhook data');
91
+ }
92
+ }
93
+
94
+ handleCallback(webhookData) {
95
+ try {
96
+ if (!this.verifyWebhookHash(webhookData)) {
97
+ throw new Error('Invalid webhook signature');
98
+ }
99
+
100
+ const data = this.parseWebhookData(webhookData.res);
101
+
102
+ return {
103
+ status: 'success',
104
+ data: {
105
+ email: data.email,
106
+ orderId: data.orderid,
107
+ currency: data.currency, // 0:TL, 1:USD, 2:EUR
108
+ price: data.price,
109
+ buyerName: data.buyername,
110
+ buyerSurname: data.buyersurname,
111
+ productId: data.productid,
112
+ productCount: data.productcount,
113
+ customerNote: data.customernote,
114
+ productList: data.productlist,
115
+ chartDetails: data.chartdetails,
116
+ isTest: data.istest // 0:live, 1:test
117
+ }
118
+ };
119
+ } catch (error) {
120
+ throw new Error(`Webhook handling error: ${error.message}`);
121
+ }
122
+ }
123
+ }
124
+
125
+ module.exports = Shopier;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickpos",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "main": "app.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -22,7 +22,8 @@
22
22
  "weepay",
23
23
  "paynet",
24
24
  "stripe",
25
- "paypal"
25
+ "paypal",
26
+ "shopier"
26
27
  ],
27
28
  "repository": {
28
29
  "type": "git",
package/readme.md CHANGED
@@ -133,6 +133,7 @@ const quickPos = new QuickPos({
133
133
  ## Desteklenen Ödeme Sağlayıcıları 🏦
134
134
 
135
135
  - PayTR
136
+ - Shopier
136
137
 
137
138
  ---
138
139