@unchainedshop/plugins 1.1.7 → 1.1.9
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.
- package/lib/files/gridfs/gridfs-webhook.d.ts +2 -1
- package/lib/files/gridfs/gridfs-webhook.js +1 -1
- package/lib/files/gridfs/gridfs-webhook.js.map +1 -1
- package/lib/files/minio/minio-webhook.d.ts +2 -1
- package/lib/files/minio/minio-webhook.js +30 -28
- package/lib/files/minio/minio-webhook.js.map +1 -1
- package/lib/payment/apple-iap/adapter.d.ts +2 -1
- package/lib/payment/apple-iap/adapter.js +93 -91
- package/lib/payment/apple-iap/adapter.js.map +1 -1
- package/lib/payment/apple-iap/db/AppleTransactionsCollection.d.ts +2 -2
- package/lib/payment/apple-iap/index.d.ts +2 -1
- package/lib/payment/apple-iap/index.js +2 -1
- package/lib/payment/apple-iap/index.js.map +1 -1
- package/lib/payment/bity/adapter.d.ts +2 -1
- package/lib/payment/bity/adapter.js +49 -47
- package/lib/payment/bity/adapter.js.map +1 -1
- package/lib/payment/bity/db/BityCredentialsCollection.d.ts +2 -2
- package/lib/payment/bity/index.d.ts +2 -1
- package/lib/payment/bity/index.js +2 -1
- package/lib/payment/bity/index.js.map +1 -1
- package/lib/payment/cryptopay.d.ts +2 -1
- package/lib/payment/cryptopay.js +59 -57
- package/lib/payment/cryptopay.js.map +1 -1
- package/lib/payment/datatrans-v2/index.d.ts +2 -1
- package/lib/payment/datatrans-v2/index.js +2 -1
- package/lib/payment/datatrans-v2/index.js.map +1 -1
- package/lib/payment/datatrans-v2/middleware.d.ts +2 -1
- package/lib/payment/datatrans-v2/middleware.js +99 -97
- package/lib/payment/datatrans-v2/middleware.js.map +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts +0 -2
- package/lib/payment/paypal-checkout.js +1 -1
- package/lib/payment/paypal-checkout.js.map +1 -1
- package/lib/payment/postfinance-checkout/index.d.ts +2 -1
- package/lib/payment/postfinance-checkout/index.js +2 -1
- package/lib/payment/postfinance-checkout/index.js.map +1 -1
- package/lib/payment/postfinance-checkout/middleware.d.ts +2 -1
- package/lib/payment/postfinance-checkout/middleware.js +35 -33
- package/lib/payment/postfinance-checkout/middleware.js.map +1 -1
- package/lib/payment/postfinance-checkout/utils.d.ts +0 -1
- package/lib/payment/stripe.d.ts +2 -1
- package/lib/payment/stripe.js +62 -59
- package/lib/payment/stripe.js.map +1 -1
- package/lib/pricing/product-price-cryptopay.d.ts +2 -1
- package/lib/pricing/product-price-cryptopay.js +19 -17
- package/lib/pricing/product-price-cryptopay.js.map +1 -1
- package/package.json +18 -18
- package/src/files/gridfs/gridfs-webhook.js +40 -39
- package/src/files/minio/minio-webhook.js +33 -30
- package/src/payment/apple-iap/adapter.ts +112 -109
- package/src/payment/apple-iap/index.ts +2 -1
- package/src/payment/bity/adapter.ts +50 -48
- package/src/payment/bity/index.ts +2 -1
- package/src/payment/cryptopay.ts +68 -66
- package/src/payment/datatrans-v2/index.ts +3 -1
- package/src/payment/datatrans-v2/middleware.ts +129 -123
- package/src/payment/paypal-checkout.ts +1 -1
- package/src/payment/postfinance-checkout/index.ts +3 -1
- package/src/payment/postfinance-checkout/middleware.ts +41 -39
- package/src/payment/stripe.ts +81 -73
- package/src/pricing/product-price-cryptopay.ts +19 -17
- package/tsconfig.build.json +13 -5
|
@@ -88,44 +88,89 @@ const fixPeriods = async (
|
|
|
88
88
|
);
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (req.method === 'POST') {
|
|
100
|
-
try {
|
|
101
|
-
const resolvedContext = req.unchainedContext as Context;
|
|
102
|
-
const { modules, services } = resolvedContext;
|
|
103
|
-
const responseBody = req.body || {};
|
|
104
|
-
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
105
|
-
throw new Error('shared secret not valid');
|
|
106
|
-
}
|
|
91
|
+
export default (app) => {
|
|
92
|
+
useMiddlewareWithCurrentContext(
|
|
93
|
+
app,
|
|
94
|
+
APPLE_IAP_WEBHOOK_PATH,
|
|
95
|
+
bodyParser.json({
|
|
96
|
+
strict: false,
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
107
99
|
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
useMiddlewareWithCurrentContext(app, APPLE_IAP_WEBHOOK_PATH, async (req, res) => {
|
|
101
|
+
if (req.method === 'POST') {
|
|
102
|
+
try {
|
|
103
|
+
const resolvedContext = req.unchainedContext as Context;
|
|
104
|
+
const { modules, services } = resolvedContext;
|
|
105
|
+
const responseBody = req.body || {};
|
|
106
|
+
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
107
|
+
throw new Error('shared secret not valid');
|
|
108
|
+
}
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const orderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
114
|
-
context: {
|
|
115
|
-
'meta.transactionIdentifier': latestTransaction.transaction_id,
|
|
116
|
-
},
|
|
117
|
-
});
|
|
110
|
+
const transactions = responseBody?.unified_receipt?.latest_receipt_info; // eslint-disable-line
|
|
111
|
+
const latestTransaction = transactions[0];
|
|
118
112
|
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
114
|
+
// Find the cart to checkout
|
|
115
|
+
const orderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
116
|
+
context: {
|
|
117
|
+
'meta.transactionIdentifier': latestTransaction.transaction_id,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (!orderPayment) throw new Error('Could not find any matching order payment');
|
|
122
|
+
const order = await modules.orders.findOrder({
|
|
123
|
+
orderId: orderPayment.orderId,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (modules.orders.isCart(order)) {
|
|
127
|
+
// checkout if is cart, else just ignore because the cart is already checked out
|
|
128
|
+
// through submission of the receipt with GraphQL
|
|
129
|
+
const checkedOut = await modules.orders.checkout(
|
|
130
|
+
order._id,
|
|
131
|
+
{
|
|
132
|
+
transactionContext: {
|
|
133
|
+
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
resolvedContext,
|
|
137
|
+
);
|
|
138
|
+
const orderId = checkedOut._id;
|
|
139
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
140
|
+
orderId,
|
|
141
|
+
});
|
|
142
|
+
await fixPeriods(
|
|
143
|
+
{
|
|
144
|
+
transactionId: latestTransaction.original_transaction_id,
|
|
145
|
+
transactions,
|
|
146
|
+
enrollmentId: enrollment._id,
|
|
147
|
+
orderId,
|
|
148
|
+
},
|
|
149
|
+
resolvedContext,
|
|
150
|
+
);
|
|
123
151
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
152
|
+
logger.info(`Apple IAP Webhook: Confirmed checkout for order ${checkedOut.orderNumber}`, {
|
|
153
|
+
orderId: checkedOut._id,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
// Just store payment credentials, use the enrollments paymentProvider reference and
|
|
158
|
+
// let the job do the rest
|
|
159
|
+
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
160
|
+
context: {
|
|
161
|
+
'meta.transactionIdentifier': latestTransaction.original_transaction_id,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
if (!originalOrderPayment) throw new Error('Could not find any matching order payment');
|
|
165
|
+
const originalOrder = await modules.orders.findOrder({
|
|
166
|
+
orderId: originalOrderPayment.orderId,
|
|
167
|
+
});
|
|
168
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
169
|
+
orderId: originalOrder._id,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
await services.payment.registerPaymentCredentials(
|
|
173
|
+
enrollment.payment.paymentProviderId,
|
|
129
174
|
{
|
|
130
175
|
transactionContext: {
|
|
131
176
|
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
@@ -133,97 +178,55 @@ useMiddlewareWithCurrentContext(APPLE_IAP_WEBHOOK_PATH, async (req, res) => {
|
|
|
133
178
|
},
|
|
134
179
|
resolvedContext,
|
|
135
180
|
);
|
|
136
|
-
|
|
137
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
138
|
-
orderId,
|
|
139
|
-
});
|
|
181
|
+
|
|
140
182
|
await fixPeriods(
|
|
141
183
|
{
|
|
142
184
|
transactionId: latestTransaction.original_transaction_id,
|
|
143
185
|
transactions,
|
|
144
186
|
enrollmentId: enrollment._id,
|
|
145
|
-
orderId,
|
|
187
|
+
orderId: originalOrder._id,
|
|
146
188
|
},
|
|
147
189
|
resolvedContext,
|
|
148
190
|
);
|
|
149
191
|
|
|
150
|
-
logger.info(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
// Just store payment credentials, use the enrollments paymentProvider reference and
|
|
156
|
-
// let the job do the rest
|
|
157
|
-
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
158
|
-
context: {
|
|
159
|
-
'meta.transactionIdentifier': latestTransaction.original_transaction_id,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
if (!originalOrderPayment) throw new Error('Could not find any matching order payment');
|
|
163
|
-
const originalOrder = await modules.orders.findOrder({
|
|
164
|
-
orderId: originalOrderPayment.orderId,
|
|
165
|
-
});
|
|
166
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
167
|
-
orderId: originalOrder._id,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
await services.payment.registerPaymentCredentials(
|
|
171
|
-
enrollment.payment.paymentProviderId,
|
|
172
|
-
{
|
|
173
|
-
transactionContext: {
|
|
174
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
resolvedContext,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
await fixPeriods(
|
|
181
|
-
{
|
|
182
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
183
|
-
transactions,
|
|
184
|
-
enrollmentId: enrollment._id,
|
|
185
|
-
orderId: originalOrder._id,
|
|
186
|
-
},
|
|
187
|
-
resolvedContext,
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
logger.info(
|
|
191
|
-
`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
192
|
-
);
|
|
192
|
+
logger.info(
|
|
193
|
+
`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
194
|
+
);
|
|
193
195
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
197
|
+
if (
|
|
198
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
199
|
+
responseBody.auto_renew_status === 'false'
|
|
200
|
+
) {
|
|
201
|
+
await modules.enrollments.terminateEnrollment(enrollment, {}, resolvedContext);
|
|
202
|
+
}
|
|
200
203
|
}
|
|
201
|
-
}
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
206
|
+
if (
|
|
207
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
208
|
+
responseBody.auto_renew_status === 'false'
|
|
209
|
+
) {
|
|
210
|
+
await modules.enrollments.terminateEnrollment(enrollment, {}, resolvedContext);
|
|
211
|
+
}
|
|
209
212
|
}
|
|
213
|
+
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
210
214
|
}
|
|
211
|
-
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
212
|
-
}
|
|
213
215
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
res.writeHead(200);
|
|
217
|
+
res.end();
|
|
218
|
+
return;
|
|
219
|
+
} catch (e) {
|
|
220
|
+
logger.warn(`Apple IAP Webhook: ${e.message}`, e);
|
|
221
|
+
res.writeHead(503);
|
|
222
|
+
res.end(JSON.stringify(e));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
222
225
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
226
|
+
res.writeHead(404);
|
|
227
|
+
res.end();
|
|
228
|
+
});
|
|
229
|
+
};
|
|
227
230
|
|
|
228
231
|
const AppleIAP: IPaymentAdapter = {
|
|
229
232
|
...PaymentAdapter,
|
|
@@ -185,56 +185,58 @@ const estimateBityOrder = async (data: any, context: Context) => {
|
|
|
185
185
|
return response.json();
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
188
|
+
export default (app) => {
|
|
189
|
+
useMiddlewareWithCurrentContext(app, BITY_OAUTH_INIT_PATH, async (req, res) => {
|
|
190
|
+
if (req.method === 'GET') {
|
|
191
|
+
try {
|
|
192
|
+
const resolvedContext = req.unchainedContext;
|
|
193
|
+
await checkAction(resolvedContext, actions.managePaymentProviders);
|
|
194
|
+
|
|
195
|
+
const bityAuthClient = createBityAuth();
|
|
196
|
+
const uri = bityAuthClient.code.getUri();
|
|
197
|
+
logger.info(`Bity Webhook: Login ${uri}`);
|
|
198
|
+
res.writeHead(302, {
|
|
199
|
+
Location: uri,
|
|
200
|
+
});
|
|
201
|
+
res.end();
|
|
202
|
+
return;
|
|
203
|
+
} catch (e) {
|
|
204
|
+
logger.warn(`Bity Webhook: Failed with ${e.message}`);
|
|
205
|
+
res.writeHead(503);
|
|
206
|
+
res.end(JSON.stringify(e));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
207
209
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
210
|
+
res.writeHead(404);
|
|
211
|
+
res.end();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
useMiddlewareWithCurrentContext(app, BITY_OAUTH_PATH, async (req, res, next) => {
|
|
215
|
+
bodyParser.urlencoded({ extended: false })(req, res, next);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
useMiddlewareWithCurrentContext(app, BITY_OAUTH_PATH, async (req, res) => {
|
|
219
|
+
if (req.method === 'GET') {
|
|
220
|
+
try {
|
|
221
|
+
const resolvedContext = req.unchainedContext as Context;
|
|
222
|
+
await checkAction(resolvedContext, actions.managePaymentProviders);
|
|
223
|
+
const bityAuthClient = createBityAuth();
|
|
224
|
+
const user = await bityAuthClient.code.getToken(req.originalUrl);
|
|
225
|
+
await upsertBityCredentials(user, resolvedContext);
|
|
226
|
+
res.writeHead(200);
|
|
227
|
+
res.end('Bity Credentials Setup Complete');
|
|
228
|
+
return;
|
|
229
|
+
} catch (e) {
|
|
230
|
+
logger.warn(`Bity Webhook: Failed with ${e.message}`);
|
|
231
|
+
res.writeHead(503);
|
|
232
|
+
res.end(JSON.stringify(e));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
233
235
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
236
|
+
res.writeHead(404);
|
|
237
|
+
res.end();
|
|
238
|
+
});
|
|
239
|
+
};
|
|
238
240
|
|
|
239
241
|
let bityAuthClient;
|
|
240
242
|
const loadToken = async (context: Context) => {
|
package/src/payment/cryptopay.ts
CHANGED
|
@@ -30,79 +30,81 @@ enum CryptopayCurrencies { // eslint-disable-line
|
|
|
30
30
|
const MAX_RATE_AGE = parseInt(CRYPTOPAY_MAX_RATE_AGE, 10);
|
|
31
31
|
const MAX_ALLOWED_DIFF = parseFloat(CRYPTOPAY_MAX_CONV_DIFF); // Accept payments when the converted amount differs by adapterActions much (in percent)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const orderPayment = await resolvedContext.modules.orders.payments.findOrderPaymentByContextData({
|
|
45
|
-
context: { currency, address },
|
|
46
|
-
});
|
|
47
|
-
if (orderPayment) {
|
|
48
|
-
if (currency === CryptopayCurrencies.ETH && contract && contract !== '') {
|
|
49
|
-
const ERC20CurrencyCount = await resolvedContext.modules.currencies.count({
|
|
50
|
-
includeInactive: false,
|
|
51
|
-
contractAddress: contract,
|
|
52
|
-
});
|
|
53
|
-
if (!ERC20CurrencyCount) {
|
|
54
|
-
logger.warn(`Cryptopay Plugin: ERC20 token address ${contract} not whitelisted.`);
|
|
55
|
-
response.end(JSON.stringify({ success: false }));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
33
|
+
export default (app) => {
|
|
34
|
+
useMiddlewareWithCurrentContext(app, CRYPTOPAY_WEBHOOK_PATH, bodyParser.json());
|
|
35
|
+
|
|
36
|
+
useMiddlewareWithCurrentContext(app, CRYPTOPAY_WEBHOOK_PATH, async (request, response) => {
|
|
37
|
+
// Return a 200 response to acknowledge receipt of the event
|
|
38
|
+
const resolvedContext = request.unchainedContext as Context;
|
|
39
|
+
const { currency, contract, decimals, address, amount, secret } = request.body;
|
|
40
|
+
if (secret !== CRYPTOPAY_SECRET) {
|
|
41
|
+
logger.warn(`Cryptopay Plugin: Invalid Cryptopay Secret provided`);
|
|
42
|
+
response.end(JSON.stringify({ success: false }));
|
|
43
|
+
return;
|
|
58
44
|
}
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
});
|
|
62
|
-
const pricing = OrderPricingSheet({
|
|
63
|
-
calculation: order.calculation,
|
|
64
|
-
currency: order.currency,
|
|
45
|
+
const orderPayment = await resolvedContext.modules.orders.payments.findOrderPaymentByContextData({
|
|
46
|
+
context: { currency, address },
|
|
65
47
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
if (orderPayment) {
|
|
49
|
+
if (currency === CryptopayCurrencies.ETH && contract && contract !== '') {
|
|
50
|
+
const ERC20CurrencyCount = await resolvedContext.modules.currencies.count({
|
|
51
|
+
includeInactive: false,
|
|
52
|
+
contractAddress: contract,
|
|
53
|
+
});
|
|
54
|
+
if (!ERC20CurrencyCount) {
|
|
55
|
+
logger.warn(`Cryptopay Plugin: ERC20 token address ${contract} not whitelisted.`);
|
|
56
|
+
response.end(JSON.stringify({ success: false }));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const order = await resolvedContext.modules.orders.findOrder({
|
|
61
|
+
orderId: orderPayment.orderId,
|
|
62
|
+
});
|
|
63
|
+
const pricing = OrderPricingSheet({
|
|
64
|
+
calculation: order.calculation,
|
|
65
|
+
currency: order.currency,
|
|
66
|
+
});
|
|
67
|
+
const totalAmount = pricing?.total({ useNetPrice: false }).amount;
|
|
68
|
+
let convertedAmount: number;
|
|
69
|
+
if (order.currency === currency) {
|
|
70
|
+
convertedAmount = amount / 10 ** (decimals - 8); // All crypto native prices denoted with 8 decimals
|
|
71
|
+
} else {
|
|
72
|
+
// Need to convert
|
|
73
|
+
const rate = await resolvedContext.modules.products.prices.rates.getRate(
|
|
74
|
+
order.currency,
|
|
75
|
+
contract && contract !== '' ? contract : currency, // Convert to the smart contract if given
|
|
76
|
+
MAX_RATE_AGE,
|
|
77
|
+
);
|
|
78
|
+
if (rate) {
|
|
79
|
+
// We assume that we are converting to a fiat currency here (with 2 decimals).
|
|
80
|
+
// Paying an order with prices in crypto in another crypto is not supported.
|
|
81
|
+
convertedAmount = Math.round((amount / 10 ** decimals) * rate * 100);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (convertedAmount && convertedAmount >= totalAmount * (1 - MAX_ALLOWED_DIFF)) {
|
|
85
|
+
await resolvedContext.modules.orders.checkout(
|
|
86
|
+
order._id,
|
|
87
|
+
{
|
|
88
|
+
transactionContext: { address },
|
|
89
|
+
paymentContext: { address },
|
|
90
|
+
},
|
|
91
|
+
resolvedContext,
|
|
92
|
+
);
|
|
93
|
+
response.end(JSON.stringify({ success: true }));
|
|
94
|
+
} else {
|
|
95
|
+
logger.warn(
|
|
96
|
+
`Cryptopay Plugin: OrderPayment ${orderPayment._id} not marked as paid. Converted amount is ${convertedAmount}`,
|
|
97
|
+
);
|
|
98
|
+
response.end(JSON.stringify({ success: false }));
|
|
81
99
|
}
|
|
82
|
-
}
|
|
83
|
-
if (convertedAmount && convertedAmount >= totalAmount * (1 - MAX_ALLOWED_DIFF)) {
|
|
84
|
-
await resolvedContext.modules.orders.checkout(
|
|
85
|
-
order._id,
|
|
86
|
-
{
|
|
87
|
-
transactionContext: { address },
|
|
88
|
-
paymentContext: { address },
|
|
89
|
-
},
|
|
90
|
-
resolvedContext,
|
|
91
|
-
);
|
|
92
|
-
response.end(JSON.stringify({ success: true }));
|
|
93
100
|
} else {
|
|
94
|
-
logger.
|
|
95
|
-
`Cryptopay Plugin:
|
|
101
|
+
logger.info(
|
|
102
|
+
`Cryptopay Plugin: No orderPayment with address ${address} and currency ${currency} found`,
|
|
96
103
|
);
|
|
97
104
|
response.end(JSON.stringify({ success: false }));
|
|
98
105
|
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
`Cryptopay Plugin: No orderPayment with address ${address} and currency ${currency} found`,
|
|
102
|
-
);
|
|
103
|
-
response.end(JSON.stringify({ success: false }));
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
+
});
|
|
107
|
+
};
|
|
106
108
|
|
|
107
109
|
const Cryptopay: IPaymentAdapter = {
|
|
108
110
|
...PaymentAdapter,
|
|
@@ -10,12 +10,14 @@ import type {
|
|
|
10
10
|
StatusResponseSuccess,
|
|
11
11
|
ValidateResponseSuccess,
|
|
12
12
|
} from './api/types';
|
|
13
|
-
import './middleware';
|
|
13
|
+
import setupDatatrans from './middleware';
|
|
14
14
|
import parseRegistrationData from './parseRegistrationData';
|
|
15
15
|
import roundedAmountFromOrder from './roundedAmountFromOrder';
|
|
16
16
|
|
|
17
17
|
const logger = createLogger('unchained:core-payment:datatrans');
|
|
18
18
|
|
|
19
|
+
export default setupDatatrans;
|
|
20
|
+
|
|
19
21
|
// v2
|
|
20
22
|
const { DATATRANS_SECRET, DATATRANS_SIGN_KEY, DATATRANS_API_ENDPOINT, DATATRANS_MERCHANT_ID } =
|
|
21
23
|
process.env;
|