@unchainedshop/plugins 3.0.0-rc9 → 3.0.1

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.
Files changed (292) hide show
  1. package/lib/files/gridfs/{gridfs-adapter.d.ts → adapter.d.ts} +2 -4
  2. package/lib/files/gridfs/adapter.d.ts.map +1 -0
  3. package/lib/files/gridfs/{gridfs-adapter.js → adapter.js} +1 -1
  4. package/lib/files/gridfs/adapter.js.map +1 -0
  5. package/lib/files/gridfs/handler-express.d.ts +10 -0
  6. package/lib/files/gridfs/handler-express.d.ts.map +1 -0
  7. package/lib/files/gridfs/{gridfs-webhook.js → handler-express.js} +3 -2
  8. package/lib/files/gridfs/handler-express.js.map +1 -0
  9. package/lib/files/gridfs/handler-fastify.d.ts +4 -0
  10. package/lib/files/gridfs/handler-fastify.d.ts.map +1 -0
  11. package/lib/files/gridfs/handler-fastify.js +91 -0
  12. package/lib/files/gridfs/handler-fastify.js.map +1 -0
  13. package/lib/files/gridfs/index.d.ts +4 -10
  14. package/lib/files/gridfs/index.d.ts.map +1 -1
  15. package/lib/files/gridfs/index.js +3 -27
  16. package/lib/files/gridfs/index.js.map +1 -1
  17. package/lib/files/gridfs/module.d.ts +26 -0
  18. package/lib/files/gridfs/module.d.ts.map +1 -0
  19. package/lib/files/gridfs/module.js +33 -0
  20. package/lib/files/gridfs/module.js.map +1 -0
  21. package/lib/files/minio/handler-express.d.ts +3 -0
  22. package/lib/files/minio/handler-express.d.ts.map +1 -0
  23. package/lib/files/minio/{minio-webhook.js → handler-express.js} +3 -2
  24. package/lib/files/minio/handler-express.js.map +1 -0
  25. package/lib/files/minio/handler-fastify.d.ts +4 -0
  26. package/lib/files/minio/handler-fastify.d.ts.map +1 -0
  27. package/lib/files/minio/handler-fastify.js +34 -0
  28. package/lib/files/minio/handler-fastify.js.map +1 -0
  29. package/lib/files/minio/{minio-adapter.d.ts → index.d.ts} +1 -1
  30. package/lib/files/minio/index.d.ts.map +1 -0
  31. package/lib/files/minio/{minio-adapter.js → index.js} +1 -1
  32. package/lib/files/minio/index.js.map +1 -0
  33. package/lib/filters/local-search.d.ts.map +1 -1
  34. package/lib/filters/local-search.js +3 -23
  35. package/lib/filters/local-search.js.map +1 -1
  36. package/lib/payment/apple-iap/adapter.d.ts +1 -1
  37. package/lib/payment/apple-iap/adapter.d.ts.map +1 -1
  38. package/lib/payment/apple-iap/adapter.js +5 -155
  39. package/lib/payment/apple-iap/adapter.js.map +1 -1
  40. package/lib/payment/apple-iap/fix-periods.d.ts +8 -0
  41. package/lib/payment/apple-iap/fix-periods.d.ts.map +1 -0
  42. package/lib/payment/apple-iap/fix-periods.js +22 -0
  43. package/lib/payment/apple-iap/fix-periods.js.map +1 -0
  44. package/lib/payment/apple-iap/handler-express.d.ts +3 -0
  45. package/lib/payment/apple-iap/handler-express.d.ts.map +1 -0
  46. package/lib/payment/apple-iap/handler-express.js +110 -0
  47. package/lib/payment/apple-iap/handler-express.js.map +1 -0
  48. package/lib/payment/apple-iap/handler-fastify.d.ts +4 -0
  49. package/lib/payment/apple-iap/handler-fastify.d.ts.map +1 -0
  50. package/lib/payment/apple-iap/handler-fastify.js +104 -0
  51. package/lib/payment/apple-iap/handler-fastify.js.map +1 -0
  52. package/lib/payment/apple-iap/index.d.ts +3 -1
  53. package/lib/payment/apple-iap/index.d.ts.map +1 -1
  54. package/lib/payment/apple-iap/index.js +2 -1
  55. package/lib/payment/apple-iap/index.js.map +1 -1
  56. package/lib/payment/apple-iap/module.d.ts +22 -0
  57. package/lib/payment/apple-iap/module.d.ts.map +1 -0
  58. package/lib/payment/apple-iap/{module/configureAppleTransactionsModule.js → module.js} +7 -2
  59. package/lib/payment/apple-iap/module.js.map +1 -0
  60. package/lib/payment/apple-iap/verify-receipt.d.ts +5 -0
  61. package/lib/payment/apple-iap/verify-receipt.d.ts.map +1 -0
  62. package/lib/payment/apple-iap/verify-receipt.js +26 -0
  63. package/lib/payment/apple-iap/verify-receipt.js.map +1 -0
  64. package/lib/payment/cryptopay/handler-express.d.ts +3 -0
  65. package/lib/payment/cryptopay/handler-express.d.ts.map +1 -0
  66. package/lib/payment/cryptopay/{middleware.js → handler-express.js} +3 -2
  67. package/lib/payment/cryptopay/{middleware.js.map → handler-express.js.map} +1 -1
  68. package/lib/payment/cryptopay/handler-fastify.d.ts +4 -0
  69. package/lib/payment/cryptopay/handler-fastify.d.ts.map +1 -0
  70. package/lib/payment/cryptopay/handler-fastify.js +69 -0
  71. package/lib/payment/cryptopay/handler-fastify.js.map +1 -0
  72. package/lib/payment/cryptopay/index.d.ts +4 -4
  73. package/lib/payment/cryptopay/index.d.ts.map +1 -1
  74. package/lib/payment/cryptopay/index.js +3 -4
  75. package/lib/payment/cryptopay/index.js.map +1 -1
  76. package/lib/payment/cryptopay/module.d.ts +54 -0
  77. package/lib/payment/cryptopay/module.d.ts.map +1 -0
  78. package/lib/payment/cryptopay/{module/configureCryptopayModule.js → module.js} +8 -3
  79. package/lib/payment/cryptopay/module.js.map +1 -0
  80. package/lib/payment/cryptopay/plugin.js +1 -1
  81. package/lib/payment/cryptopay/plugin.js.map +1 -1
  82. package/lib/payment/datatrans-v2/{middleware.d.ts → handler-express.d.ts} +1 -1
  83. package/lib/payment/datatrans-v2/handler-express.d.ts.map +1 -0
  84. package/lib/payment/datatrans-v2/{middleware.js → handler-express.js} +2 -2
  85. package/lib/payment/datatrans-v2/handler-express.js.map +1 -0
  86. package/lib/payment/datatrans-v2/handler-fastify.d.ts +3 -0
  87. package/lib/payment/datatrans-v2/handler-fastify.d.ts.map +1 -0
  88. package/lib/payment/datatrans-v2/handler-fastify.js +66 -0
  89. package/lib/payment/datatrans-v2/handler-fastify.js.map +1 -0
  90. package/lib/payment/datatrans-v2/index.d.ts +1 -1
  91. package/lib/payment/datatrans-v2/index.d.ts.map +1 -1
  92. package/lib/payment/datatrans-v2/index.js +0 -1
  93. package/lib/payment/datatrans-v2/index.js.map +1 -1
  94. package/lib/payment/paypal-checkout.js +2 -2
  95. package/lib/payment/paypal-checkout.js.map +1 -1
  96. package/lib/payment/payrexx/{middleware.d.ts → handler-express.d.ts} +1 -1
  97. package/lib/payment/payrexx/handler-express.d.ts.map +1 -0
  98. package/lib/payment/payrexx/{middleware.js → handler-express.js} +2 -2
  99. package/lib/payment/payrexx/handler-express.js.map +1 -0
  100. package/lib/payment/payrexx/handler-fastify.d.ts +3 -0
  101. package/lib/payment/payrexx/handler-fastify.d.ts.map +1 -0
  102. package/lib/payment/payrexx/handler-fastify.js +87 -0
  103. package/lib/payment/payrexx/handler-fastify.js.map +1 -0
  104. package/lib/payment/payrexx/index.d.ts +1 -1
  105. package/lib/payment/payrexx/index.d.ts.map +1 -1
  106. package/lib/payment/payrexx/index.js +0 -1
  107. package/lib/payment/payrexx/index.js.map +1 -1
  108. package/lib/payment/postfinance-checkout/{middleware.d.ts → handler-express.d.ts} +1 -1
  109. package/lib/payment/postfinance-checkout/handler-express.d.ts.map +1 -0
  110. package/lib/payment/postfinance-checkout/{middleware.js → handler-express.js} +1 -1
  111. package/lib/payment/postfinance-checkout/handler-express.js.map +1 -0
  112. package/lib/payment/postfinance-checkout/handler-fastify.d.ts +3 -0
  113. package/lib/payment/postfinance-checkout/handler-fastify.d.ts.map +1 -0
  114. package/lib/payment/postfinance-checkout/handler-fastify.js +39 -0
  115. package/lib/payment/postfinance-checkout/handler-fastify.js.map +1 -0
  116. package/lib/payment/postfinance-checkout/index.d.ts +1 -1
  117. package/lib/payment/postfinance-checkout/index.d.ts.map +1 -1
  118. package/lib/payment/postfinance-checkout/index.js +0 -1
  119. package/lib/payment/postfinance-checkout/index.js.map +1 -1
  120. package/lib/payment/saferpay/adapter.d.ts +0 -1
  121. package/lib/payment/saferpay/adapter.d.ts.map +1 -1
  122. package/lib/payment/saferpay/adapter.js +0 -1
  123. package/lib/payment/saferpay/adapter.js.map +1 -1
  124. package/lib/payment/saferpay/{middleware.d.ts → handler-express.d.ts} +1 -1
  125. package/lib/payment/saferpay/handler-express.d.ts.map +1 -0
  126. package/lib/payment/saferpay/{middleware.js → handler-express.js} +2 -2
  127. package/lib/payment/saferpay/handler-express.js.map +1 -0
  128. package/lib/payment/saferpay/handler-fastify.d.ts +3 -0
  129. package/lib/payment/saferpay/handler-fastify.d.ts.map +1 -0
  130. package/lib/payment/saferpay/handler-fastify.js +56 -0
  131. package/lib/payment/saferpay/handler-fastify.js.map +1 -0
  132. package/lib/payment/saferpay/index.d.ts +3 -2
  133. package/lib/payment/saferpay/index.d.ts.map +1 -1
  134. package/lib/payment/saferpay/index.js +2 -2
  135. package/lib/payment/saferpay/index.js.map +1 -1
  136. package/lib/payment/saferpay/module.d.ts +24 -0
  137. package/lib/payment/saferpay/module.d.ts.map +1 -0
  138. package/lib/payment/saferpay/{module/configureSaferpayTransactionsModule.js → module.js} +8 -3
  139. package/lib/payment/saferpay/module.js.map +1 -0
  140. package/lib/payment/stripe/{middleware.d.ts → handler-express.d.ts} +1 -1
  141. package/lib/payment/stripe/handler-express.d.ts.map +1 -0
  142. package/lib/payment/stripe/{middleware.js → handler-express.js} +2 -2
  143. package/lib/payment/stripe/handler-express.js.map +1 -0
  144. package/lib/payment/stripe/handler-fastify.d.ts +7 -0
  145. package/lib/payment/stripe/handler-fastify.d.ts.map +1 -0
  146. package/lib/payment/stripe/handler-fastify.js +112 -0
  147. package/lib/payment/stripe/handler-fastify.js.map +1 -0
  148. package/lib/payment/stripe/index.d.ts +1 -1
  149. package/lib/payment/stripe/index.d.ts.map +1 -1
  150. package/lib/payment/stripe/index.js +0 -1
  151. package/lib/payment/stripe/index.js.map +1 -1
  152. package/lib/presets/all-express.d.ts +7 -0
  153. package/lib/presets/all-express.d.ts.map +1 -0
  154. package/lib/presets/all-express.js +27 -0
  155. package/lib/presets/all-express.js.map +1 -0
  156. package/lib/presets/all-fastify.d.ts +7 -0
  157. package/lib/presets/all-fastify.d.ts.map +1 -0
  158. package/lib/presets/all-fastify.js +64 -0
  159. package/lib/presets/all-fastify.js.map +1 -0
  160. package/lib/presets/all.d.ts +69 -0
  161. package/lib/presets/all.d.ts.map +1 -0
  162. package/lib/presets/all.js +30 -0
  163. package/lib/presets/all.js.map +1 -0
  164. package/lib/presets/base-express.js +2 -2
  165. package/lib/presets/base-express.js.map +1 -1
  166. package/lib/presets/base-fastify.d.ts +4 -0
  167. package/lib/presets/base-fastify.d.ts.map +1 -0
  168. package/lib/presets/base-fastify.js +18 -0
  169. package/lib/presets/base-fastify.js.map +1 -0
  170. package/lib/presets/{base-modules.d.ts → base.d.ts} +3 -7
  171. package/lib/presets/base.d.ts.map +1 -0
  172. package/lib/presets/{base-modules.js → base.js} +3 -9
  173. package/lib/presets/base.js.map +1 -0
  174. package/lib/presets/crypto-express.js +2 -2
  175. package/lib/presets/crypto-express.js.map +1 -1
  176. package/lib/presets/crypto-fastify.d.ts +4 -0
  177. package/lib/presets/crypto-fastify.d.ts.map +1 -0
  178. package/lib/presets/crypto-fastify.js +12 -0
  179. package/lib/presets/crypto-fastify.js.map +1 -0
  180. package/lib/presets/crypto.d.ts +8 -0
  181. package/lib/presets/crypto.d.ts.map +1 -0
  182. package/lib/presets/crypto.js +9 -0
  183. package/lib/presets/crypto.js.map +1 -0
  184. package/lib/pricing/product-discount.js +2 -0
  185. package/lib/pricing/product-discount.js.map +1 -1
  186. package/lib/warehousing/eth-minter.js +2 -2
  187. package/lib/warehousing/eth-minter.js.map +1 -1
  188. package/lib/worker/BaseWorker.d.ts.map +1 -1
  189. package/lib/worker/BaseWorker.js +1 -3
  190. package/lib/worker/BaseWorker.js.map +1 -1
  191. package/lib/worker/error-notifications.js +1 -1
  192. package/lib/worker/error-notifications.js.map +1 -1
  193. package/lib/worker/zombie-killer.js +4 -1
  194. package/lib/worker/zombie-killer.js.map +1 -1
  195. package/package.json +41 -37
  196. package/src/files/gridfs/{gridfs-adapter.ts → adapter.ts} +1 -3
  197. package/src/files/gridfs/{gridfs-webhook.ts → handler-express.ts} +5 -3
  198. package/src/files/gridfs/handler-fastify.ts +122 -0
  199. package/src/files/gridfs/index.ts +4 -29
  200. package/src/files/gridfs/module.ts +39 -0
  201. package/src/files/minio/{minio-webhook.ts → handler-express.ts} +3 -1
  202. package/src/files/minio/handler-fastify.ts +44 -0
  203. package/src/filters/local-search.ts +3 -25
  204. package/src/payment/apple-iap/adapter.ts +6 -193
  205. package/src/payment/apple-iap/fix-periods.ts +34 -0
  206. package/src/payment/apple-iap/handler-express.ts +134 -0
  207. package/src/payment/apple-iap/handler-fastify.ts +137 -0
  208. package/src/payment/apple-iap/index.ts +5 -1
  209. package/src/payment/apple-iap/module.ts +29 -0
  210. package/src/payment/apple-iap/verify-receipt.ts +27 -0
  211. package/src/payment/cryptopay/{middleware.ts → handler-express.ts} +5 -5
  212. package/src/payment/cryptopay/handler-fastify.ts +89 -0
  213. package/src/payment/cryptopay/index.ts +5 -4
  214. package/src/payment/cryptopay/{module/configureCryptopayModule.ts → module.ts} +38 -39
  215. package/src/payment/cryptopay/plugin.ts +3 -3
  216. package/src/payment/datatrans-v2/{middleware.ts → handler-express.ts} +1 -1
  217. package/src/payment/datatrans-v2/handler-fastify.ts +88 -0
  218. package/src/payment/datatrans-v2/index.ts +0 -2
  219. package/src/payment/paypal-checkout.ts +2 -2
  220. package/src/payment/payrexx/{middleware.ts → handler-express.ts} +1 -1
  221. package/src/payment/payrexx/handler-fastify.ts +105 -0
  222. package/src/payment/payrexx/index.ts +0 -2
  223. package/src/payment/postfinance-checkout/handler-fastify.ts +52 -0
  224. package/src/payment/postfinance-checkout/index.ts +0 -2
  225. package/src/payment/saferpay/adapter.ts +2 -4
  226. package/src/payment/saferpay/{middleware.ts → handler-express.ts} +3 -3
  227. package/src/payment/saferpay/handler-fastify.ts +75 -0
  228. package/src/payment/saferpay/index.ts +5 -2
  229. package/src/payment/saferpay/{module/configureSaferpayTransactionsModule.ts → module.ts} +11 -3
  230. package/src/payment/stripe/{middleware.ts → handler-express.ts} +1 -1
  231. package/src/payment/stripe/handler-fastify.ts +139 -0
  232. package/src/payment/stripe/index.ts +0 -2
  233. package/src/presets/all-express.ts +51 -0
  234. package/src/presets/all-fastify.ts +87 -0
  235. package/src/presets/all.ts +35 -0
  236. package/src/presets/base-express.ts +2 -2
  237. package/src/presets/base-fastify.ts +20 -0
  238. package/src/presets/{base-modules.ts → base.ts} +3 -17
  239. package/src/presets/crypto-express.ts +2 -2
  240. package/src/presets/crypto-fastify.ts +15 -0
  241. package/src/presets/crypto.ts +11 -0
  242. package/src/pricing/product-discount.ts +2 -0
  243. package/src/warehousing/eth-minter.ts +2 -2
  244. package/src/worker/BaseWorker.ts +1 -4
  245. package/src/worker/error-notifications.ts +1 -1
  246. package/src/worker/zombie-killer.ts +4 -4
  247. package/lib/files/gridfs/gridfs-adapter.d.ts.map +0 -1
  248. package/lib/files/gridfs/gridfs-adapter.js.map +0 -1
  249. package/lib/files/gridfs/gridfs-webhook.d.ts +0 -11
  250. package/lib/files/gridfs/gridfs-webhook.d.ts.map +0 -1
  251. package/lib/files/gridfs/gridfs-webhook.js.map +0 -1
  252. package/lib/files/minio/minio-adapter.d.ts.map +0 -1
  253. package/lib/files/minio/minio-adapter.js.map +0 -1
  254. package/lib/files/minio/minio-webhook.d.ts +0 -2
  255. package/lib/files/minio/minio-webhook.d.ts.map +0 -1
  256. package/lib/files/minio/minio-webhook.js.map +0 -1
  257. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts +0 -9
  258. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts.map +0 -1
  259. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js.map +0 -1
  260. package/lib/payment/cryptopay/middleware.d.ts +0 -2
  261. package/lib/payment/cryptopay/middleware.d.ts.map +0 -1
  262. package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts +0 -25
  263. package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts.map +0 -1
  264. package/lib/payment/cryptopay/module/configureCryptopayModule.js.map +0 -1
  265. package/lib/payment/datatrans-v2/middleware.d.ts.map +0 -1
  266. package/lib/payment/datatrans-v2/middleware.js.map +0 -1
  267. package/lib/payment/payrexx/middleware.d.ts.map +0 -1
  268. package/lib/payment/payrexx/middleware.js.map +0 -1
  269. package/lib/payment/postfinance-checkout/middleware.d.ts.map +0 -1
  270. package/lib/payment/postfinance-checkout/middleware.js.map +0 -1
  271. package/lib/payment/saferpay/middleware.d.ts.map +0 -1
  272. package/lib/payment/saferpay/middleware.js.map +0 -1
  273. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts +0 -10
  274. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts.map +0 -1
  275. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js.map +0 -1
  276. package/lib/payment/stripe/middleware.d.ts.map +0 -1
  277. package/lib/payment/stripe/middleware.js.map +0 -1
  278. package/lib/plugins-index.d.ts +0 -18
  279. package/lib/plugins-index.d.ts.map +0 -1
  280. package/lib/plugins-index.js +0 -52
  281. package/lib/plugins-index.js.map +0 -1
  282. package/lib/presets/base-modules.d.ts.map +0 -1
  283. package/lib/presets/base-modules.js.map +0 -1
  284. package/lib/presets/crypto-modules.d.ts +0 -11
  285. package/lib/presets/crypto-modules.d.ts.map +0 -1
  286. package/lib/presets/crypto-modules.js +0 -14
  287. package/lib/presets/crypto-modules.js.map +0 -1
  288. package/src/payment/apple-iap/module/configureAppleTransactionsModule.ts +0 -25
  289. package/src/plugins-index.ts +0 -90
  290. package/src/presets/crypto-modules.ts +0 -23
  291. /package/src/files/minio/{minio-adapter.ts → index.ts} +0 -0
  292. /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 { UnchainedCore } from '@unchainedshop/core';
6
- import { AppleTransactionsModule } from './module/configureAppleTransactionsModule.js';
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, APPLE_IAP_ENVIRONMENT = 'sandbox' } = process.env;
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
- export * from './module/configureAppleTransactionsModule.js';
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/configureCryptopayModule.js';
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
- export const cryptopayHandler = async (req, res) => {
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;