@unchainedshop/plugins 3.0.0-rc9 → 3.0.0
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-adapter.d.ts → adapter.d.ts} +2 -4
- package/lib/files/gridfs/adapter.d.ts.map +1 -0
- package/lib/files/gridfs/{gridfs-adapter.js → adapter.js} +1 -1
- package/lib/files/gridfs/adapter.js.map +1 -0
- package/lib/files/gridfs/handler-express.d.ts +10 -0
- package/lib/files/gridfs/handler-express.d.ts.map +1 -0
- package/lib/files/gridfs/{gridfs-webhook.js → handler-express.js} +3 -2
- package/lib/files/gridfs/handler-express.js.map +1 -0
- package/lib/files/gridfs/handler-fastify.d.ts +4 -0
- package/lib/files/gridfs/handler-fastify.d.ts.map +1 -0
- package/lib/files/gridfs/handler-fastify.js +91 -0
- package/lib/files/gridfs/handler-fastify.js.map +1 -0
- package/lib/files/gridfs/index.d.ts +4 -10
- package/lib/files/gridfs/index.d.ts.map +1 -1
- package/lib/files/gridfs/index.js +3 -27
- package/lib/files/gridfs/index.js.map +1 -1
- package/lib/files/gridfs/module.d.ts +26 -0
- package/lib/files/gridfs/module.d.ts.map +1 -0
- package/lib/files/gridfs/module.js +33 -0
- package/lib/files/gridfs/module.js.map +1 -0
- package/lib/files/minio/handler-express.d.ts +3 -0
- package/lib/files/minio/handler-express.d.ts.map +1 -0
- package/lib/files/minio/{minio-webhook.js → handler-express.js} +3 -2
- package/lib/files/minio/handler-express.js.map +1 -0
- package/lib/files/minio/handler-fastify.d.ts +4 -0
- package/lib/files/minio/handler-fastify.d.ts.map +1 -0
- package/lib/files/minio/handler-fastify.js +34 -0
- package/lib/files/minio/handler-fastify.js.map +1 -0
- package/lib/files/minio/{minio-adapter.d.ts → index.d.ts} +1 -1
- package/lib/files/minio/index.d.ts.map +1 -0
- package/lib/files/minio/{minio-adapter.js → index.js} +1 -1
- package/lib/files/minio/index.js.map +1 -0
- package/lib/filters/local-search.d.ts.map +1 -1
- package/lib/filters/local-search.js +3 -23
- package/lib/filters/local-search.js.map +1 -1
- package/lib/payment/apple-iap/adapter.d.ts +1 -1
- package/lib/payment/apple-iap/adapter.d.ts.map +1 -1
- package/lib/payment/apple-iap/adapter.js +5 -155
- package/lib/payment/apple-iap/adapter.js.map +1 -1
- package/lib/payment/apple-iap/fix-periods.d.ts +8 -0
- package/lib/payment/apple-iap/fix-periods.d.ts.map +1 -0
- package/lib/payment/apple-iap/fix-periods.js +22 -0
- package/lib/payment/apple-iap/fix-periods.js.map +1 -0
- package/lib/payment/apple-iap/handler-express.d.ts +3 -0
- package/lib/payment/apple-iap/handler-express.d.ts.map +1 -0
- package/lib/payment/apple-iap/handler-express.js +110 -0
- package/lib/payment/apple-iap/handler-express.js.map +1 -0
- package/lib/payment/apple-iap/handler-fastify.d.ts +4 -0
- package/lib/payment/apple-iap/handler-fastify.d.ts.map +1 -0
- package/lib/payment/apple-iap/handler-fastify.js +104 -0
- package/lib/payment/apple-iap/handler-fastify.js.map +1 -0
- package/lib/payment/apple-iap/index.d.ts +3 -1
- package/lib/payment/apple-iap/index.d.ts.map +1 -1
- package/lib/payment/apple-iap/index.js +2 -1
- package/lib/payment/apple-iap/index.js.map +1 -1
- package/lib/payment/apple-iap/module.d.ts +22 -0
- package/lib/payment/apple-iap/module.d.ts.map +1 -0
- package/lib/payment/apple-iap/{module/configureAppleTransactionsModule.js → module.js} +7 -2
- package/lib/payment/apple-iap/module.js.map +1 -0
- package/lib/payment/apple-iap/verify-receipt.d.ts +5 -0
- package/lib/payment/apple-iap/verify-receipt.d.ts.map +1 -0
- package/lib/payment/apple-iap/verify-receipt.js +26 -0
- package/lib/payment/apple-iap/verify-receipt.js.map +1 -0
- package/lib/payment/cryptopay/handler-express.d.ts +3 -0
- package/lib/payment/cryptopay/handler-express.d.ts.map +1 -0
- package/lib/payment/cryptopay/{middleware.js → handler-express.js} +3 -2
- package/lib/payment/cryptopay/{middleware.js.map → handler-express.js.map} +1 -1
- package/lib/payment/cryptopay/handler-fastify.d.ts +4 -0
- package/lib/payment/cryptopay/handler-fastify.d.ts.map +1 -0
- package/lib/payment/cryptopay/handler-fastify.js +69 -0
- package/lib/payment/cryptopay/handler-fastify.js.map +1 -0
- package/lib/payment/cryptopay/index.d.ts +4 -4
- package/lib/payment/cryptopay/index.d.ts.map +1 -1
- package/lib/payment/cryptopay/index.js +3 -4
- package/lib/payment/cryptopay/index.js.map +1 -1
- package/lib/payment/cryptopay/module.d.ts +54 -0
- package/lib/payment/cryptopay/module.d.ts.map +1 -0
- package/lib/payment/cryptopay/{module/configureCryptopayModule.js → module.js} +8 -3
- package/lib/payment/cryptopay/module.js.map +1 -0
- package/lib/payment/cryptopay/plugin.js +1 -1
- package/lib/payment/cryptopay/plugin.js.map +1 -1
- package/lib/payment/datatrans-v2/{middleware.d.ts → handler-express.d.ts} +1 -1
- package/lib/payment/datatrans-v2/handler-express.d.ts.map +1 -0
- package/lib/payment/datatrans-v2/{middleware.js → handler-express.js} +2 -2
- package/lib/payment/datatrans-v2/handler-express.js.map +1 -0
- package/lib/payment/datatrans-v2/handler-fastify.d.ts +3 -0
- package/lib/payment/datatrans-v2/handler-fastify.d.ts.map +1 -0
- package/lib/payment/datatrans-v2/handler-fastify.js +66 -0
- package/lib/payment/datatrans-v2/handler-fastify.js.map +1 -0
- package/lib/payment/datatrans-v2/index.d.ts +1 -1
- package/lib/payment/datatrans-v2/index.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/index.js +0 -1
- package/lib/payment/datatrans-v2/index.js.map +1 -1
- package/lib/payment/payrexx/{middleware.d.ts → handler-express.d.ts} +1 -1
- package/lib/payment/payrexx/handler-express.d.ts.map +1 -0
- package/lib/payment/payrexx/{middleware.js → handler-express.js} +2 -2
- package/lib/payment/payrexx/handler-express.js.map +1 -0
- package/lib/payment/payrexx/handler-fastify.d.ts +3 -0
- package/lib/payment/payrexx/handler-fastify.d.ts.map +1 -0
- package/lib/payment/payrexx/handler-fastify.js +87 -0
- package/lib/payment/payrexx/handler-fastify.js.map +1 -0
- package/lib/payment/payrexx/index.d.ts +1 -1
- package/lib/payment/payrexx/index.d.ts.map +1 -1
- package/lib/payment/payrexx/index.js +0 -1
- package/lib/payment/payrexx/index.js.map +1 -1
- package/lib/payment/postfinance-checkout/{middleware.d.ts → handler-express.d.ts} +1 -1
- package/lib/payment/postfinance-checkout/handler-express.d.ts.map +1 -0
- package/lib/payment/postfinance-checkout/{middleware.js → handler-express.js} +1 -1
- package/lib/payment/postfinance-checkout/handler-express.js.map +1 -0
- package/lib/payment/postfinance-checkout/handler-fastify.d.ts +3 -0
- package/lib/payment/postfinance-checkout/handler-fastify.d.ts.map +1 -0
- package/lib/payment/postfinance-checkout/handler-fastify.js +39 -0
- package/lib/payment/postfinance-checkout/handler-fastify.js.map +1 -0
- package/lib/payment/postfinance-checkout/index.d.ts +1 -1
- package/lib/payment/postfinance-checkout/index.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/index.js +0 -1
- package/lib/payment/postfinance-checkout/index.js.map +1 -1
- package/lib/payment/saferpay/adapter.d.ts +0 -1
- package/lib/payment/saferpay/adapter.d.ts.map +1 -1
- package/lib/payment/saferpay/adapter.js +0 -1
- package/lib/payment/saferpay/adapter.js.map +1 -1
- package/lib/payment/saferpay/{middleware.d.ts → handler-express.d.ts} +1 -1
- package/lib/payment/saferpay/handler-express.d.ts.map +1 -0
- package/lib/payment/saferpay/{middleware.js → handler-express.js} +2 -2
- package/lib/payment/saferpay/handler-express.js.map +1 -0
- package/lib/payment/saferpay/handler-fastify.d.ts +3 -0
- package/lib/payment/saferpay/handler-fastify.d.ts.map +1 -0
- package/lib/payment/saferpay/handler-fastify.js +56 -0
- package/lib/payment/saferpay/handler-fastify.js.map +1 -0
- package/lib/payment/saferpay/index.d.ts +3 -2
- package/lib/payment/saferpay/index.d.ts.map +1 -1
- package/lib/payment/saferpay/index.js +2 -2
- package/lib/payment/saferpay/index.js.map +1 -1
- package/lib/payment/saferpay/module.d.ts +24 -0
- package/lib/payment/saferpay/module.d.ts.map +1 -0
- package/lib/payment/saferpay/{module/configureSaferpayTransactionsModule.js → module.js} +8 -3
- package/lib/payment/saferpay/module.js.map +1 -0
- package/lib/payment/stripe/{middleware.d.ts → handler-express.d.ts} +1 -1
- package/lib/payment/stripe/handler-express.d.ts.map +1 -0
- package/lib/payment/stripe/{middleware.js → handler-express.js} +2 -2
- package/lib/payment/stripe/handler-express.js.map +1 -0
- package/lib/payment/stripe/handler-fastify.d.ts +7 -0
- package/lib/payment/stripe/handler-fastify.d.ts.map +1 -0
- package/lib/payment/stripe/handler-fastify.js +112 -0
- package/lib/payment/stripe/handler-fastify.js.map +1 -0
- package/lib/payment/stripe/index.d.ts +1 -1
- package/lib/payment/stripe/index.d.ts.map +1 -1
- package/lib/payment/stripe/index.js +0 -1
- package/lib/payment/stripe/index.js.map +1 -1
- package/lib/presets/all-express.d.ts +7 -0
- package/lib/presets/all-express.d.ts.map +1 -0
- package/lib/presets/all-express.js +27 -0
- package/lib/presets/all-express.js.map +1 -0
- package/lib/presets/all-fastify.d.ts +7 -0
- package/lib/presets/all-fastify.d.ts.map +1 -0
- package/lib/presets/all-fastify.js +64 -0
- package/lib/presets/all-fastify.js.map +1 -0
- package/lib/presets/all.d.ts +69 -0
- package/lib/presets/all.d.ts.map +1 -0
- package/lib/presets/all.js +30 -0
- package/lib/presets/all.js.map +1 -0
- package/lib/presets/base-express.js +2 -2
- package/lib/presets/base-express.js.map +1 -1
- package/lib/presets/base-fastify.d.ts +4 -0
- package/lib/presets/base-fastify.d.ts.map +1 -0
- package/lib/presets/base-fastify.js +18 -0
- package/lib/presets/base-fastify.js.map +1 -0
- package/lib/presets/{base-modules.d.ts → base.d.ts} +3 -7
- package/lib/presets/base.d.ts.map +1 -0
- package/lib/presets/{base-modules.js → base.js} +3 -9
- package/lib/presets/base.js.map +1 -0
- package/lib/presets/crypto-express.js +2 -2
- package/lib/presets/crypto-express.js.map +1 -1
- package/lib/presets/crypto-fastify.d.ts +4 -0
- package/lib/presets/crypto-fastify.d.ts.map +1 -0
- package/lib/presets/crypto-fastify.js +12 -0
- package/lib/presets/crypto-fastify.js.map +1 -0
- package/lib/presets/crypto.d.ts +8 -0
- package/lib/presets/crypto.d.ts.map +1 -0
- package/lib/presets/crypto.js +9 -0
- package/lib/presets/crypto.js.map +1 -0
- package/lib/pricing/product-discount.js +2 -0
- package/lib/pricing/product-discount.js.map +1 -1
- package/lib/warehousing/eth-minter.js +2 -2
- package/lib/warehousing/eth-minter.js.map +1 -1
- package/lib/worker/zombie-killer.js +4 -1
- package/lib/worker/zombie-killer.js.map +1 -1
- package/package.json +41 -37
- package/src/files/gridfs/{gridfs-adapter.ts → adapter.ts} +1 -3
- package/src/files/gridfs/{gridfs-webhook.ts → handler-express.ts} +5 -3
- package/src/files/gridfs/handler-fastify.ts +122 -0
- package/src/files/gridfs/index.ts +4 -29
- package/src/files/gridfs/module.ts +39 -0
- package/src/files/minio/{minio-webhook.ts → handler-express.ts} +3 -1
- package/src/files/minio/handler-fastify.ts +44 -0
- package/src/filters/local-search.ts +3 -25
- package/src/payment/apple-iap/adapter.ts +6 -193
- package/src/payment/apple-iap/fix-periods.ts +34 -0
- package/src/payment/apple-iap/handler-express.ts +134 -0
- package/src/payment/apple-iap/handler-fastify.ts +137 -0
- package/src/payment/apple-iap/index.ts +5 -1
- package/src/payment/apple-iap/module.ts +29 -0
- package/src/payment/apple-iap/verify-receipt.ts +27 -0
- package/src/payment/cryptopay/{middleware.ts → handler-express.ts} +5 -5
- package/src/payment/cryptopay/handler-fastify.ts +89 -0
- package/src/payment/cryptopay/index.ts +5 -4
- package/src/payment/cryptopay/{module/configureCryptopayModule.ts → module.ts} +38 -39
- package/src/payment/cryptopay/plugin.ts +3 -3
- package/src/payment/datatrans-v2/{middleware.ts → handler-express.ts} +1 -1
- package/src/payment/datatrans-v2/handler-fastify.ts +88 -0
- package/src/payment/datatrans-v2/index.ts +0 -2
- package/src/payment/payrexx/{middleware.ts → handler-express.ts} +1 -1
- package/src/payment/payrexx/handler-fastify.ts +105 -0
- package/src/payment/payrexx/index.ts +0 -2
- package/src/payment/postfinance-checkout/handler-fastify.ts +52 -0
- package/src/payment/postfinance-checkout/index.ts +0 -2
- package/src/payment/saferpay/adapter.ts +2 -4
- package/src/payment/saferpay/{middleware.ts → handler-express.ts} +3 -3
- package/src/payment/saferpay/handler-fastify.ts +75 -0
- package/src/payment/saferpay/index.ts +5 -2
- package/src/payment/saferpay/{module/configureSaferpayTransactionsModule.ts → module.ts} +11 -3
- package/src/payment/stripe/{middleware.ts → handler-express.ts} +1 -1
- package/src/payment/stripe/handler-fastify.ts +139 -0
- package/src/payment/stripe/index.ts +0 -2
- package/src/presets/all-express.ts +51 -0
- package/src/presets/all-fastify.ts +87 -0
- package/src/presets/all.ts +35 -0
- package/src/presets/base-express.ts +2 -2
- package/src/presets/base-fastify.ts +20 -0
- package/src/presets/{base-modules.ts → base.ts} +3 -17
- package/src/presets/crypto-express.ts +2 -2
- package/src/presets/crypto-fastify.ts +15 -0
- package/src/presets/crypto.ts +11 -0
- package/src/pricing/product-discount.ts +2 -0
- package/src/warehousing/eth-minter.ts +2 -2
- package/src/worker/zombie-killer.ts +4 -4
- package/lib/files/gridfs/gridfs-adapter.d.ts.map +0 -1
- package/lib/files/gridfs/gridfs-adapter.js.map +0 -1
- package/lib/files/gridfs/gridfs-webhook.d.ts +0 -11
- package/lib/files/gridfs/gridfs-webhook.d.ts.map +0 -1
- package/lib/files/gridfs/gridfs-webhook.js.map +0 -1
- package/lib/files/minio/minio-adapter.d.ts.map +0 -1
- package/lib/files/minio/minio-adapter.js.map +0 -1
- package/lib/files/minio/minio-webhook.d.ts +0 -2
- package/lib/files/minio/minio-webhook.d.ts.map +0 -1
- package/lib/files/minio/minio-webhook.js.map +0 -1
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts +0 -9
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts.map +0 -1
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js.map +0 -1
- package/lib/payment/cryptopay/middleware.d.ts +0 -2
- package/lib/payment/cryptopay/middleware.d.ts.map +0 -1
- package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts +0 -25
- package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts.map +0 -1
- package/lib/payment/cryptopay/module/configureCryptopayModule.js.map +0 -1
- package/lib/payment/datatrans-v2/middleware.d.ts.map +0 -1
- package/lib/payment/datatrans-v2/middleware.js.map +0 -1
- package/lib/payment/payrexx/middleware.d.ts.map +0 -1
- package/lib/payment/payrexx/middleware.js.map +0 -1
- package/lib/payment/postfinance-checkout/middleware.d.ts.map +0 -1
- package/lib/payment/postfinance-checkout/middleware.js.map +0 -1
- package/lib/payment/saferpay/middleware.d.ts.map +0 -1
- package/lib/payment/saferpay/middleware.js.map +0 -1
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts +0 -10
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts.map +0 -1
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js.map +0 -1
- package/lib/payment/stripe/middleware.d.ts.map +0 -1
- package/lib/payment/stripe/middleware.js.map +0 -1
- package/lib/plugins-index.d.ts +0 -18
- package/lib/plugins-index.d.ts.map +0 -1
- package/lib/plugins-index.js +0 -52
- package/lib/plugins-index.js.map +0 -1
- package/lib/presets/base-modules.d.ts.map +0 -1
- package/lib/presets/base-modules.js.map +0 -1
- package/lib/presets/crypto-modules.d.ts +0 -11
- package/lib/presets/crypto-modules.d.ts.map +0 -1
- package/lib/presets/crypto-modules.js +0 -14
- package/lib/presets/crypto-modules.js.map +0 -1
- package/src/payment/apple-iap/module/configureAppleTransactionsModule.ts +0 -25
- package/src/plugins-index.ts +0 -90
- package/src/presets/crypto-modules.ts +0 -23
- /package/src/files/minio/{minio-adapter.ts → index.ts} +0 -0
- /package/src/payment/postfinance-checkout/{middleware.ts → handler-express.ts} +0 -0
|
@@ -1,196 +1,11 @@
|
|
|
1
|
-
import { Context } from '@unchainedshop/api';
|
|
2
|
-
import { EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
3
1
|
import { IPaymentAdapter, PaymentAdapter, PaymentDirector, PaymentError } from '@unchainedshop/core';
|
|
4
2
|
import { createLogger } from '@unchainedshop/logger';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { AppleTransactionsModule } from './module.js';
|
|
4
|
+
import { verifyReceipt } from './verify-receipt.js';
|
|
7
5
|
|
|
8
6
|
const logger = createLogger('unchained:core-payment:iap');
|
|
9
7
|
|
|
10
|
-
const { APPLE_IAP_SHARED_SECRET
|
|
11
|
-
|
|
12
|
-
// https://developer.apple.com/documentation/storekit/in-app_purchase/validating_receipts_with_the_app_store
|
|
13
|
-
const environments = {
|
|
14
|
-
sandbox: 'https://sandbox.itunes.apple.com/verifyReceipt',
|
|
15
|
-
production: 'https://buy.itunes.apple.com/verifyReceipt',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const verifyReceipt = async ({ receiptData, password }): Promise<any> => {
|
|
19
|
-
const payload: any = {
|
|
20
|
-
'receipt-data': receiptData,
|
|
21
|
-
};
|
|
22
|
-
if (password) {
|
|
23
|
-
payload.password = password;
|
|
24
|
-
}
|
|
25
|
-
const result = await fetch(environments[APPLE_IAP_ENVIRONMENT], {
|
|
26
|
-
body: JSON.stringify(payload),
|
|
27
|
-
method: 'POST',
|
|
28
|
-
// eslint-disable-next-line
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
duplex: 'half',
|
|
31
|
-
headers: {
|
|
32
|
-
'Content-Type': 'application/json',
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
return result.json();
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const AppleNotificationTypes = {
|
|
39
|
-
INITIAL_BUY: 'INITIAL_BUY',
|
|
40
|
-
DID_RECOVER: 'DID_RECOVER',
|
|
41
|
-
DID_CHANGE_RENEWAL_STATUS: 'DID_CHANGE_RENEWAL_STATUS',
|
|
42
|
-
DID_FAIL_TO_RENEW: 'DID_FAIL_TO_RENEW',
|
|
43
|
-
DID_CHANGE_RENEWAL_PREF: 'DID_CHANGE_RENEWAL_PREF',
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const fixPeriods = async (
|
|
47
|
-
{ transactionId, enrollmentId, orderId, transactions },
|
|
48
|
-
unchainedAPI: UnchainedCore,
|
|
49
|
-
) => {
|
|
50
|
-
const relevantTransactions = transactions.filter(
|
|
51
|
-
// eslint-disable-next-line
|
|
52
|
-
({ original_transaction_id }) => {
|
|
53
|
-
return original_transaction_id === transactionId; // eslint-disable-line
|
|
54
|
-
},
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const adjustedEnrollmentPeriods = relevantTransactions
|
|
58
|
-
.map((transaction) => {
|
|
59
|
-
return {
|
|
60
|
-
isTrial: transaction.is_trial_period === 'true', // eslint-disable-line
|
|
61
|
-
start: new Date(parseInt(transaction.purchase_date_ms, 10)),
|
|
62
|
-
end: new Date(parseInt(transaction.expires_date_ms, 10)),
|
|
63
|
-
orderId: transaction.transaction_id === transactionId ? orderId : null,
|
|
64
|
-
};
|
|
65
|
-
})
|
|
66
|
-
.toSorted((left, right) => {
|
|
67
|
-
return left.end.getTime() - right.end.getTime();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
await unchainedAPI.modules.enrollments.removeEnrollmentPeriodByOrderId(enrollmentId, orderId);
|
|
71
|
-
|
|
72
|
-
return Promise.all(
|
|
73
|
-
adjustedEnrollmentPeriods.map((period) =>
|
|
74
|
-
unchainedAPI.modules.enrollments.addEnrollmentPeriod(enrollmentId, period),
|
|
75
|
-
),
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const appleIAPHandler = async (req, res) => {
|
|
80
|
-
if (req.method === 'POST') {
|
|
81
|
-
try {
|
|
82
|
-
const resolvedContext = req.unchainedContext as Context;
|
|
83
|
-
const { modules, services } = resolvedContext;
|
|
84
|
-
const responseBody = req.body || {};
|
|
85
|
-
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
86
|
-
throw new Error('shared secret not valid');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const transactions = responseBody?.unified_receipt?.latest_receipt_info; // eslint-disable-line
|
|
90
|
-
const latestTransaction = transactions[0];
|
|
91
|
-
|
|
92
|
-
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
93
|
-
// Find the cart to checkout
|
|
94
|
-
const orderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
95
|
-
context: {
|
|
96
|
-
'meta.transactionIdentifier': latestTransaction.transaction_id,
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
if (!orderPayment) throw new Error('Could not find any matching order payment');
|
|
101
|
-
|
|
102
|
-
const order = await services.orders.checkoutOrder(orderPayment.orderId, {
|
|
103
|
-
paymentContext: {
|
|
104
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
const orderId = order._id;
|
|
108
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
109
|
-
orderId,
|
|
110
|
-
});
|
|
111
|
-
await fixPeriods(
|
|
112
|
-
{
|
|
113
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
114
|
-
transactions,
|
|
115
|
-
enrollmentId: enrollment._id,
|
|
116
|
-
orderId,
|
|
117
|
-
},
|
|
118
|
-
resolvedContext,
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
logger.info(`Apple IAP Webhook: Confirmed checkout for order ${order.orderNumber}`, {
|
|
122
|
-
orderId: order._id,
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
125
|
-
// Just store payment credentials, use the enrollments paymentProvider reference and
|
|
126
|
-
// let the job do the rest
|
|
127
|
-
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
128
|
-
context: {
|
|
129
|
-
'meta.transactionIdentifier': latestTransaction.original_transaction_id,
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
if (!originalOrderPayment) throw new Error('Could not find any matching order payment');
|
|
133
|
-
const originalOrder = await modules.orders.findOrder({
|
|
134
|
-
orderId: originalOrderPayment.orderId,
|
|
135
|
-
});
|
|
136
|
-
const enrollment = await modules.enrollments.findEnrollment({
|
|
137
|
-
orderId: originalOrder._id,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
141
|
-
transactionContext: {
|
|
142
|
-
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
143
|
-
},
|
|
144
|
-
userId: enrollment.userId,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
await fixPeriods(
|
|
148
|
-
{
|
|
149
|
-
transactionId: latestTransaction.original_transaction_id,
|
|
150
|
-
transactions,
|
|
151
|
-
enrollmentId: enrollment._id,
|
|
152
|
-
orderId: originalOrder._id,
|
|
153
|
-
},
|
|
154
|
-
resolvedContext,
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
logger.info(
|
|
158
|
-
`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
162
|
-
if (
|
|
163
|
-
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
164
|
-
responseBody.auto_renew_status === 'false'
|
|
165
|
-
) {
|
|
166
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
171
|
-
if (
|
|
172
|
-
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
173
|
-
responseBody.auto_renew_status === 'false'
|
|
174
|
-
) {
|
|
175
|
-
await services.enrollments.terminateEnrollment(enrollment);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
res.writeHead(200);
|
|
182
|
-
res.end();
|
|
183
|
-
return;
|
|
184
|
-
} catch (e) {
|
|
185
|
-
logger.warn(`Apple IAP Webhook: ${e.message}`, e);
|
|
186
|
-
res.writeHead(503);
|
|
187
|
-
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
res.writeHead(404);
|
|
192
|
-
res.end();
|
|
193
|
-
};
|
|
8
|
+
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
194
9
|
|
|
195
10
|
const AppleIAP: IPaymentAdapter = {
|
|
196
11
|
...PaymentAdapter,
|
|
@@ -205,7 +20,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
205
20
|
},
|
|
206
21
|
|
|
207
22
|
actions: (params, context) => {
|
|
208
|
-
const { modules } = context;
|
|
23
|
+
const { order, modules } = context as typeof context & { modules: AppleTransactionsModule };
|
|
209
24
|
|
|
210
25
|
const adapterActions = {
|
|
211
26
|
...PaymentAdapter.actions(params, context),
|
|
@@ -266,10 +81,8 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
266
81
|
|
|
267
82
|
// eslint-disable-next-line
|
|
268
83
|
async charge(transactionContext) {
|
|
269
|
-
const { order } = context;
|
|
270
84
|
const { meta, paymentCredentials, receiptData } = transactionContext || {};
|
|
271
85
|
const { transactionIdentifier } = meta || {};
|
|
272
|
-
const appleTransactions = (context.modules as any).appleTransactions as AppleTransactionsModule;
|
|
273
86
|
|
|
274
87
|
if (!transactionIdentifier) {
|
|
275
88
|
throw new Error('Apple IAP Plugin: You have to set the transaction id on the order payment');
|
|
@@ -324,13 +137,13 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
324
137
|
throw new Error('Apple IAP Plugin: Product in order does not match transaction');
|
|
325
138
|
|
|
326
139
|
const alreadyProcessedTransaction =
|
|
327
|
-
await appleTransactions.findTransactionById(transactionIdentifier);
|
|
140
|
+
await modules.appleTransactions.findTransactionById(transactionIdentifier);
|
|
328
141
|
|
|
329
142
|
if (alreadyProcessedTransaction)
|
|
330
143
|
throw new Error('Apple IAP Plugin: Transaction already processed');
|
|
331
144
|
|
|
332
145
|
// All good
|
|
333
|
-
await appleTransactions.createTransaction({
|
|
146
|
+
await modules.appleTransactions.createTransaction({
|
|
334
147
|
_id: transactionIdentifier,
|
|
335
148
|
matchedTransaction,
|
|
336
149
|
orderId: order._id,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { UnchainedCore } from '@unchainedshop/core';
|
|
2
|
+
|
|
3
|
+
export const fixPeriods = async (
|
|
4
|
+
{ transactionId, enrollmentId, orderId, transactions },
|
|
5
|
+
unchainedAPI: UnchainedCore,
|
|
6
|
+
) => {
|
|
7
|
+
const relevantTransactions = transactions.filter(
|
|
8
|
+
// eslint-disable-next-line
|
|
9
|
+
({ original_transaction_id }) => {
|
|
10
|
+
return original_transaction_id === transactionId; // eslint-disable-line
|
|
11
|
+
},
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const adjustedEnrollmentPeriods = relevantTransactions
|
|
15
|
+
.map((transaction) => {
|
|
16
|
+
return {
|
|
17
|
+
isTrial: transaction.is_trial_period === 'true', // eslint-disable-line
|
|
18
|
+
start: new Date(parseInt(transaction.purchase_date_ms, 10)),
|
|
19
|
+
end: new Date(parseInt(transaction.expires_date_ms, 10)),
|
|
20
|
+
orderId: transaction.transaction_id === transactionId ? orderId : null,
|
|
21
|
+
};
|
|
22
|
+
})
|
|
23
|
+
.toSorted((left, right) => {
|
|
24
|
+
return left.end.getTime() - right.end.getTime();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
await unchainedAPI.modules.enrollments.removeEnrollmentPeriodByOrderId(enrollmentId, orderId);
|
|
28
|
+
|
|
29
|
+
return Promise.all(
|
|
30
|
+
adjustedEnrollmentPeriods.map((period) =>
|
|
31
|
+
unchainedAPI.modules.enrollments.addEnrollmentPeriod(enrollmentId, period),
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Context } from '@unchainedshop/api';
|
|
2
|
+
import { EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
3
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
4
|
+
import { fixPeriods } from './fix-periods.js';
|
|
5
|
+
|
|
6
|
+
const logger = createLogger('unchained:core-payment:iap');
|
|
7
|
+
|
|
8
|
+
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
9
|
+
|
|
10
|
+
const AppleNotificationTypes = {
|
|
11
|
+
INITIAL_BUY: 'INITIAL_BUY',
|
|
12
|
+
DID_RECOVER: 'DID_RECOVER',
|
|
13
|
+
DID_CHANGE_RENEWAL_STATUS: 'DID_CHANGE_RENEWAL_STATUS',
|
|
14
|
+
DID_FAIL_TO_RENEW: 'DID_FAIL_TO_RENEW',
|
|
15
|
+
DID_CHANGE_RENEWAL_PREF: 'DID_CHANGE_RENEWAL_PREF',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const appleIAPHandler = async (req, res) => {
|
|
19
|
+
if (req.method === 'POST') {
|
|
20
|
+
try {
|
|
21
|
+
const resolvedContext = req.unchainedContext as Context;
|
|
22
|
+
const { modules, services } = resolvedContext;
|
|
23
|
+
const responseBody = req.body || {};
|
|
24
|
+
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
25
|
+
throw new Error('shared secret not valid');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const transactions = responseBody?.unified_receipt?.latest_receipt_info; // eslint-disable-line
|
|
29
|
+
const latestTransaction = transactions[0];
|
|
30
|
+
|
|
31
|
+
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
32
|
+
// Find the cart to checkout
|
|
33
|
+
const orderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
34
|
+
context: {
|
|
35
|
+
'meta.transactionIdentifier': latestTransaction.transaction_id,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!orderPayment) throw new Error('Could not find any matching order payment');
|
|
40
|
+
|
|
41
|
+
const order = await services.orders.checkoutOrder(orderPayment.orderId, {
|
|
42
|
+
paymentContext: {
|
|
43
|
+
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const orderId = order._id;
|
|
47
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
48
|
+
orderId,
|
|
49
|
+
});
|
|
50
|
+
await fixPeriods(
|
|
51
|
+
{
|
|
52
|
+
transactionId: latestTransaction.original_transaction_id,
|
|
53
|
+
transactions,
|
|
54
|
+
enrollmentId: enrollment._id,
|
|
55
|
+
orderId,
|
|
56
|
+
},
|
|
57
|
+
resolvedContext,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
logger.info(`Apple IAP Webhook: Confirmed checkout for order ${order.orderNumber}`, {
|
|
61
|
+
orderId: order._id,
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
// Just store payment credentials, use the enrollments paymentProvider reference and
|
|
65
|
+
// let the job do the rest
|
|
66
|
+
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
67
|
+
context: {
|
|
68
|
+
'meta.transactionIdentifier': latestTransaction.original_transaction_id,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
if (!originalOrderPayment) throw new Error('Could not find any matching order payment');
|
|
72
|
+
const originalOrder = await modules.orders.findOrder({
|
|
73
|
+
orderId: originalOrderPayment.orderId,
|
|
74
|
+
});
|
|
75
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
76
|
+
orderId: originalOrder._id,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
80
|
+
transactionContext: {
|
|
81
|
+
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
82
|
+
},
|
|
83
|
+
userId: enrollment.userId,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await fixPeriods(
|
|
87
|
+
{
|
|
88
|
+
transactionId: latestTransaction.original_transaction_id,
|
|
89
|
+
transactions,
|
|
90
|
+
enrollmentId: enrollment._id,
|
|
91
|
+
orderId: originalOrder._id,
|
|
92
|
+
},
|
|
93
|
+
resolvedContext,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
logger.info(
|
|
97
|
+
`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
101
|
+
if (
|
|
102
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
103
|
+
responseBody.auto_renew_status === 'false'
|
|
104
|
+
) {
|
|
105
|
+
await services.enrollments.terminateEnrollment(enrollment);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
110
|
+
if (
|
|
111
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
112
|
+
responseBody.auto_renew_status === 'false'
|
|
113
|
+
) {
|
|
114
|
+
await services.enrollments.terminateEnrollment(enrollment);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
res.writeHead(200);
|
|
121
|
+
res.end();
|
|
122
|
+
return;
|
|
123
|
+
} catch (e) {
|
|
124
|
+
logger.warn(`Apple IAP Webhook: ${e.message}`, e);
|
|
125
|
+
res.writeHead(503);
|
|
126
|
+
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
res.writeHead(404);
|
|
131
|
+
res.end();
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export default appleIAPHandler;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Context } 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 { FastifyRequest, RouteHandlerMethod } from 'fastify';
|
|
6
|
+
import { AppleTransactionsModule } from './module.js';
|
|
7
|
+
|
|
8
|
+
const logger = createLogger('unchained:core-payment:iap');
|
|
9
|
+
|
|
10
|
+
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
11
|
+
|
|
12
|
+
const AppleNotificationTypes = {
|
|
13
|
+
INITIAL_BUY: 'INITIAL_BUY',
|
|
14
|
+
DID_RECOVER: 'DID_RECOVER',
|
|
15
|
+
DID_CHANGE_RENEWAL_STATUS: 'DID_CHANGE_RENEWAL_STATUS',
|
|
16
|
+
DID_FAIL_TO_RENEW: 'DID_FAIL_TO_RENEW',
|
|
17
|
+
DID_CHANGE_RENEWAL_PREF: 'DID_CHANGE_RENEWAL_PREF',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const appleIAPHandler: RouteHandlerMethod = async (
|
|
21
|
+
req: FastifyRequest & {
|
|
22
|
+
unchainedContext: Context & {
|
|
23
|
+
modules: AppleTransactionsModule;
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
reply,
|
|
27
|
+
) => {
|
|
28
|
+
try {
|
|
29
|
+
const resolvedContext = req.unchainedContext as Context;
|
|
30
|
+
const { modules, services } = resolvedContext;
|
|
31
|
+
const responseBody: Record<string, any> = req.body || {};
|
|
32
|
+
if (responseBody.password !== APPLE_IAP_SHARED_SECRET) {
|
|
33
|
+
throw new Error('shared secret not valid');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const transactions = responseBody?.unified_receipt?.latest_receipt_info; // eslint-disable-line
|
|
37
|
+
const latestTransaction = transactions[0];
|
|
38
|
+
|
|
39
|
+
if (responseBody.notification_type === AppleNotificationTypes.INITIAL_BUY) {
|
|
40
|
+
// Find the cart to checkout
|
|
41
|
+
const orderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
42
|
+
context: {
|
|
43
|
+
'meta.transactionIdentifier': latestTransaction.transaction_id,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!orderPayment) throw new Error('Could not find any matching order payment');
|
|
48
|
+
|
|
49
|
+
const order = await services.orders.checkoutOrder(orderPayment.orderId, {
|
|
50
|
+
paymentContext: {
|
|
51
|
+
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
const orderId = order._id;
|
|
55
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
56
|
+
orderId,
|
|
57
|
+
});
|
|
58
|
+
await fixPeriods(
|
|
59
|
+
{
|
|
60
|
+
transactionId: latestTransaction.original_transaction_id,
|
|
61
|
+
transactions,
|
|
62
|
+
enrollmentId: enrollment._id,
|
|
63
|
+
orderId,
|
|
64
|
+
},
|
|
65
|
+
resolvedContext,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
logger.info(`Apple IAP Webhook: Confirmed checkout for order ${order.orderNumber}`, {
|
|
69
|
+
orderId: order._id,
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
// Just store payment credentials, use the enrollments paymentProvider reference and
|
|
73
|
+
// let the job do the rest
|
|
74
|
+
const originalOrderPayment = await modules.orders.payments.findOrderPaymentByContextData({
|
|
75
|
+
context: {
|
|
76
|
+
'meta.transactionIdentifier': latestTransaction.original_transaction_id,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
if (!originalOrderPayment) throw new Error('Could not find any matching order payment');
|
|
80
|
+
const originalOrder = await modules.orders.findOrder({
|
|
81
|
+
orderId: originalOrderPayment.orderId,
|
|
82
|
+
});
|
|
83
|
+
const enrollment = await modules.enrollments.findEnrollment({
|
|
84
|
+
orderId: originalOrder._id,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
88
|
+
transactionContext: {
|
|
89
|
+
receiptData: responseBody?.unified_receipt?.latest_receipt, // eslint-disable-line
|
|
90
|
+
},
|
|
91
|
+
userId: enrollment.userId,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await fixPeriods(
|
|
95
|
+
{
|
|
96
|
+
transactionId: latestTransaction.original_transaction_id,
|
|
97
|
+
transactions,
|
|
98
|
+
enrollmentId: enrollment._id,
|
|
99
|
+
orderId: originalOrder._id,
|
|
100
|
+
},
|
|
101
|
+
resolvedContext,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
logger.info(
|
|
105
|
+
`Apple IAP Webhook: Processed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
109
|
+
if (
|
|
110
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
111
|
+
responseBody.auto_renew_status === 'false'
|
|
112
|
+
) {
|
|
113
|
+
await services.enrollments.terminateEnrollment(enrollment);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (responseBody.notification_type === AppleNotificationTypes.DID_CHANGE_RENEWAL_STATUS) {
|
|
118
|
+
if (
|
|
119
|
+
enrollment.status !== EnrollmentStatus.TERMINATED &&
|
|
120
|
+
responseBody.auto_renew_status === 'false'
|
|
121
|
+
) {
|
|
122
|
+
await services.enrollments.terminateEnrollment(enrollment);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
logger.info(`Apple IAP Webhook: Updated enrollment from Apple`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
reply.status(200);
|
|
129
|
+
return reply.send();
|
|
130
|
+
} catch (e) {
|
|
131
|
+
logger.warn(`Apple IAP Webhook: ${e.message}`, e);
|
|
132
|
+
reply.status(503);
|
|
133
|
+
return reply.send({ name: e.name, code: e.code, message: e.message });
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export default appleIAPHandler;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export * from './adapter.js';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import appleTransactionsModule, { type AppleTransactionsModule } from './module.js';
|
|
4
|
+
|
|
5
|
+
export type { AppleTransactionsModule };
|
|
6
|
+
export default appleTransactionsModule;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AppleTransaction, AppleTransactionsCollection } from './db/AppleTransactionsCollection.js';
|
|
2
|
+
|
|
3
|
+
export const configureAppleTransactionsModule = async ({ db }) => {
|
|
4
|
+
const AppleTransactions = await AppleTransactionsCollection(db);
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
findTransactionById: async (transactionIdentifier: string): Promise<AppleTransaction> => {
|
|
8
|
+
return AppleTransactions.findOne({ _id: transactionIdentifier });
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
createTransaction: async (doc: AppleTransaction) => {
|
|
12
|
+
await AppleTransactions.insertOne({
|
|
13
|
+
...doc,
|
|
14
|
+
created: new Date(),
|
|
15
|
+
});
|
|
16
|
+
return doc._id;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
appleTransactions: {
|
|
23
|
+
configure: configureAppleTransactionsModule,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type AppleTransactionsModule = {
|
|
28
|
+
appleTransactions: Awaited<ReturnType<typeof configureAppleTransactionsModule>>;
|
|
29
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { APPLE_IAP_ENVIRONMENT = 'sandbox' } = process.env;
|
|
2
|
+
|
|
3
|
+
// https://developer.apple.com/documentation/storekit/in-app_purchase/validating_receipts_with_the_app_store
|
|
4
|
+
const environments = {
|
|
5
|
+
sandbox: 'https://sandbox.itunes.apple.com/verifyReceipt',
|
|
6
|
+
production: 'https://buy.itunes.apple.com/verifyReceipt',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const verifyReceipt = async ({ receiptData, password }): Promise<any> => {
|
|
10
|
+
const payload: any = {
|
|
11
|
+
'receipt-data': receiptData,
|
|
12
|
+
};
|
|
13
|
+
if (password) {
|
|
14
|
+
payload.password = password;
|
|
15
|
+
}
|
|
16
|
+
const result = await fetch(environments[APPLE_IAP_ENVIRONMENT], {
|
|
17
|
+
body: JSON.stringify(payload),
|
|
18
|
+
method: 'POST',
|
|
19
|
+
// eslint-disable-next-line
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
duplex: 'half',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return result.json();
|
|
27
|
+
};
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { createLogger } from '@unchainedshop/logger';
|
|
2
2
|
import { Context } from '@unchainedshop/api';
|
|
3
3
|
import { OrderStatus } from '@unchainedshop/core-orders';
|
|
4
|
-
import { CryptopayModule } from './module
|
|
4
|
+
import { CryptopayModule } from './module.js';
|
|
5
5
|
import { ProductPriceRate } from '@unchainedshop/core-products';
|
|
6
6
|
|
|
7
7
|
const { CRYPTOPAY_SECRET, CRYPTOPAY_MAX_RATE_AGE = '360' } = process.env;
|
|
8
8
|
|
|
9
9
|
const logger = createLogger('unchained:core-payment:cryptopay');
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const cryptopayHandler = async (req, res) => {
|
|
12
12
|
const resolvedContext = req.unchainedContext as Context & {
|
|
13
|
-
modules:
|
|
14
|
-
cryptopay: CryptopayModule;
|
|
15
|
-
};
|
|
13
|
+
modules: CryptopayModule;
|
|
16
14
|
};
|
|
17
15
|
const { modules, services } = resolvedContext;
|
|
18
16
|
|
|
@@ -88,3 +86,5 @@ export const cryptopayHandler = async (req, res) => {
|
|
|
88
86
|
res.writeHead(404);
|
|
89
87
|
res.end(JSON.stringify({ success: false }));
|
|
90
88
|
};
|
|
89
|
+
|
|
90
|
+
export default cryptopayHandler;
|