@unchainedshop/plugins 4.8.26 → 4.8.27

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 (243) hide show
  1. package/lib/delivery/post/adapter.d.ts +2 -0
  2. package/lib/delivery/post/adapter.js +22 -0
  3. package/lib/delivery/post/index.d.ts +4 -0
  4. package/lib/delivery/post/index.js +10 -0
  5. package/lib/delivery/send-message/adapter.d.ts +2 -0
  6. package/lib/delivery/send-message/adapter.js +39 -0
  7. package/lib/delivery/send-message/index.d.ts +4 -0
  8. package/lib/delivery/send-message/index.js +10 -0
  9. package/lib/delivery/stores/adapter.d.ts +2 -0
  10. package/lib/delivery/stores/adapter.js +42 -0
  11. package/lib/delivery/stores/index.d.ts +4 -0
  12. package/lib/delivery/stores/index.js +10 -0
  13. package/lib/enrollments/licensed/adapter.d.ts +6 -0
  14. package/lib/enrollments/licensed/adapter.js +51 -0
  15. package/lib/enrollments/licensed/index.d.ts +4 -0
  16. package/lib/enrollments/licensed/index.js +10 -0
  17. package/lib/files/gridfs/api.d.ts +7 -0
  18. package/lib/files/gridfs/api.js +163 -0
  19. package/lib/files/minio/adapter.d.ts +4 -0
  20. package/lib/files/minio/adapter.js +160 -0
  21. package/lib/files/minio/api.d.ts +2 -0
  22. package/lib/files/minio/api.js +40 -0
  23. package/lib/files/temp-upload/api.d.ts +8 -0
  24. package/lib/files/temp-upload/api.js +48 -0
  25. package/lib/files/temp-upload/index.d.ts +3 -0
  26. package/lib/files/temp-upload/index.js +15 -0
  27. package/lib/filters/local-search/adapter.d.ts +2 -0
  28. package/lib/filters/local-search/adapter.js +56 -0
  29. package/lib/filters/local-search/index.d.ts +4 -0
  30. package/lib/filters/local-search/index.js +10 -0
  31. package/lib/filters/strict-equal/adapter.d.ts +2 -0
  32. package/lib/filters/strict-equal/adapter.js +23 -0
  33. package/lib/filters/strict-equal/index.d.ts +4 -0
  34. package/lib/filters/strict-equal/index.js +10 -0
  35. package/lib/payment/apple-iap/api.d.ts +2 -0
  36. package/lib/payment/apple-iap/api.js +119 -0
  37. package/lib/payment/cryptopay/adapter.d.ts +2 -0
  38. package/lib/payment/cryptopay/adapter.js +157 -0
  39. package/lib/payment/cryptopay/api.d.ts +2 -0
  40. package/lib/payment/cryptopay/api.js +23 -0
  41. package/lib/payment/datatrans-v2/adapter.d.ts +2 -0
  42. package/lib/payment/datatrans-v2/adapter.js +417 -0
  43. package/lib/payment/datatrans-v2/api.d.ts +2 -0
  44. package/lib/payment/datatrans-v2/api.js +108 -0
  45. package/lib/payment/invoice/adapter.d.ts +2 -0
  46. package/lib/payment/invoice/adapter.js +26 -0
  47. package/lib/payment/invoice/index.d.ts +4 -0
  48. package/lib/payment/invoice/index.js +10 -0
  49. package/lib/payment/invoice-prepaid/adapter.d.ts +2 -0
  50. package/lib/payment/invoice-prepaid/adapter.js +29 -0
  51. package/lib/payment/invoice-prepaid/index.d.ts +4 -0
  52. package/lib/payment/invoice-prepaid/index.js +10 -0
  53. package/lib/payment/payrexx/adapter.d.ts +2 -0
  54. package/lib/payment/payrexx/adapter.js +161 -0
  55. package/lib/payment/payrexx/api.d.ts +2 -0
  56. package/lib/payment/payrexx/api.js +97 -0
  57. package/lib/payment/postfinance-checkout/adapter.d.ts +2 -0
  58. package/lib/payment/postfinance-checkout/adapter.js +189 -0
  59. package/lib/payment/postfinance-checkout/webhook.d.ts +2 -0
  60. package/lib/payment/postfinance-checkout/webhook.js +48 -0
  61. package/lib/payment/saferpay/webhook.d.ts +2 -0
  62. package/lib/payment/saferpay/webhook.js +64 -0
  63. package/lib/payment/stripe/adapter.d.ts +2 -0
  64. package/lib/payment/stripe/adapter.js +121 -0
  65. package/lib/payment/stripe/api.d.ts +6 -0
  66. package/lib/payment/stripe/api.js +165 -0
  67. package/lib/pricing/delivery-eu-tax/adapter.d.ts +3 -0
  68. package/lib/pricing/delivery-eu-tax/adapter.js +55 -0
  69. package/lib/pricing/delivery-eu-tax/index.d.ts +4 -0
  70. package/lib/pricing/delivery-eu-tax/index.js +10 -0
  71. package/lib/pricing/delivery-swiss-tax/adapter.d.ts +3 -0
  72. package/lib/pricing/delivery-swiss-tax/adapter.js +43 -0
  73. package/lib/pricing/delivery-swiss-tax/index.d.ts +4 -0
  74. package/lib/pricing/delivery-swiss-tax/index.js +10 -0
  75. package/lib/pricing/delivery-uk-tax/adapter.d.ts +3 -0
  76. package/lib/pricing/delivery-uk-tax/adapter.js +43 -0
  77. package/lib/pricing/delivery-uk-tax/index.d.ts +4 -0
  78. package/lib/pricing/delivery-uk-tax/index.js +10 -0
  79. package/lib/pricing/delivery-us-sales-tax/adapter.d.ts +3 -0
  80. package/lib/pricing/delivery-us-sales-tax/adapter.js +58 -0
  81. package/lib/pricing/delivery-us-sales-tax/index.d.ts +4 -0
  82. package/lib/pricing/delivery-us-sales-tax/index.js +10 -0
  83. package/lib/pricing/discount-100-off/adapter.d.ts +3 -0
  84. package/lib/pricing/discount-100-off/adapter.js +30 -0
  85. package/lib/pricing/discount-100-off/index.d.ts +4 -0
  86. package/lib/pricing/discount-100-off/index.js +10 -0
  87. package/lib/pricing/discount-half-price-manual/adapter.d.ts +3 -0
  88. package/lib/pricing/discount-half-price-manual/adapter.js +30 -0
  89. package/lib/pricing/discount-half-price-manual/index.d.ts +4 -0
  90. package/lib/pricing/discount-half-price-manual/index.js +10 -0
  91. package/lib/pricing/free-delivery/adapter.d.ts +3 -0
  92. package/lib/pricing/free-delivery/adapter.js +27 -0
  93. package/lib/pricing/free-delivery/index.d.ts +4 -0
  94. package/lib/pricing/free-delivery/index.js +10 -0
  95. package/lib/pricing/free-payment/adapter.d.ts +3 -0
  96. package/lib/pricing/free-payment/adapter.js +27 -0
  97. package/lib/pricing/free-payment/index.d.ts +4 -0
  98. package/lib/pricing/free-payment/index.js +10 -0
  99. package/lib/pricing/order-delivery/adapter.d.ts +3 -0
  100. package/lib/pricing/order-delivery/adapter.js +33 -0
  101. package/lib/pricing/order-delivery/index.d.ts +4 -0
  102. package/lib/pricing/order-delivery/index.js +10 -0
  103. package/lib/pricing/order-discount/adapter.d.ts +3 -0
  104. package/lib/pricing/order-discount/adapter.js +74 -0
  105. package/lib/pricing/order-discount/index.d.ts +4 -0
  106. package/lib/pricing/order-discount/index.js +10 -0
  107. package/lib/pricing/order-items/adapter.d.ts +3 -0
  108. package/lib/pricing/order-items/adapter.js +43 -0
  109. package/lib/pricing/order-items/index.d.ts +4 -0
  110. package/lib/pricing/order-items/index.js +10 -0
  111. package/lib/pricing/order-payment/adapter.d.ts +3 -0
  112. package/lib/pricing/order-payment/adapter.js +33 -0
  113. package/lib/pricing/order-payment/index.d.ts +4 -0
  114. package/lib/pricing/order-payment/index.js +10 -0
  115. package/lib/pricing/product-catalog-price/adapter.d.ts +3 -0
  116. package/lib/pricing/product-catalog-price/adapter.js +60 -0
  117. package/lib/pricing/product-catalog-price/index.d.ts +4 -0
  118. package/lib/pricing/product-catalog-price/index.js +10 -0
  119. package/lib/pricing/product-discount/adapter.d.ts +3 -0
  120. package/lib/pricing/product-discount/adapter.js +69 -0
  121. package/lib/pricing/product-discount/index.d.ts +4 -0
  122. package/lib/pricing/product-discount/index.js +10 -0
  123. package/lib/pricing/product-eu-tax/adapter.d.ts +3 -0
  124. package/lib/pricing/product-eu-tax/adapter.js +56 -0
  125. package/lib/pricing/product-eu-tax/index.d.ts +4 -0
  126. package/lib/pricing/product-eu-tax/index.js +10 -0
  127. package/lib/pricing/product-price-rateconversion/adapter.d.ts +3 -0
  128. package/lib/pricing/product-price-rateconversion/adapter.js +53 -0
  129. package/lib/pricing/product-price-rateconversion/index.d.ts +4 -0
  130. package/lib/pricing/product-price-rateconversion/index.js +10 -0
  131. package/lib/pricing/product-quotation-price.d.ts +2 -0
  132. package/lib/pricing/product-quotation-price.js +40 -0
  133. package/lib/pricing/product-swiss-tax/adapter.d.ts +3 -0
  134. package/lib/pricing/product-swiss-tax/adapter.js +57 -0
  135. package/lib/pricing/product-swiss-tax/index.d.ts +4 -0
  136. package/lib/pricing/product-swiss-tax/index.js +10 -0
  137. package/lib/pricing/product-uk-tax/adapter.d.ts +3 -0
  138. package/lib/pricing/product-uk-tax/adapter.js +57 -0
  139. package/lib/pricing/product-uk-tax/index.d.ts +4 -0
  140. package/lib/pricing/product-uk-tax/index.js +10 -0
  141. package/lib/pricing/product-us-sales-tax/adapter.d.ts +3 -0
  142. package/lib/pricing/product-us-sales-tax/adapter.js +52 -0
  143. package/lib/pricing/product-us-sales-tax/index.d.ts +4 -0
  144. package/lib/pricing/product-us-sales-tax/index.js +10 -0
  145. package/lib/quotations/manual/adapter.d.ts +2 -0
  146. package/lib/quotations/manual/adapter.js +24 -0
  147. package/lib/quotations/manual/index.d.ts +4 -0
  148. package/lib/quotations/manual/index.js +10 -0
  149. package/lib/warehousing/erc-metadata/api.d.ts +12 -0
  150. package/lib/warehousing/erc-metadata/api.js +43 -0
  151. package/lib/warehousing/erc-metadata/index.d.ts +3 -0
  152. package/lib/warehousing/erc-metadata/index.js +15 -0
  153. package/lib/warehousing/eth-minter/adapter.d.ts +2 -0
  154. package/lib/warehousing/eth-minter/adapter.js +119 -0
  155. package/lib/warehousing/eth-minter/index.d.ts +4 -0
  156. package/lib/warehousing/eth-minter/index.js +10 -0
  157. package/lib/warehousing/store/adapter.d.ts +2 -0
  158. package/lib/warehousing/store/adapter.js +33 -0
  159. package/lib/warehousing/store/index.d.ts +4 -0
  160. package/lib/warehousing/store/index.js +10 -0
  161. package/lib/worker/budgetsms/adapter.d.ts +22 -0
  162. package/lib/worker/budgetsms/adapter.js +169 -0
  163. package/lib/worker/budgetsms/index.d.ts +4 -0
  164. package/lib/worker/budgetsms/index.js +10 -0
  165. package/lib/worker/bulk-export/adapter.d.ts +3 -0
  166. package/lib/worker/bulk-export/adapter.js +64 -0
  167. package/lib/worker/bulk-export/index.d.ts +4 -0
  168. package/lib/worker/bulk-export/index.js +10 -0
  169. package/lib/worker/bulk-import/adapter.d.ts +3 -0
  170. package/lib/worker/bulk-import/adapter.js +65 -0
  171. package/lib/worker/bulk-import/api.d.ts +9 -0
  172. package/lib/worker/bulk-import/api.js +52 -0
  173. package/lib/worker/bulk-import/index.d.ts +4 -0
  174. package/lib/worker/bulk-import/index.js +18 -0
  175. package/lib/worker/bulkgate/adapter.d.ts +12 -0
  176. package/lib/worker/bulkgate/adapter.js +91 -0
  177. package/lib/worker/bulkgate/index.d.ts +4 -0
  178. package/lib/worker/bulkgate/index.js +10 -0
  179. package/lib/worker/email/adapter.d.ts +9 -0
  180. package/lib/worker/email/adapter.js +150 -0
  181. package/lib/worker/email/index.d.ts +4 -0
  182. package/lib/worker/email/index.js +10 -0
  183. package/lib/worker/enrollment-order-generator/adapter.d.ts +4 -0
  184. package/lib/worker/enrollment-order-generator/adapter.js +77 -0
  185. package/lib/worker/enrollment-order-generator/index.d.ts +4 -0
  186. package/lib/worker/enrollment-order-generator/index.js +13 -0
  187. package/lib/worker/error-notifications/adapter.d.ts +10 -0
  188. package/lib/worker/error-notifications/adapter.js +62 -0
  189. package/lib/worker/error-notifications/index.d.ts +4 -0
  190. package/lib/worker/error-notifications/index.js +13 -0
  191. package/lib/worker/export-token/adapter.d.ts +4 -0
  192. package/lib/worker/export-token/adapter.js +25 -0
  193. package/lib/worker/export-token/index.d.ts +4 -0
  194. package/lib/worker/export-token/index.js +13 -0
  195. package/lib/worker/external/adapter.d.ts +3 -0
  196. package/lib/worker/external/adapter.js +13 -0
  197. package/lib/worker/external/index.d.ts +4 -0
  198. package/lib/worker/external/index.js +10 -0
  199. package/lib/worker/gc-guests/adapter.d.ts +9 -0
  200. package/lib/worker/gc-guests/adapter.js +56 -0
  201. package/lib/worker/gc-guests/index.d.ts +4 -0
  202. package/lib/worker/gc-guests/index.js +13 -0
  203. package/lib/worker/heartbeat/adapter.d.ts +8 -0
  204. package/lib/worker/heartbeat/adapter.js +26 -0
  205. package/lib/worker/heartbeat/index.d.ts +4 -0
  206. package/lib/worker/heartbeat/index.js +10 -0
  207. package/lib/worker/http-request/adapter.d.ts +8 -0
  208. package/lib/worker/http-request/adapter.js +55 -0
  209. package/lib/worker/http-request/index.d.ts +4 -0
  210. package/lib/worker/http-request/index.js +10 -0
  211. package/lib/worker/invalidate-carts/adapter.d.ts +9 -0
  212. package/lib/worker/invalidate-carts/adapter.js +52 -0
  213. package/lib/worker/invalidate-carts/index.d.ts +4 -0
  214. package/lib/worker/invalidate-carts/index.js +13 -0
  215. package/lib/worker/message/adapter.d.ts +11 -0
  216. package/lib/worker/message/adapter.js +42 -0
  217. package/lib/worker/message/index.d.ts +4 -0
  218. package/lib/worker/message/index.js +10 -0
  219. package/lib/worker/push-notification/adapter.d.ts +9 -0
  220. package/lib/worker/push-notification/adapter.js +87 -0
  221. package/lib/worker/push-notification/index.d.ts +4 -0
  222. package/lib/worker/push-notification/index.js +10 -0
  223. package/lib/worker/twilio/adapter.d.ts +8 -0
  224. package/lib/worker/twilio/adapter.js +59 -0
  225. package/lib/worker/twilio/index.d.ts +4 -0
  226. package/lib/worker/twilio/index.js +10 -0
  227. package/lib/worker/update-coinbase-rates/adapter.d.ts +4 -0
  228. package/lib/worker/update-coinbase-rates/adapter.js +59 -0
  229. package/lib/worker/update-coinbase-rates/index.d.ts +4 -0
  230. package/lib/worker/update-coinbase-rates/index.js +13 -0
  231. package/lib/worker/update-ecb-rates/adapter.d.ts +4 -0
  232. package/lib/worker/update-ecb-rates/adapter.js +94 -0
  233. package/lib/worker/update-ecb-rates/index.d.ts +4 -0
  234. package/lib/worker/update-ecb-rates/index.js +13 -0
  235. package/lib/worker/update-token-ownership/adapter.d.ts +5 -0
  236. package/lib/worker/update-token-ownership/adapter.js +58 -0
  237. package/lib/worker/update-token-ownership/index.d.ts +4 -0
  238. package/lib/worker/update-token-ownership/index.js +13 -0
  239. package/lib/worker/zombie-killer/adapter.d.ts +15 -0
  240. package/lib/worker/zombie-killer/adapter.js +113 -0
  241. package/lib/worker/zombie-killer/index.d.ts +4 -0
  242. package/lib/worker/zombie-killer/index.js +13 -0
  243. package/package.json +19 -19
@@ -0,0 +1,121 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { stripe, createOrderPaymentIntent, createRegistrationIntent } from "./stripe.js";
3
+ import { OrderPricingSheet, PaymentAdapter, PaymentError, } from '@unchainedshop/core';
4
+ const logger = createLogger('unchained:stripe');
5
+ export const Stripe = {
6
+ ...PaymentAdapter,
7
+ key: 'shop.unchained.payment.stripe',
8
+ label: 'Stripe',
9
+ version: '2.0.0',
10
+ typeSupported(type) {
11
+ return type === 'GENERIC';
12
+ },
13
+ actions: (config, context) => {
14
+ const { modules } = context;
15
+ const descriptorPrefix = config.find(({ key }) => key === 'descriptorPrefix')?.value || '';
16
+ const assertUserData = async (forcedUserId) => {
17
+ const userId = forcedUserId || context?.userId;
18
+ const user = await modules.users.findUserById(userId);
19
+ if (!user)
20
+ throw new Error('User not found');
21
+ const email = modules.users.primaryEmail(user)?.address;
22
+ const name = user.profile?.displayName || user.username || email;
23
+ return {
24
+ email,
25
+ name,
26
+ userId,
27
+ };
28
+ };
29
+ const adapterActions = {
30
+ ...PaymentAdapter.actions(config, context),
31
+ configurationError() {
32
+ if (!stripe)
33
+ return PaymentError.INCOMPLETE_CONFIGURATION;
34
+ return null;
35
+ },
36
+ isActive: () => {
37
+ if (adapterActions.configurationError() === null)
38
+ return true;
39
+ return false;
40
+ },
41
+ isPayLaterAllowed() {
42
+ return false;
43
+ },
44
+ validate: async ({ token }) => {
45
+ const paymentMethod = await stripe.paymentMethods.retrieve(token);
46
+ return !!paymentMethod;
47
+ },
48
+ register: async ({ setupIntentId }) => {
49
+ if (!setupIntentId) {
50
+ throw new Error('You have to provide a setupIntentId');
51
+ }
52
+ const setupIntent = await stripe.setupIntents.retrieve(setupIntentId);
53
+ if (setupIntent.status === 'succeeded') {
54
+ return {
55
+ token: setupIntent.payment_method,
56
+ customer: setupIntent.customer,
57
+ payment_method_types: setupIntent.payment_method_types,
58
+ usage: setupIntent.usage,
59
+ };
60
+ }
61
+ logger.warn('Registration declined', setupIntentId);
62
+ return null;
63
+ },
64
+ sign: async (transactionContext = {}) => {
65
+ const { orderPayment, order, paymentProvider } = context;
66
+ const { userId, name, email } = await assertUserData(order?.userId);
67
+ if (orderPayment) {
68
+ if (!order)
69
+ throw new Error('order not found in context');
70
+ const pricing = OrderPricingSheet({
71
+ calculation: order?.calculation,
72
+ currencyCode: order?.currencyCode,
73
+ });
74
+ const paymentIntent = await createOrderPaymentIntent({ userId, name, email, order, orderPayment, pricing, descriptorPrefix }, transactionContext);
75
+ return paymentIntent.client_secret;
76
+ }
77
+ const paymentIntent = await createRegistrationIntent({ userId, name, email, paymentProviderId: paymentProvider._id, descriptorPrefix }, transactionContext);
78
+ return paymentIntent.client_secret;
79
+ },
80
+ charge: async ({ paymentIntentId, paymentCredentials }) => {
81
+ if (!paymentIntentId && !paymentCredentials) {
82
+ throw new Error('You have to provide paymentIntentId or paymentCredentials');
83
+ }
84
+ const { order, orderPayment } = context;
85
+ if (!order)
86
+ throw new Error('order not found in context');
87
+ if (!orderPayment)
88
+ throw new Error('orderPayment not found in context');
89
+ const { userId, name, email } = await assertUserData(order?.userId);
90
+ const pricing = OrderPricingSheet({
91
+ calculation: order.calculation,
92
+ currencyCode: order.currencyCode,
93
+ });
94
+ const paymentIntentObject = paymentIntentId
95
+ ? await stripe.paymentIntents.retrieve(paymentIntentId)
96
+ : await createOrderPaymentIntent({ userId, name, email, orderPayment, order, pricing, descriptorPrefix }, {
97
+ customer: paymentCredentials.meta?.customer,
98
+ confirm: true,
99
+ payment_method: paymentCredentials.token,
100
+ payment_method_types: paymentCredentials.meta?.payment_method_types,
101
+ });
102
+ const { currencyCode, amount } = pricing.total({ useNetPrice: false });
103
+ if (paymentIntentObject.currency !== currencyCode.toLowerCase() ||
104
+ paymentIntentObject.amount !== Math.round(amount)) {
105
+ throw new Error('The price has changed since the intent has been created');
106
+ }
107
+ if (paymentIntentObject.metadata?.orderPaymentId !== orderPayment?._id) {
108
+ throw new Error('The order payment is different from the initiating intent');
109
+ }
110
+ if (paymentIntentObject.status === 'succeeded') {
111
+ return paymentIntentObject;
112
+ }
113
+ logger.info('Charge postponed because paymentIntent has wrong status', {
114
+ orderPaymentId: paymentIntentObject.id,
115
+ });
116
+ return false;
117
+ },
118
+ };
119
+ return adapterActions;
120
+ },
121
+ };
@@ -0,0 +1,6 @@
1
+ import type { UnchainedCore } from '@unchainedshop/core';
2
+ export declare const WebhookEventTypes: {
3
+ PAYMENT_INTENT_SUCCEEDED: string;
4
+ SETUP_INTENT_SUCCEEDED: string;
5
+ };
6
+ export declare function stripeWebhookHandler(request: Request, context: UnchainedCore): Promise<Response>;
@@ -0,0 +1,165 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { stripe } from "./stripe.js";
3
+ const logger = createLogger('unchained:stripe:handler');
4
+ export const WebhookEventTypes = {
5
+ PAYMENT_INTENT_SUCCEEDED: 'payment_intent.succeeded',
6
+ SETUP_INTENT_SUCCEEDED: 'setup_intent.succeeded',
7
+ };
8
+ export async function stripeWebhookHandler(request, context) {
9
+ try {
10
+ const { modules, services } = context;
11
+ const sig = request.headers.get('stripe-signature');
12
+ if (!sig) {
13
+ logger.error('stripe-signature header was not provided for webhook');
14
+ return new Response(JSON.stringify({
15
+ success: false,
16
+ message: 'stripe-signature header was not provided for webhook',
17
+ name: 'MISSING_SIGNATURE',
18
+ }), {
19
+ status: 400,
20
+ headers: { 'Content-Type': 'application/json' },
21
+ });
22
+ }
23
+ if (!process.env.STRIPE_ENDPOINT_SECRET) {
24
+ logger.error('env STRIPE_ENDPOINT_SECRET is required for webhook handling');
25
+ return new Response(JSON.stringify({
26
+ success: false,
27
+ message: 'env STRIPE_ENDPOINT_SECRET is required for webhook handling',
28
+ name: 'MISSING_ENDPOINT_SECRET',
29
+ }), {
30
+ status: 500,
31
+ headers: { 'Content-Type': 'application/json' },
32
+ });
33
+ }
34
+ const rawBody = await request.text();
35
+ let event;
36
+ try {
37
+ event = stripe.webhooks.constructEvent(rawBody, sig, process.env.STRIPE_ENDPOINT_SECRET);
38
+ }
39
+ catch (err) {
40
+ logger.error(`Error constructing event: ${err.message}`);
41
+ return new Response(JSON.stringify({
42
+ success: false,
43
+ message: err.message,
44
+ name: err.name || 'SIGNATURE_VERIFICATION_FAILED',
45
+ }), {
46
+ status: 400,
47
+ headers: { 'Content-Type': 'application/json' },
48
+ });
49
+ }
50
+ if (!Object.values(WebhookEventTypes).includes(event.type)) {
51
+ logger.info(`unhandled event type`, {
52
+ type: event.type,
53
+ });
54
+ return new Response(JSON.stringify({
55
+ success: false,
56
+ ignored: true,
57
+ name: 'UNHANDLED_EVENT_TYPE',
58
+ message: `Unhandled event type: ${event.type}. Supported types: ${Object.values(WebhookEventTypes).join(', ')}`,
59
+ }), {
60
+ status: 200,
61
+ headers: { 'Content-Type': 'application/json' },
62
+ });
63
+ }
64
+ const environmentInMetadata = event.data?.object?.metadata?.environment || '';
65
+ const environmentInEnv = process.env.STRIPE_WEBHOOK_ENVIRONMENT || '';
66
+ if (environmentInMetadata !== environmentInEnv) {
67
+ logger.info(`unhandled event environment`, {
68
+ type: event.type,
69
+ environment: environmentInMetadata,
70
+ });
71
+ return new Response(JSON.stringify({
72
+ success: false,
73
+ ignored: true,
74
+ name: 'UNHANDLED_EVENT_ENVIRONMENT',
75
+ message: `Unhandled event environment: ${environmentInMetadata}. Supported environment: ${environmentInEnv}`,
76
+ }), {
77
+ status: 200,
78
+ headers: { 'Content-Type': 'application/json' },
79
+ });
80
+ }
81
+ logger.info(`Processing event`, {
82
+ type: event.type,
83
+ });
84
+ if (event.type === WebhookEventTypes.PAYMENT_INTENT_SUCCEEDED) {
85
+ const paymentIntent = event.data.object;
86
+ const { orderPaymentId } = paymentIntent.metadata || {};
87
+ logger.info(`checkout with orderPaymentId: ${orderPaymentId}`, {
88
+ type: event.type,
89
+ });
90
+ await modules.orders.payments.logEvent(orderPaymentId, event);
91
+ const orderPayment = await modules.orders.payments.findOrderPayment({
92
+ orderPaymentId,
93
+ });
94
+ if (!orderPayment) {
95
+ throw new Error(`order payment not found with orderPaymentId: ${orderPaymentId}`);
96
+ }
97
+ const order = await services.orders.checkoutOrder(orderPayment.orderId, {
98
+ paymentContext: {
99
+ paymentIntentId: paymentIntent.id,
100
+ },
101
+ });
102
+ if (!order)
103
+ throw new Error(`Order with id ${orderPayment.orderId} not found`);
104
+ logger.info(`checkout successful`, {
105
+ orderPaymentId,
106
+ orderId: order._id,
107
+ type: event.type,
108
+ });
109
+ return new Response(JSON.stringify({
110
+ success: true,
111
+ message: 'checkout successful',
112
+ orderId: order._id,
113
+ }), {
114
+ status: 200,
115
+ headers: { 'Content-Type': 'application/json' },
116
+ });
117
+ }
118
+ if (event.type === WebhookEventTypes.SETUP_INTENT_SUCCEEDED) {
119
+ const setupIntent = event.data.object;
120
+ const { paymentProviderId, userId } = setupIntent.metadata || {};
121
+ logger.info(`registered payment credential with paymentProviderId: ${paymentProviderId}`, {
122
+ type: event.type,
123
+ userId,
124
+ });
125
+ const paymentCredentials = await services.orders.registerPaymentCredentials(paymentProviderId, {
126
+ transactionContext: {
127
+ setupIntentId: setupIntent.id,
128
+ },
129
+ userId,
130
+ });
131
+ logger.info(`payment credentials registration successful`, {
132
+ userId,
133
+ paymentProviderId,
134
+ paymentCredentialsId: paymentCredentials?._id,
135
+ type: event.type,
136
+ });
137
+ return new Response(JSON.stringify({
138
+ success: true,
139
+ message: 'payment credentials registration successful',
140
+ paymentCredentialsId: paymentCredentials?._id,
141
+ }), {
142
+ status: 200,
143
+ headers: { 'Content-Type': 'application/json' },
144
+ });
145
+ }
146
+ return new Response(JSON.stringify({
147
+ success: false,
148
+ message: 'Unhandled event type',
149
+ }), {
150
+ status: 200,
151
+ headers: { 'Content-Type': 'application/json' },
152
+ });
153
+ }
154
+ catch (error) {
155
+ logger.error(error);
156
+ return new Response(JSON.stringify({
157
+ success: false,
158
+ message: error.message,
159
+ name: error.name,
160
+ }), {
161
+ status: 500,
162
+ headers: { 'Content-Type': 'application/json' },
163
+ });
164
+ }
165
+ }
@@ -0,0 +1,3 @@
1
+ import { type IDeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export declare const DeliveryEuTax: IDeliveryPricingAdapter;
3
+ export default DeliveryEuTax;
@@ -0,0 +1,55 @@
1
+ import { DeliveryPricingRowCategory, DeliveryPricingAdapter, } from '@unchainedshop/core';
2
+ import { isEuMemberCountry, resolveEuTaxCategoryFromDeliveryProvider, resolveEuTaxRate, } from "../tax/eu.js";
3
+ import resolveDeliveryLocation from "../utils/resolveDeliveryLocation.js";
4
+ import { applyTaxRateToTaxableRows } from "../tax/applyTaxRateToTaxableRows.js";
5
+ export const DeliveryEuTax = {
6
+ ...DeliveryPricingAdapter,
7
+ key: 'shop.unchained.pricing.delivery-eu-tax',
8
+ version: '1.0.0',
9
+ label: 'Apply EU VAT on Delivery Fees',
10
+ orderIndex: 80,
11
+ isActivatedFor: (context) => {
12
+ if (!context.order)
13
+ return false;
14
+ if (!context.orderDelivery)
15
+ return false;
16
+ const { countryCode } = resolveDeliveryLocation({
17
+ order: context.order,
18
+ orderDelivery: context.orderDelivery,
19
+ countryCode: context.countryCode,
20
+ });
21
+ return isEuMemberCountry(countryCode);
22
+ },
23
+ actions: (params) => {
24
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
25
+ const { context } = params;
26
+ return {
27
+ ...pricingAdapter,
28
+ calculate: async () => {
29
+ const { countryCode } = resolveDeliveryLocation({
30
+ order: context.order,
31
+ orderDelivery: context.orderDelivery,
32
+ countryCode: context.countryCode,
33
+ });
34
+ const category = resolveEuTaxCategoryFromDeliveryProvider(context.provider);
35
+ const taxRate = resolveEuTaxRate({
36
+ countryCode,
37
+ category,
38
+ referenceDate: context.order?.ordered,
39
+ });
40
+ if (taxRate === null)
41
+ return pricingAdapter.calculate();
42
+ DeliveryPricingAdapter.log(`DeliveryEuTax -> Tax Multiplicator: ${taxRate}`);
43
+ applyTaxRateToTaxableRows({
44
+ calculationSheet: params.calculationSheet,
45
+ resultSheet: pricingAdapter.resultSheet(),
46
+ taxRate,
47
+ baseCategory: DeliveryPricingRowCategory.Delivery,
48
+ adapterKey: DeliveryEuTax.key,
49
+ });
50
+ return pricingAdapter.calculate();
51
+ },
52
+ };
53
+ },
54
+ };
55
+ export default DeliveryEuTax;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const DeliveryEuTaxPlugin: IPlugin;
3
+ export default DeliveryEuTaxPlugin;
4
+ export { DeliveryEuTax } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { DeliveryEuTax } from "./adapter.js";
3
+ export const DeliveryEuTaxPlugin = {
4
+ key: 'shop.unchained.pricing.delivery-eu-tax',
5
+ label: 'Delivery EU Tax Plugin',
6
+ version: '1.0.0',
7
+ adapters: [DeliveryEuTax],
8
+ };
9
+ export default DeliveryEuTaxPlugin;
10
+ export { DeliveryEuTax } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IDeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export declare const DeliverySwissTax: IDeliveryPricingAdapter;
3
+ export default DeliverySwissTax;
@@ -0,0 +1,43 @@
1
+ import { DeliveryPricingRowCategory, DeliveryPricingAdapter, } from '@unchainedshop/core';
2
+ import { resolveTaxCategoryFromDeliveryProvider, SwissTaxCategories } from "../tax/ch.js";
3
+ import isDeliveryAddressInCountry from "../utils/isDeliveryAddressInCountry.js";
4
+ import { applyTaxRateToTaxableRows } from "../tax/applyTaxRateToTaxableRows.js";
5
+ export const DeliverySwissTax = {
6
+ ...DeliveryPricingAdapter,
7
+ key: 'shop.unchained.pricing.delivery-swiss-tax',
8
+ version: '1.0.0',
9
+ label: 'Apply Swiss Tax on Delivery Fees',
10
+ orderIndex: 80,
11
+ isActivatedFor: (context) => {
12
+ if (!context.order)
13
+ return false;
14
+ if (!context.orderDelivery)
15
+ return false;
16
+ return isDeliveryAddressInCountry({
17
+ order: context.order,
18
+ orderDelivery: context.orderDelivery,
19
+ countryCode: context.countryCode,
20
+ }, ['CH', 'LI']);
21
+ },
22
+ actions: (params) => {
23
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
24
+ const { context } = params;
25
+ return {
26
+ ...pricingAdapter,
27
+ calculate: async () => {
28
+ const taxCategory = resolveTaxCategoryFromDeliveryProvider(context.provider) || SwissTaxCategories.DEFAULT;
29
+ const taxRate = taxCategory.rate(context.order?.ordered);
30
+ DeliveryPricingAdapter.log(`DeliverySwissTax -> Tax Multiplicator: ${taxRate}`);
31
+ applyTaxRateToTaxableRows({
32
+ calculationSheet: params.calculationSheet,
33
+ resultSheet: pricingAdapter.resultSheet(),
34
+ taxRate,
35
+ baseCategory: DeliveryPricingRowCategory.Delivery,
36
+ adapterKey: DeliverySwissTax.key,
37
+ });
38
+ return pricingAdapter.calculate();
39
+ },
40
+ };
41
+ },
42
+ };
43
+ export default DeliverySwissTax;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const DeliverySwissTaxPlugin: IPlugin;
3
+ export default DeliverySwissTaxPlugin;
4
+ export { DeliverySwissTax } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { DeliverySwissTax } from "./adapter.js";
3
+ export const DeliverySwissTaxPlugin = {
4
+ key: 'shop.unchained.pricing.delivery-swiss-tax',
5
+ label: 'Delivery Swiss Tax Plugin',
6
+ version: '1.0.0',
7
+ adapters: [DeliverySwissTax],
8
+ };
9
+ export default DeliverySwissTaxPlugin;
10
+ export { DeliverySwissTax } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IDeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export declare const DeliveryUkTax: IDeliveryPricingAdapter;
3
+ export default DeliveryUkTax;
@@ -0,0 +1,43 @@
1
+ import { DeliveryPricingRowCategory, DeliveryPricingAdapter, } from '@unchainedshop/core';
2
+ import { resolveUkTaxCategoryFromDeliveryProvider, UkTaxCategories, UK_VAT_COUNTRY_CODES, } from "../tax/uk.js";
3
+ import isDeliveryAddressInCountry from "../utils/isDeliveryAddressInCountry.js";
4
+ import { applyTaxRateToTaxableRows } from "../tax/applyTaxRateToTaxableRows.js";
5
+ export const DeliveryUkTax = {
6
+ ...DeliveryPricingAdapter,
7
+ key: 'shop.unchained.pricing.delivery-uk-tax',
8
+ version: '1.0.0',
9
+ label: 'Apply UK VAT on Delivery Fees',
10
+ orderIndex: 80,
11
+ isActivatedFor: (context) => {
12
+ if (!context.order)
13
+ return false;
14
+ if (!context.orderDelivery)
15
+ return false;
16
+ return isDeliveryAddressInCountry({
17
+ order: context.order,
18
+ orderDelivery: context.orderDelivery,
19
+ countryCode: context.countryCode,
20
+ }, UK_VAT_COUNTRY_CODES);
21
+ },
22
+ actions: (params) => {
23
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
24
+ const { context } = params;
25
+ return {
26
+ ...pricingAdapter,
27
+ calculate: async () => {
28
+ const taxCategory = resolveUkTaxCategoryFromDeliveryProvider(context.provider) || UkTaxCategories.STANDARD;
29
+ const taxRate = taxCategory.rate(context.order?.ordered);
30
+ DeliveryPricingAdapter.log(`DeliveryUkTax -> Tax Multiplicator: ${taxRate}`);
31
+ applyTaxRateToTaxableRows({
32
+ calculationSheet: params.calculationSheet,
33
+ resultSheet: pricingAdapter.resultSheet(),
34
+ taxRate,
35
+ baseCategory: DeliveryPricingRowCategory.Delivery,
36
+ adapterKey: DeliveryUkTax.key,
37
+ });
38
+ return pricingAdapter.calculate();
39
+ },
40
+ };
41
+ },
42
+ };
43
+ export default DeliveryUkTax;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const DeliveryUkTaxPlugin: IPlugin;
3
+ export default DeliveryUkTaxPlugin;
4
+ export { DeliveryUkTax } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { DeliveryUkTax } from "./adapter.js";
3
+ export const DeliveryUkTaxPlugin = {
4
+ key: 'shop.unchained.pricing.delivery-uk-tax',
5
+ label: 'Delivery UK Tax Plugin',
6
+ version: '1.0.0',
7
+ adapters: [DeliveryUkTax],
8
+ };
9
+ export default DeliveryUkTaxPlugin;
10
+ export { DeliveryUkTax } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IDeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export declare const DeliveryUsSalesTax: IDeliveryPricingAdapter;
3
+ export default DeliveryUsSalesTax;
@@ -0,0 +1,58 @@
1
+ import { DeliveryPricingRowCategory, DeliveryPricingAdapter, } from '@unchainedshop/core';
2
+ import { US_COUNTRY_CODE, isDeliveryExemptFromUsSalesTax, resolveUsSalesTaxRate } from "../tax/us.js";
3
+ import resolveDeliveryLocation from "../utils/resolveDeliveryLocation.js";
4
+ import { applyTaxRateToTaxableRows } from "../tax/applyTaxRateToTaxableRows.js";
5
+ export const DeliveryUsSalesTax = {
6
+ ...DeliveryPricingAdapter,
7
+ key: 'shop.unchained.pricing.delivery-us-sales-tax',
8
+ version: '1.0.0',
9
+ label: 'Apply US State Sales Tax on Delivery Fees',
10
+ orderIndex: 80,
11
+ isActivatedFor: (context) => {
12
+ if (!context.order)
13
+ return false;
14
+ if (!context.orderDelivery)
15
+ return false;
16
+ const { countryCode } = resolveDeliveryLocation({
17
+ order: context.order,
18
+ orderDelivery: context.orderDelivery,
19
+ countryCode: context.countryCode,
20
+ });
21
+ return countryCode === US_COUNTRY_CODE;
22
+ },
23
+ actions: (params) => {
24
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
25
+ const { context } = params;
26
+ return {
27
+ ...pricingAdapter,
28
+ calculate: async () => {
29
+ if (isDeliveryExemptFromUsSalesTax(context.provider)) {
30
+ return pricingAdapter.calculate();
31
+ }
32
+ const { regionCode } = resolveDeliveryLocation({
33
+ order: context.order,
34
+ orderDelivery: context.orderDelivery,
35
+ countryCode: context.countryCode,
36
+ });
37
+ const taxRate = resolveUsSalesTaxRate({
38
+ regionCode,
39
+ referenceDate: context.order?.ordered,
40
+ });
41
+ if (taxRate === null) {
42
+ DeliveryPricingAdapter.log(`DeliveryUsSalesTax -> unknown state '${regionCode}', no sales tax applied`);
43
+ return pricingAdapter.calculate();
44
+ }
45
+ DeliveryPricingAdapter.log(`DeliveryUsSalesTax -> Tax Multiplicator: ${taxRate}`);
46
+ applyTaxRateToTaxableRows({
47
+ calculationSheet: params.calculationSheet,
48
+ resultSheet: pricingAdapter.resultSheet(),
49
+ taxRate,
50
+ baseCategory: DeliveryPricingRowCategory.Delivery,
51
+ adapterKey: DeliveryUsSalesTax.key,
52
+ });
53
+ return pricingAdapter.calculate();
54
+ },
55
+ };
56
+ },
57
+ };
58
+ export default DeliveryUsSalesTax;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const DeliveryUsSalesTaxPlugin: IPlugin;
3
+ export default DeliveryUsSalesTaxPlugin;
4
+ export { DeliveryUsSalesTax } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { DeliveryUsSalesTax } from "./adapter.js";
3
+ export const DeliveryUsSalesTaxPlugin = {
4
+ key: 'shop.unchained.pricing.delivery-us-sales-tax',
5
+ label: 'Delivery US Sales Tax Plugin',
6
+ version: '1.0.0',
7
+ adapters: [DeliveryUsSalesTax],
8
+ };
9
+ export default DeliveryUsSalesTaxPlugin;
10
+ export { DeliveryUsSalesTax } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type OrderDiscountConfiguration, type IDiscountAdapter } from '@unchainedshop/core';
2
+ export declare const HundredOff: IDiscountAdapter<OrderDiscountConfiguration>;
3
+ export default HundredOff;
@@ -0,0 +1,30 @@
1
+ import { OrderDiscountAdapter, } from '@unchainedshop/core';
2
+ export const HundredOff = {
3
+ ...OrderDiscountAdapter,
4
+ key: 'shop.unchained.discount.100-off',
5
+ label: '100 Off',
6
+ version: '1.0.0',
7
+ orderIndex: 10,
8
+ isManualAdditionAllowed: async () => {
9
+ return true;
10
+ },
11
+ isManualRemovalAllowed: async () => {
12
+ return true;
13
+ },
14
+ actions: async ({ context }) => ({
15
+ ...(await OrderDiscountAdapter.actions({ context })),
16
+ isValidForSystemTriggering: async () => {
17
+ return false;
18
+ },
19
+ isValidForCodeTriggering: async ({ code }) => {
20
+ return code.toUpperCase() === '100OFF';
21
+ },
22
+ discountForPricingAdapterKey: ({ pricingAdapterKey }) => {
23
+ if (pricingAdapterKey === 'shop.unchained.pricing.order-discount') {
24
+ return { fixedRate: 10000 };
25
+ }
26
+ return null;
27
+ },
28
+ }),
29
+ };
30
+ export default HundredOff;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const HundredOffPlugin: IPlugin;
3
+ export default HundredOffPlugin;
4
+ export { HundredOff } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { HundredOff } from "./adapter.js";
3
+ export const HundredOffPlugin = {
4
+ key: 'shop.unchained.discount.100-off',
5
+ label: '100 Off Discount Plugin',
6
+ version: '1.0.0',
7
+ adapters: [HundredOff],
8
+ };
9
+ export default HundredOffPlugin;
10
+ export { HundredOff } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type ProductDiscountConfiguration, type IDiscountAdapter } from '@unchainedshop/core';
2
+ export declare const HalfPriceManual: IDiscountAdapter<ProductDiscountConfiguration>;
3
+ export default HalfPriceManual;