@unchainedshop/plugins 4.6.2 → 4.7.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.
- package/README.md +0 -2
- package/lib/events/node-event-emitter.d.ts +3 -1
- package/lib/events/node-event-emitter.js +3 -3
- package/lib/files/gridfs/adapter.d.ts +2 -2
- package/lib/files/gridfs/adapter.js +2 -5
- package/lib/files/gridfs/index.d.ts +5 -4
- package/lib/files/gridfs/index.js +30 -3
- package/lib/files/minio/index.d.ts +4 -5
- package/lib/files/minio/index.js +18 -157
- package/lib/payment/apple-iap/adapter.d.ts +2 -1
- package/lib/payment/apple-iap/adapter.js +2 -3
- package/lib/payment/apple-iap/index.d.ts +6 -4
- package/lib/payment/apple-iap/index.js +28 -3
- package/lib/payment/cryptopay/index.d.ts +5 -4
- package/lib/payment/cryptopay/index.js +31 -3
- package/lib/payment/datatrans-v2/index.d.ts +4 -1
- package/lib/payment/datatrans-v2/index.js +17 -400
- package/lib/payment/payrexx/index.d.ts +4 -1
- package/lib/payment/payrexx/index.js +19 -158
- package/lib/payment/postfinance-checkout/index.d.ts +5 -0
- package/lib/payment/postfinance-checkout/index.js +25 -186
- package/lib/payment/saferpay/adapter.js +1 -2
- package/lib/payment/saferpay/index.d.ts +5 -4
- package/lib/payment/saferpay/index.js +29 -3
- package/lib/payment/stripe/index.d.ts +4 -1
- package/lib/payment/stripe/index.js +22 -116
- package/lib/payment/stripe/stripe.js +2 -5
- package/lib/presets/all.d.ts +1 -70
- package/lib/presets/all.js +41 -27
- package/lib/presets/base.d.ts +1 -25
- package/lib/presets/base.js +56 -25
- package/lib/presets/countries/ch.d.ts +1 -2
- package/lib/presets/countries/ch.js +7 -2
- package/lib/presets/crypto.d.ts +3 -7
- package/lib/presets/crypto.js +18 -7
- package/package.json +15 -10
- package/lib/delivery/post.d.ts +0 -1
- package/lib/delivery/post.js +0 -23
- package/lib/delivery/send-message.d.ts +0 -1
- package/lib/delivery/send-message.js +0 -40
- package/lib/delivery/stores.d.ts +0 -1
- package/lib/delivery/stores.js +0 -43
- package/lib/enrollments/licensed.d.ts +0 -4
- package/lib/enrollments/licensed.js +0 -52
- package/lib/files/gridfs/handler-express.d.ts +0 -9
- package/lib/files/gridfs/handler-express.js +0 -110
- package/lib/files/gridfs/handler-fastify.d.ts +0 -3
- package/lib/files/gridfs/handler-fastify.js +0 -138
- package/lib/files/minio/handler-express.d.ts +0 -2
- package/lib/files/minio/handler-express.js +0 -36
- package/lib/files/minio/handler-fastify.d.ts +0 -3
- package/lib/files/minio/handler-fastify.js +0 -40
- package/lib/filters/local-search.d.ts +0 -3
- package/lib/filters/local-search.js +0 -66
- package/lib/filters/strict-equal.d.ts +0 -1
- package/lib/filters/strict-equal.js +0 -24
- package/lib/payment/apple-iap/handler-express.d.ts +0 -2
- package/lib/payment/apple-iap/handler-express.js +0 -103
- package/lib/payment/apple-iap/handler-fastify.d.ts +0 -3
- package/lib/payment/apple-iap/handler-fastify.js +0 -102
- package/lib/payment/braintree.d.ts +0 -1
- package/lib/payment/braintree.js +0 -138
- package/lib/payment/cryptopay/handler-express.d.ts +0 -2
- package/lib/payment/cryptopay/handler-express.js +0 -19
- package/lib/payment/cryptopay/handler-fastify.d.ts +0 -3
- package/lib/payment/cryptopay/handler-fastify.js +0 -17
- package/lib/payment/cryptopay/plugin.d.ts +0 -3
- package/lib/payment/cryptopay/plugin.js +0 -159
- package/lib/payment/datatrans-v2/handler-express.d.ts +0 -1
- package/lib/payment/datatrans-v2/handler-express.js +0 -71
- package/lib/payment/datatrans-v2/handler-fastify.d.ts +0 -2
- package/lib/payment/datatrans-v2/handler-fastify.js +0 -71
- package/lib/payment/invoice-prepaid.d.ts +0 -1
- package/lib/payment/invoice-prepaid.js +0 -30
- package/lib/payment/invoice.d.ts +0 -1
- package/lib/payment/invoice.js +0 -27
- package/lib/payment/paypal-checkout.d.ts +0 -1
- package/lib/payment/paypal-checkout.js +0 -87
- package/lib/payment/payrexx/handler-express.d.ts +0 -1
- package/lib/payment/payrexx/handler-express.js +0 -85
- package/lib/payment/payrexx/handler-fastify.d.ts +0 -2
- package/lib/payment/payrexx/handler-fastify.js +0 -91
- package/lib/payment/postfinance-checkout/handler-express.d.ts +0 -1
- package/lib/payment/postfinance-checkout/handler-express.js +0 -37
- package/lib/payment/postfinance-checkout/handler-fastify.d.ts +0 -2
- package/lib/payment/postfinance-checkout/handler-fastify.js +0 -40
- package/lib/payment/saferpay/handler-express.d.ts +0 -1
- package/lib/payment/saferpay/handler-express.js +0 -59
- package/lib/payment/saferpay/handler-fastify.d.ts +0 -2
- package/lib/payment/saferpay/handler-fastify.js +0 -62
- package/lib/payment/stripe/handler-express.d.ts +0 -5
- package/lib/payment/stripe/handler-express.js +0 -121
- package/lib/payment/stripe/handler-fastify.d.ts +0 -6
- package/lib/payment/stripe/handler-fastify.js +0 -131
- package/lib/presets/all-express.d.ts +0 -6
- package/lib/presets/all-express.js +0 -26
- package/lib/presets/all-fastify.d.ts +0 -6
- package/lib/presets/all-fastify.js +0 -49
- package/lib/presets/base-express.d.ts +0 -2
- package/lib/presets/base-express.js +0 -5
- package/lib/presets/base-fastify.d.ts +0 -3
- package/lib/presets/base-fastify.js +0 -16
- package/lib/presets/crypto-express.d.ts +0 -3
- package/lib/presets/crypto-express.js +0 -8
- package/lib/presets/crypto-fastify.d.ts +0 -3
- package/lib/presets/crypto-fastify.js +0 -11
- package/lib/pricing/delivery-swiss-tax.d.ts +0 -2
- package/lib/pricing/delivery-swiss-tax.js +0 -62
- package/lib/pricing/discount-100-off.d.ts +0 -2
- package/lib/pricing/discount-100-off.js +0 -30
- package/lib/pricing/discount-half-price-manual.d.ts +0 -2
- package/lib/pricing/discount-half-price-manual.js +0 -30
- package/lib/pricing/discount-half-price.d.ts +0 -2
- package/lib/pricing/discount-half-price.js +0 -33
- package/lib/pricing/free-delivery.d.ts +0 -2
- package/lib/pricing/free-delivery.js +0 -27
- package/lib/pricing/free-payment.d.ts +0 -2
- package/lib/pricing/free-payment.js +0 -27
- package/lib/pricing/order-delivery.d.ts +0 -2
- package/lib/pricing/order-delivery.js +0 -33
- package/lib/pricing/order-discount.d.ts +0 -2
- package/lib/pricing/order-discount.js +0 -74
- package/lib/pricing/order-items-discount.d.ts +0 -2
- package/lib/pricing/order-items-discount.js +0 -50
- package/lib/pricing/order-items.d.ts +0 -2
- package/lib/pricing/order-items.js +0 -43
- package/lib/pricing/order-payment.d.ts +0 -2
- package/lib/pricing/order-payment.js +0 -33
- package/lib/pricing/order-round.d.ts +0 -10
- package/lib/pricing/order-round.js +0 -135
- package/lib/pricing/product-catalog-price-options.d.ts +0 -2
- package/lib/pricing/product-catalog-price-options.js +0 -51
- package/lib/pricing/product-catalog-price.d.ts +0 -2
- package/lib/pricing/product-catalog-price.js +0 -60
- package/lib/pricing/product-discount.d.ts +0 -2
- package/lib/pricing/product-discount.js +0 -69
- package/lib/pricing/product-price-rateconversion.d.ts +0 -2
- package/lib/pricing/product-price-rateconversion.js +0 -53
- package/lib/pricing/product-round.d.ts +0 -10
- package/lib/pricing/product-round.js +0 -44
- package/lib/pricing/product-swiss-tax.d.ts +0 -2
- package/lib/pricing/product-swiss-tax.js +0 -76
- package/lib/quotations/manual.d.ts +0 -1
- package/lib/quotations/manual.js +0 -20
- package/lib/warehousing/eth-minter.d.ts +0 -1
- package/lib/warehousing/eth-minter.js +0 -120
- package/lib/warehousing/store.d.ts +0 -1
- package/lib/warehousing/store.js +0 -34
- package/lib/worker/budgetsms.d.ts +0 -9
- package/lib/worker/budgetsms.js +0 -169
- package/lib/worker/bulk-export.d.ts +0 -2
- package/lib/worker/bulk-export.js +0 -64
- package/lib/worker/bulk-import.d.ts +0 -2
- package/lib/worker/bulk-import.js +0 -65
- package/lib/worker/bulkgate.d.ts +0 -1
- package/lib/worker/bulkgate.js +0 -91
- package/lib/worker/email.d.ts +0 -1
- package/lib/worker/email.js +0 -136
- package/lib/worker/enrollment-order-generator.d.ts +0 -1
- package/lib/worker/enrollment-order-generator.js +0 -77
- package/lib/worker/error-notifications.d.ts +0 -9
- package/lib/worker/error-notifications.js +0 -61
- package/lib/worker/export-token.d.ts +0 -4
- package/lib/worker/export-token.js +0 -26
- package/lib/worker/external.d.ts +0 -2
- package/lib/worker/external.js +0 -13
- package/lib/worker/heartbeat.d.ts +0 -1
- package/lib/worker/heartbeat.js +0 -26
- package/lib/worker/http-request.d.ts +0 -8
- package/lib/worker/http-request.js +0 -56
- package/lib/worker/message.d.ts +0 -10
- package/lib/worker/message.js +0 -42
- package/lib/worker/push-notification.d.ts +0 -1
- package/lib/worker/push-notification.js +0 -87
- package/lib/worker/twilio.d.ts +0 -1
- package/lib/worker/twilio.js +0 -59
- package/lib/worker/update-coinbase-rates.d.ts +0 -1
- package/lib/worker/update-coinbase-rates.js +0 -59
- package/lib/worker/update-ecb-rates.d.ts +0 -1
- package/lib/worker/update-ecb-rates.js +0 -92
- package/lib/worker/update-token-ownership.d.ts +0 -3
- package/lib/worker/update-token-ownership.js +0 -57
- package/lib/worker/zombie-killer.d.ts +0 -13
- package/lib/worker/zombie-killer.js +0 -91
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
-
import { timingSafeStringEqual } from '@unchainedshop/utils';
|
|
3
|
-
const logger = createLogger('unchained:minio');
|
|
4
|
-
const { MINIO_WEBHOOK_AUTH_TOKEN } = process.env;
|
|
5
|
-
const isAuthorized = async ({ authorization = '' }) => {
|
|
6
|
-
if (!MINIO_WEBHOOK_AUTH_TOKEN)
|
|
7
|
-
return false;
|
|
8
|
-
const [type, token] = authorization.split(' ');
|
|
9
|
-
if (type !== 'Bearer' || !token)
|
|
10
|
-
return false;
|
|
11
|
-
return timingSafeStringEqual(token, MINIO_WEBHOOK_AUTH_TOKEN);
|
|
12
|
-
};
|
|
13
|
-
const minioHandler = async (req, res) => {
|
|
14
|
-
try {
|
|
15
|
-
if (req.method === 'POST' && req.body) {
|
|
16
|
-
const { headers } = req;
|
|
17
|
-
const { Records = [], EventName } = req.body;
|
|
18
|
-
if (EventName === 's3:ObjectCreated:Put' && (await isAuthorized(headers))) {
|
|
19
|
-
const [{ s3 }] = Records;
|
|
20
|
-
const { object } = s3;
|
|
21
|
-
const { size, contentType: type } = object;
|
|
22
|
-
const [fileId] = object.key.split('.');
|
|
23
|
-
const { services } = req.unchainedContext;
|
|
24
|
-
await services.files.linkFile({ fileId, type, size });
|
|
25
|
-
res.status(200).end();
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
res.status(404).end();
|
|
30
|
-
}
|
|
31
|
-
catch (e) {
|
|
32
|
-
logger.error(e);
|
|
33
|
-
res.status(503).send({ name: e.name, code: e.code, message: e.message });
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
export default minioHandler;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import {} from '@unchainedshop/api';
|
|
2
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
3
|
-
import {} from 'fastify';
|
|
4
|
-
import { timingSafeStringEqual } from '@unchainedshop/utils';
|
|
5
|
-
const logger = createLogger('unchained:minio');
|
|
6
|
-
const { MINIO_WEBHOOK_AUTH_TOKEN } = process.env;
|
|
7
|
-
const isAuthorized = async ({ authorization = '' }) => {
|
|
8
|
-
if (!MINIO_WEBHOOK_AUTH_TOKEN)
|
|
9
|
-
return false;
|
|
10
|
-
const [type, token] = authorization.split(' ');
|
|
11
|
-
if (type !== 'Bearer' || !token)
|
|
12
|
-
return false;
|
|
13
|
-
return timingSafeStringEqual(token, MINIO_WEBHOOK_AUTH_TOKEN);
|
|
14
|
-
};
|
|
15
|
-
const minioHandler = async (req, res) => {
|
|
16
|
-
try {
|
|
17
|
-
if (req.body) {
|
|
18
|
-
const { headers } = req;
|
|
19
|
-
const { Records = [], EventName } = req.body;
|
|
20
|
-
if (EventName === 's3:ObjectCreated:Put' && (await isAuthorized(headers))) {
|
|
21
|
-
const [{ s3 }] = Records;
|
|
22
|
-
const { object } = s3;
|
|
23
|
-
const { size, contentType: type } = object;
|
|
24
|
-
const [fileId] = object.key.split('.');
|
|
25
|
-
const { services } = req.unchainedContext;
|
|
26
|
-
await services.files.linkFile({ fileId, type, size });
|
|
27
|
-
res.status(200);
|
|
28
|
-
return res.send();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
res.status(404);
|
|
32
|
-
return res.send();
|
|
33
|
-
}
|
|
34
|
-
catch (e) {
|
|
35
|
-
logger.error(e);
|
|
36
|
-
res.status(503);
|
|
37
|
-
return res.send({ name: e.name, code: e.code, message: e.message });
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
export default minioHandler;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { FilterDirector, FilterAdapter } from '@unchainedshop/core';
|
|
2
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
3
|
-
import { isDocumentDBCompatModeEnabled } from '@unchainedshop/mongodb';
|
|
4
|
-
const logger = createLogger('unchained:local-search');
|
|
5
|
-
const LocalSearch = {
|
|
6
|
-
...FilterAdapter,
|
|
7
|
-
key: 'shop.unchained.filters.local-search',
|
|
8
|
-
label: 'Simple Fulltext search with MongoDB',
|
|
9
|
-
version: '1.0.0',
|
|
10
|
-
orderIndex: 10,
|
|
11
|
-
actions: (params) => {
|
|
12
|
-
return {
|
|
13
|
-
...FilterAdapter.actions(params),
|
|
14
|
-
searchProducts: async ({ productIds }) => {
|
|
15
|
-
const { queryString } = params.searchQuery;
|
|
16
|
-
if (!queryString)
|
|
17
|
-
return productIds;
|
|
18
|
-
const products = await params.modules.products.texts.findTexts({
|
|
19
|
-
queryString,
|
|
20
|
-
productIds: productIds ? [...new Set(productIds)] : undefined,
|
|
21
|
-
}, {
|
|
22
|
-
projection: {
|
|
23
|
-
productId: 1,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
return products.map(({ productId }) => productId);
|
|
27
|
-
},
|
|
28
|
-
searchAssortments: async ({ assortmentIds }) => {
|
|
29
|
-
const { queryString } = params.searchQuery;
|
|
30
|
-
if (!queryString) {
|
|
31
|
-
return assortmentIds;
|
|
32
|
-
}
|
|
33
|
-
const assortments = await params.modules.assortments.texts.findTexts({
|
|
34
|
-
queryString,
|
|
35
|
-
assortmentIds,
|
|
36
|
-
}, {
|
|
37
|
-
projection: {
|
|
38
|
-
assortmentId: 1,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
return assortments.map(({ assortmentId }) => assortmentId);
|
|
42
|
-
},
|
|
43
|
-
async transformFilterSelector(last) {
|
|
44
|
-
const { queryString, filterIds, includeInactive } = params.searchQuery;
|
|
45
|
-
if (queryString && !filterIds) {
|
|
46
|
-
const selector = { ...last };
|
|
47
|
-
if (selector?.key) {
|
|
48
|
-
delete selector.key;
|
|
49
|
-
}
|
|
50
|
-
if (!includeInactive) {
|
|
51
|
-
selector.isActive = true;
|
|
52
|
-
}
|
|
53
|
-
return selector;
|
|
54
|
-
}
|
|
55
|
-
return last;
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
export default LocalSearch;
|
|
61
|
-
if (!isDocumentDBCompatModeEnabled()) {
|
|
62
|
-
FilterDirector.registerAdapter(LocalSearch);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
logger.warn('Free text search queries have been disabled due to DocumentDB compatibility mode (env UNCHAINED_DOCUMENTDB_COMPAT_MODE is trueish)');
|
|
66
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { FilterDirector, FilterAdapter } from '@unchainedshop/core';
|
|
2
|
-
const StrictQualFilter = {
|
|
3
|
-
...FilterAdapter,
|
|
4
|
-
key: 'shop.unchained.filters.strict-qual',
|
|
5
|
-
label: 'Simple Strict Equal DB Filter',
|
|
6
|
-
version: '1.0.0',
|
|
7
|
-
orderIndex: 0,
|
|
8
|
-
actions: (params) => {
|
|
9
|
-
return {
|
|
10
|
-
...FilterAdapter.actions(params),
|
|
11
|
-
transformProductSelector: async (lastSelector, options) => {
|
|
12
|
-
const { key, value } = options || {};
|
|
13
|
-
if (key) {
|
|
14
|
-
return {
|
|
15
|
-
...lastSelector,
|
|
16
|
-
[key]: value !== undefined ? value : { $exists: true },
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
return lastSelector;
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
FilterDirector.registerAdapter(StrictQualFilter);
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {} from '@unchainedshop/api';
|
|
2
|
-
import { EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
3
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
4
|
-
import { fixPeriods } from "./fix-periods.js";
|
|
5
|
-
const logger = createLogger('unchained:apple-iap:handler');
|
|
6
|
-
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
7
|
-
const AppleNotificationTypes = {
|
|
8
|
-
INITIAL_BUY: 'INITIAL_BUY',
|
|
9
|
-
DID_RECOVER: 'DID_RECOVER',
|
|
10
|
-
DID_CHANGE_RENEWAL_STATUS: 'DID_CHANGE_RENEWAL_STATUS',
|
|
11
|
-
DID_FAIL_TO_RENEW: 'DID_FAIL_TO_RENEW',
|
|
12
|
-
DID_CHANGE_RENEWAL_PREF: 'DID_CHANGE_RENEWAL_PREF',
|
|
13
|
-
};
|
|
14
|
-
export const appleIAPHandler = async (req, res) => {
|
|
15
|
-
if (req.method === 'POST') {
|
|
16
|
-
try {
|
|
17
|
-
const resolvedContext = req.unchainedContext;
|
|
18
|
-
const { modules, services } = resolvedContext;
|
|
19
|
-
const responseBody = req.body || {};
|
|
20
|
-
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
21
|
-
throw new Error('shared secret not valid');
|
|
22
|
-
}
|
|
23
|
-
const transactions = responseBody?.unified_receipt?.latest_receipt_info;
|
|
24
|
-
const latestTransaction = transactions[0];
|
|
25
|
-
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
26
|
-
const orderPayment = await modules.orders.payments.findOrderPaymentByTransactionId(latestTransaction.transaction_id);
|
|
27
|
-
if (!orderPayment)
|
|
28
|
-
throw new Error('Could not find any matching order payment');
|
|
29
|
-
const order = await services.orders.checkoutOrder(orderPayment.orderId, {
|
|
30
|
-
paymentContext: {
|
|
31
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
if (!order)
|
|
35
|
-
throw new Error(`Order with id ${orderPayment.orderId} not found`);
|
|
36
|
-
const orderId = order._id;
|
|
37
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
38
|
-
orderId,
|
|
39
|
-
});
|
|
40
|
-
if (!enrollment)
|
|
41
|
-
throw new Error('Could not find any matching enrollment');
|
|
42
|
-
await fixPeriods({
|
|
43
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
44
|
-
transactions,
|
|
45
|
-
enrollmentId: enrollment._id,
|
|
46
|
-
orderId,
|
|
47
|
-
}, resolvedContext);
|
|
48
|
-
logger.info(`Apple IAP Webhook: Confirmed checkout for order ${order.orderNumber}`, {
|
|
49
|
-
orderId: order._id,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByTransactionId(latestTransaction.original_transaction_id);
|
|
54
|
-
if (!originalOrderPayment)
|
|
55
|
-
throw new Error('Could not find any matching order payment');
|
|
56
|
-
const originalOrder = await modules.orders.findOrder({
|
|
57
|
-
orderId: originalOrderPayment.orderId,
|
|
58
|
-
});
|
|
59
|
-
const enrollment = originalOrder &&
|
|
60
|
-
(await modules.enrollments.findEnrollment({
|
|
61
|
-
orderId: originalOrder._id,
|
|
62
|
-
}));
|
|
63
|
-
if (!enrollment?.payment)
|
|
64
|
-
throw new Error('Could not find a valid enrollment payment method');
|
|
65
|
-
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
66
|
-
transactionContext: {
|
|
67
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
68
|
-
},
|
|
69
|
-
userId: enrollment.userId,
|
|
70
|
-
});
|
|
71
|
-
await fixPeriods({
|
|
72
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
73
|
-
transactions,
|
|
74
|
-
enrollmentId: enrollment._id,
|
|
75
|
-
orderId: originalOrder._id,
|
|
76
|
-
}, resolvedContext);
|
|
77
|
-
logger.info(`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`);
|
|
78
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
79
|
-
if (enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
80
|
-
responseBody.auto_renew_status === 'false') {
|
|
81
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
85
|
-
if (enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
86
|
-
responseBody.auto_renew_status === 'false') {
|
|
87
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
91
|
-
}
|
|
92
|
-
res.status(200).end();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
logger.warn(`Apple IAP Webhook: ${e.name} - ${e.message}`);
|
|
97
|
-
res.status(503).send({ name: e.name, code: e.code, message: e.message });
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
res.status(404).end();
|
|
102
|
-
};
|
|
103
|
-
export default appleIAPHandler;
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import {} from '@unchainedshop/api';
|
|
2
|
-
import { EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
3
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
4
|
-
import { fixPeriods } from "./fix-periods.js";
|
|
5
|
-
import {} from 'fastify';
|
|
6
|
-
import {} from "./module.js";
|
|
7
|
-
const logger = createLogger('unchained:apple-iap:handler');
|
|
8
|
-
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
9
|
-
const AppleNotificationTypes = {
|
|
10
|
-
INITIAL_BUY: 'INITIAL_BUY',
|
|
11
|
-
DID_RECOVER: 'DID_RECOVER',
|
|
12
|
-
DID_CHANGE_RENEWAL_STATUS: 'DID_CHANGE_RENEWAL_STATUS',
|
|
13
|
-
DID_FAIL_TO_RENEW: 'DID_FAIL_TO_RENEW',
|
|
14
|
-
DID_CHANGE_RENEWAL_PREF: 'DID_CHANGE_RENEWAL_PREF',
|
|
15
|
-
};
|
|
16
|
-
export const appleIAPHandler = async (req, reply) => {
|
|
17
|
-
try {
|
|
18
|
-
const resolvedContext = req.unchainedContext;
|
|
19
|
-
const { modules, services } = resolvedContext;
|
|
20
|
-
const responseBody = req.body || {};
|
|
21
|
-
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
22
|
-
throw new Error('shared secret not valid');
|
|
23
|
-
}
|
|
24
|
-
const transactions = responseBody?.unified_receipt?.latest_receipt_info;
|
|
25
|
-
const latestTransaction = transactions[0];
|
|
26
|
-
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
27
|
-
const orderPayment = await modules.orders.payments.findOrderPaymentByTransactionId(latestTransaction.transaction_id);
|
|
28
|
-
if (!orderPayment)
|
|
29
|
-
throw new Error('Could not find any matching order payment');
|
|
30
|
-
const order = await services.orders.checkoutOrder(orderPayment.orderId, {
|
|
31
|
-
paymentContext: {
|
|
32
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
if (!order)
|
|
36
|
-
throw new Error(`Order with id ${orderPayment.orderId} not found`);
|
|
37
|
-
const orderId = order._id;
|
|
38
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
39
|
-
orderId,
|
|
40
|
-
});
|
|
41
|
-
if (!enrollment)
|
|
42
|
-
throw new Error('Enrollent not found');
|
|
43
|
-
await fixPeriods({
|
|
44
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
45
|
-
transactions,
|
|
46
|
-
enrollmentId: enrollment._id,
|
|
47
|
-
orderId,
|
|
48
|
-
}, resolvedContext);
|
|
49
|
-
logger.info(`Webhook confirmed checkout for order ${order.orderNumber}`, {
|
|
50
|
-
orderId: order._id,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByTransactionId(latestTransaction.original_transaction_id);
|
|
55
|
-
if (!originalOrderPayment)
|
|
56
|
-
throw new Error('Could not find any matching order payment');
|
|
57
|
-
const originalOrder = await modules.orders.findOrder({
|
|
58
|
-
orderId: originalOrderPayment.orderId,
|
|
59
|
-
});
|
|
60
|
-
const enrollment = originalOrder &&
|
|
61
|
-
(await modules.enrollments.findEnrollment({
|
|
62
|
-
orderId: originalOrder._id,
|
|
63
|
-
}));
|
|
64
|
-
if (!enrollment?.payment)
|
|
65
|
-
throw new Error('Could not find a valid enrollment payment method');
|
|
66
|
-
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
67
|
-
transactionContext: {
|
|
68
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
69
|
-
},
|
|
70
|
-
userId: enrollment.userId,
|
|
71
|
-
});
|
|
72
|
-
await fixPeriods({
|
|
73
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
74
|
-
transactions,
|
|
75
|
-
enrollmentId: enrollment._id,
|
|
76
|
-
orderId: originalOrder._id,
|
|
77
|
-
}, resolvedContext);
|
|
78
|
-
logger.info(`Webhook rocessed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`);
|
|
79
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
80
|
-
if (enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
81
|
-
responseBody.auto_renew_status === 'false') {
|
|
82
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
86
|
-
if (enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
87
|
-
responseBody.auto_renew_status === 'false') {
|
|
88
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
92
|
-
}
|
|
93
|
-
reply.status(200);
|
|
94
|
-
return reply.send();
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
logger.error(e);
|
|
98
|
-
reply.status(503);
|
|
99
|
-
return reply.send({ success: false, name: e.name, code: e.code, message: e.message });
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
export default appleIAPHandler;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/payment/braintree.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
-
import { PaymentAdapter, PaymentDirector, PaymentError, OrderPricingSheet, } from '@unchainedshop/core';
|
|
3
|
-
const logger = createLogger('unchained:braintree');
|
|
4
|
-
const { BRAINTREE_SANDBOX_TOKEN, BRAINTREE_PRIVATE_KEY } = process.env;
|
|
5
|
-
let braintree;
|
|
6
|
-
try {
|
|
7
|
-
const braintreePackage = await import('braintree');
|
|
8
|
-
braintree = braintreePackage.default;
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
logger.warn("npm dependency 'braintree' is not installed, paypal adapter will not work");
|
|
12
|
-
}
|
|
13
|
-
const BraintreeDirect = {
|
|
14
|
-
...PaymentAdapter,
|
|
15
|
-
key: 'shop.unchained.braintree-direct',
|
|
16
|
-
label: 'Braintree Direct',
|
|
17
|
-
version: '1.0.0',
|
|
18
|
-
initialConfiguration: [
|
|
19
|
-
{
|
|
20
|
-
key: 'publicKey',
|
|
21
|
-
value: null,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
key: 'merchantId',
|
|
25
|
-
value: null,
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
typeSupported: (type) => {
|
|
29
|
-
return type === 'GENERIC';
|
|
30
|
-
},
|
|
31
|
-
actions: (config, context) => {
|
|
32
|
-
const getPublicKey = () => {
|
|
33
|
-
return config.reduce((current, item) => {
|
|
34
|
-
if (item.key === 'publicKey')
|
|
35
|
-
return item.value;
|
|
36
|
-
return current;
|
|
37
|
-
}, null);
|
|
38
|
-
};
|
|
39
|
-
const getMerchantId = () => {
|
|
40
|
-
return config.reduce((current, item) => {
|
|
41
|
-
if (item.key === 'merchantId')
|
|
42
|
-
return item.value;
|
|
43
|
-
return current;
|
|
44
|
-
}, null);
|
|
45
|
-
};
|
|
46
|
-
const getAccessToken = () => {
|
|
47
|
-
return BRAINTREE_SANDBOX_TOKEN;
|
|
48
|
-
};
|
|
49
|
-
const getPrivateKey = () => {
|
|
50
|
-
return BRAINTREE_PRIVATE_KEY;
|
|
51
|
-
};
|
|
52
|
-
const getGateway = (braintree) => {
|
|
53
|
-
const accessToken = getAccessToken();
|
|
54
|
-
if (accessToken) {
|
|
55
|
-
return braintree.connect({
|
|
56
|
-
accessToken,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
return braintree.connect({
|
|
60
|
-
environment: braintree.Environment.Production,
|
|
61
|
-
merchantId: getMerchantId(),
|
|
62
|
-
publicKey: getPublicKey(),
|
|
63
|
-
privateKey: getPrivateKey(),
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
const adapter = {
|
|
67
|
-
...PaymentAdapter.actions(config, context),
|
|
68
|
-
configurationError: () => {
|
|
69
|
-
const publicCredentialsValid = getAccessToken() || (getMerchantId() && getPublicKey() && getPrivateKey());
|
|
70
|
-
if (!publicCredentialsValid) {
|
|
71
|
-
return PaymentError.WRONG_CREDENTIALS;
|
|
72
|
-
}
|
|
73
|
-
return null;
|
|
74
|
-
},
|
|
75
|
-
isActive: () => {
|
|
76
|
-
if (adapter.configurationError() === null)
|
|
77
|
-
return true;
|
|
78
|
-
return false;
|
|
79
|
-
},
|
|
80
|
-
isPayLaterAllowed: () => {
|
|
81
|
-
return false;
|
|
82
|
-
},
|
|
83
|
-
sign: async () => {
|
|
84
|
-
const gateway = getGateway(braintree);
|
|
85
|
-
const result = await gateway.clientToken.generate({});
|
|
86
|
-
if (result.success) {
|
|
87
|
-
return result.clientToken;
|
|
88
|
-
}
|
|
89
|
-
throw new Error('Could not retrieve the client token');
|
|
90
|
-
},
|
|
91
|
-
charge: async ({ paypalPaymentMethodNonce }) => {
|
|
92
|
-
const { order } = context;
|
|
93
|
-
if (!order)
|
|
94
|
-
throw new Error('Order is missing in payment context');
|
|
95
|
-
if (!paypalPaymentMethodNonce)
|
|
96
|
-
throw new Error('You have to provide paypalPaymentMethodNonce in paymentContext');
|
|
97
|
-
const gateway = getGateway(braintree);
|
|
98
|
-
const address = order.billingAddress;
|
|
99
|
-
const pricing = OrderPricingSheet({
|
|
100
|
-
calculation: order.calculation,
|
|
101
|
-
currencyCode: order.currencyCode,
|
|
102
|
-
});
|
|
103
|
-
const rounded = Math.round(pricing.total({ useNetPrice: false }).amount / 10 || 0) * 10;
|
|
104
|
-
const saleRequest = {
|
|
105
|
-
amount: rounded / 100,
|
|
106
|
-
merchantAccountId: order.currencyCode,
|
|
107
|
-
paymentMethodNonce: paypalPaymentMethodNonce,
|
|
108
|
-
orderId: order.orderNumber || order._id,
|
|
109
|
-
shipping: address
|
|
110
|
-
? {
|
|
111
|
-
firstName: address.firstName,
|
|
112
|
-
lastName: address.lastName,
|
|
113
|
-
company: address.company,
|
|
114
|
-
streetAddress: address.addressLine,
|
|
115
|
-
extendedAddress: address.addressLine2,
|
|
116
|
-
locality: address.city,
|
|
117
|
-
region: address.regionCode,
|
|
118
|
-
postalCode: address.postalCode,
|
|
119
|
-
countryCodeAlpha2: address.countryCode,
|
|
120
|
-
}
|
|
121
|
-
: undefined,
|
|
122
|
-
options: {
|
|
123
|
-
submitForSettlement: true,
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
const result = await gateway.transaction.sale(saleRequest);
|
|
127
|
-
if (result.success) {
|
|
128
|
-
logger.info(`Braintree Plugin: ${result.message}`, saleRequest);
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
logger.warn(`Braintree Plugin: ${result.message}`, saleRequest);
|
|
132
|
-
throw new Error(result.message);
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
return adapter;
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
PaymentDirector.registerAdapter(BraintreeDirect);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
-
import handleWebhook from "./handle-webhook.js";
|
|
3
|
-
const logger = createLogger('unchained:cryptopay:handler');
|
|
4
|
-
const cryptopayHandler = async (req, res) => {
|
|
5
|
-
if (req.method === 'POST') {
|
|
6
|
-
try {
|
|
7
|
-
await handleWebhook(req.body, req.unchainedContext);
|
|
8
|
-
res.status(200).send({ success: true });
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
catch (e) {
|
|
12
|
-
logger.error(e);
|
|
13
|
-
res.status(500).send({ success: false, error: e.message });
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
res.status(404).send();
|
|
18
|
-
};
|
|
19
|
-
export default cryptopayHandler;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
-
import handleWebhook from "./handle-webhook.js";
|
|
3
|
-
import {} from 'fastify';
|
|
4
|
-
const logger = createLogger('unchained:cryptopay:handler');
|
|
5
|
-
const cryptopayHandler = async (req, reply) => {
|
|
6
|
-
try {
|
|
7
|
-
await handleWebhook(req.body, req.unchainedContext);
|
|
8
|
-
reply.status(200);
|
|
9
|
-
return reply.send({ success: true });
|
|
10
|
-
}
|
|
11
|
-
catch (e) {
|
|
12
|
-
logger.error(e);
|
|
13
|
-
reply.status(500);
|
|
14
|
-
return reply.send({ success: false, error: e.message });
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
export default cryptopayHandler;
|