@unchainedshop/plugins 4.6.1 → 4.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) 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 +41 -0
  23. package/lib/files/temp-upload/api.d.ts +6 -0
  24. package/lib/files/temp-upload/api.js +49 -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 +16 -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 +406 -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-swiss-tax/adapter.d.ts +3 -0
  68. package/lib/pricing/delivery-swiss-tax/adapter.js +62 -0
  69. package/lib/pricing/delivery-swiss-tax/index.d.ts +4 -0
  70. package/lib/pricing/delivery-swiss-tax/index.js +10 -0
  71. package/lib/pricing/discount-100-off/adapter.d.ts +3 -0
  72. package/lib/pricing/discount-100-off/adapter.js +30 -0
  73. package/lib/pricing/discount-100-off/index.d.ts +4 -0
  74. package/lib/pricing/discount-100-off/index.js +10 -0
  75. package/lib/pricing/discount-half-price-manual/adapter.d.ts +3 -0
  76. package/lib/pricing/discount-half-price-manual/adapter.js +30 -0
  77. package/lib/pricing/discount-half-price-manual/index.d.ts +4 -0
  78. package/lib/pricing/discount-half-price-manual/index.js +10 -0
  79. package/lib/pricing/free-delivery/adapter.d.ts +3 -0
  80. package/lib/pricing/free-delivery/adapter.js +27 -0
  81. package/lib/pricing/free-delivery/index.d.ts +4 -0
  82. package/lib/pricing/free-delivery/index.js +10 -0
  83. package/lib/pricing/free-payment/adapter.d.ts +3 -0
  84. package/lib/pricing/free-payment/adapter.js +27 -0
  85. package/lib/pricing/free-payment/index.d.ts +4 -0
  86. package/lib/pricing/free-payment/index.js +10 -0
  87. package/lib/pricing/order-delivery/adapter.d.ts +3 -0
  88. package/lib/pricing/order-delivery/adapter.js +33 -0
  89. package/lib/pricing/order-delivery/index.d.ts +4 -0
  90. package/lib/pricing/order-delivery/index.js +10 -0
  91. package/lib/pricing/order-discount/adapter.d.ts +3 -0
  92. package/lib/pricing/order-discount/adapter.js +74 -0
  93. package/lib/pricing/order-discount/index.d.ts +4 -0
  94. package/lib/pricing/order-discount/index.js +10 -0
  95. package/lib/pricing/order-items/adapter.d.ts +3 -0
  96. package/lib/pricing/order-items/adapter.js +43 -0
  97. package/lib/pricing/order-items/index.d.ts +4 -0
  98. package/lib/pricing/order-items/index.js +10 -0
  99. package/lib/pricing/order-payment/adapter.d.ts +3 -0
  100. package/lib/pricing/order-payment/adapter.js +33 -0
  101. package/lib/pricing/order-payment/index.d.ts +4 -0
  102. package/lib/pricing/order-payment/index.js +10 -0
  103. package/lib/pricing/product-catalog-price/adapter.d.ts +3 -0
  104. package/lib/pricing/product-catalog-price/adapter.js +60 -0
  105. package/lib/pricing/product-catalog-price/index.d.ts +4 -0
  106. package/lib/pricing/product-catalog-price/index.js +10 -0
  107. package/lib/pricing/product-discount/adapter.d.ts +3 -0
  108. package/lib/pricing/product-discount/adapter.js +69 -0
  109. package/lib/pricing/product-discount/index.d.ts +4 -0
  110. package/lib/pricing/product-discount/index.js +10 -0
  111. package/lib/pricing/product-price-rateconversion/adapter.d.ts +3 -0
  112. package/lib/pricing/product-price-rateconversion/adapter.js +53 -0
  113. package/lib/pricing/product-price-rateconversion/index.d.ts +4 -0
  114. package/lib/pricing/product-price-rateconversion/index.js +10 -0
  115. package/lib/pricing/product-swiss-tax/adapter.d.ts +3 -0
  116. package/lib/pricing/product-swiss-tax/adapter.js +76 -0
  117. package/lib/pricing/product-swiss-tax/index.d.ts +4 -0
  118. package/lib/pricing/product-swiss-tax/index.js +10 -0
  119. package/lib/quotations/manual/adapter.d.ts +2 -0
  120. package/lib/quotations/manual/adapter.js +19 -0
  121. package/lib/quotations/manual/index.d.ts +4 -0
  122. package/lib/quotations/manual/index.js +10 -0
  123. package/lib/warehousing/erc-metadata/api.d.ts +12 -0
  124. package/lib/warehousing/erc-metadata/api.js +43 -0
  125. package/lib/warehousing/erc-metadata/index.d.ts +3 -0
  126. package/lib/warehousing/erc-metadata/index.js +15 -0
  127. package/lib/warehousing/eth-minter/adapter.d.ts +2 -0
  128. package/lib/warehousing/eth-minter/adapter.js +119 -0
  129. package/lib/warehousing/eth-minter/index.d.ts +4 -0
  130. package/lib/warehousing/eth-minter/index.js +10 -0
  131. package/lib/warehousing/store/adapter.d.ts +2 -0
  132. package/lib/warehousing/store/adapter.js +33 -0
  133. package/lib/warehousing/store/index.d.ts +4 -0
  134. package/lib/warehousing/store/index.js +10 -0
  135. package/lib/worker/budgetsms/adapter.d.ts +22 -0
  136. package/lib/worker/budgetsms/adapter.js +169 -0
  137. package/lib/worker/budgetsms/index.d.ts +4 -0
  138. package/lib/worker/budgetsms/index.js +10 -0
  139. package/lib/worker/bulk-export/adapter.d.ts +3 -0
  140. package/lib/worker/bulk-export/adapter.js +64 -0
  141. package/lib/worker/bulk-export/index.d.ts +4 -0
  142. package/lib/worker/bulk-export/index.js +10 -0
  143. package/lib/worker/bulk-import/adapter.d.ts +3 -0
  144. package/lib/worker/bulk-import/adapter.js +65 -0
  145. package/lib/worker/bulk-import/api.d.ts +7 -0
  146. package/lib/worker/bulk-import/api.js +53 -0
  147. package/lib/worker/bulk-import/index.d.ts +4 -0
  148. package/lib/worker/bulk-import/index.js +18 -0
  149. package/lib/worker/bulkgate/adapter.d.ts +12 -0
  150. package/lib/worker/bulkgate/adapter.js +91 -0
  151. package/lib/worker/bulkgate/index.d.ts +4 -0
  152. package/lib/worker/bulkgate/index.js +10 -0
  153. package/lib/worker/email/adapter.d.ts +9 -0
  154. package/lib/worker/email/adapter.js +150 -0
  155. package/lib/worker/email/index.d.ts +4 -0
  156. package/lib/worker/email/index.js +10 -0
  157. package/lib/worker/enrollment-order-generator/adapter.d.ts +4 -0
  158. package/lib/worker/enrollment-order-generator/adapter.js +77 -0
  159. package/lib/worker/enrollment-order-generator/index.d.ts +4 -0
  160. package/lib/worker/enrollment-order-generator/index.js +13 -0
  161. package/lib/worker/error-notifications/adapter.d.ts +10 -0
  162. package/lib/worker/error-notifications/adapter.js +62 -0
  163. package/lib/worker/error-notifications/index.d.ts +4 -0
  164. package/lib/worker/error-notifications/index.js +13 -0
  165. package/lib/worker/export-token/adapter.d.ts +4 -0
  166. package/lib/worker/export-token/adapter.js +25 -0
  167. package/lib/worker/export-token/index.d.ts +4 -0
  168. package/lib/worker/export-token/index.js +13 -0
  169. package/lib/worker/external/adapter.d.ts +3 -0
  170. package/lib/worker/external/adapter.js +13 -0
  171. package/lib/worker/external/index.d.ts +4 -0
  172. package/lib/worker/external/index.js +10 -0
  173. package/lib/worker/heartbeat/adapter.d.ts +8 -0
  174. package/lib/worker/heartbeat/adapter.js +26 -0
  175. package/lib/worker/heartbeat/index.d.ts +4 -0
  176. package/lib/worker/heartbeat/index.js +10 -0
  177. package/lib/worker/http-request/adapter.d.ts +8 -0
  178. package/lib/worker/http-request/adapter.js +55 -0
  179. package/lib/worker/http-request/index.d.ts +4 -0
  180. package/lib/worker/http-request/index.js +10 -0
  181. package/lib/worker/message/adapter.d.ts +11 -0
  182. package/lib/worker/message/adapter.js +42 -0
  183. package/lib/worker/message/index.d.ts +4 -0
  184. package/lib/worker/message/index.js +10 -0
  185. package/lib/worker/push-notification/adapter.d.ts +9 -0
  186. package/lib/worker/push-notification/adapter.js +87 -0
  187. package/lib/worker/push-notification/index.d.ts +4 -0
  188. package/lib/worker/push-notification/index.js +10 -0
  189. package/lib/worker/twilio/adapter.d.ts +8 -0
  190. package/lib/worker/twilio/adapter.js +59 -0
  191. package/lib/worker/twilio/index.d.ts +4 -0
  192. package/lib/worker/twilio/index.js +10 -0
  193. package/lib/worker/update-coinbase-rates/adapter.d.ts +4 -0
  194. package/lib/worker/update-coinbase-rates/adapter.js +61 -0
  195. package/lib/worker/update-coinbase-rates/index.d.ts +4 -0
  196. package/lib/worker/update-coinbase-rates/index.js +13 -0
  197. package/lib/worker/update-ecb-rates/adapter.d.ts +4 -0
  198. package/lib/worker/update-ecb-rates/adapter.js +94 -0
  199. package/lib/worker/update-ecb-rates/index.d.ts +4 -0
  200. package/lib/worker/update-ecb-rates/index.js +13 -0
  201. package/lib/worker/update-token-ownership/adapter.d.ts +5 -0
  202. package/lib/worker/update-token-ownership/adapter.js +58 -0
  203. package/lib/worker/update-token-ownership/index.d.ts +4 -0
  204. package/lib/worker/update-token-ownership/index.js +13 -0
  205. package/lib/worker/zombie-killer/adapter.d.ts +13 -0
  206. package/lib/worker/zombie-killer/adapter.js +90 -0
  207. package/lib/worker/zombie-killer/index.d.ts +4 -0
  208. package/lib/worker/zombie-killer/index.js +10 -0
  209. package/package.json +1 -1
@@ -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 DeliverySwissTax: IDeliveryPricingAdapter;
3
+ export default DeliverySwissTax;
@@ -0,0 +1,62 @@
1
+ import { DeliveryPricingRowCategory, DeliveryPricingAdapter, } from '@unchainedshop/core';
2
+ import { resolveTaxCategoryFromDeliveryProvider, SwissTaxCategories } from "../tax/ch.js";
3
+ import isDeliveryAddressInCountry from "../utils/isDeliveryAddressInCountry.js";
4
+ export const DeliverySwissTax = {
5
+ ...DeliveryPricingAdapter,
6
+ key: 'shop.unchained.pricing.delivery-swiss-tax',
7
+ version: '1.0.0',
8
+ label: 'Apply Swiss Tax on Delivery Fees',
9
+ orderIndex: 80,
10
+ isActivatedFor: (context) => {
11
+ if (!context.order)
12
+ return false;
13
+ if (!context.orderDelivery)
14
+ return false;
15
+ return isDeliveryAddressInCountry({
16
+ order: context.order,
17
+ orderDelivery: context.orderDelivery,
18
+ countryCode: context.countryCode,
19
+ }, ['CH', 'LI']);
20
+ },
21
+ actions: (params) => {
22
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
23
+ const { context } = params;
24
+ return {
25
+ ...pricingAdapter,
26
+ calculate: async () => {
27
+ const taxCategory = resolveTaxCategoryFromDeliveryProvider(context.provider) || SwissTaxCategories.DEFAULT;
28
+ const taxRate = taxCategory.rate(context.order?.ordered);
29
+ DeliveryPricingAdapter.log(`DeliverySwissTax -> Tax Multiplicator: ${taxRate}`);
30
+ params.calculationSheet.filterBy({ isTaxable: true }).forEach(({ isNetPrice, ...row }) => {
31
+ if (!isNetPrice) {
32
+ const taxAmount = row.amount - row.amount / (1 + taxRate);
33
+ pricingAdapter.resultSheet().calculation.push({
34
+ ...row,
35
+ amount: -taxAmount,
36
+ isTaxable: false,
37
+ isNetPrice: false,
38
+ meta: { adapter: DeliverySwissTax.key },
39
+ });
40
+ pricingAdapter.resultSheet().addTax({
41
+ amount: taxAmount,
42
+ rate: taxRate,
43
+ baseCategory: DeliveryPricingRowCategory.Delivery,
44
+ meta: { adapter: DeliverySwissTax.key },
45
+ });
46
+ }
47
+ else {
48
+ const taxAmount = row.amount * taxRate;
49
+ pricingAdapter.resultSheet().addTax({
50
+ amount: taxAmount,
51
+ rate: taxRate,
52
+ baseCategory: DeliveryPricingRowCategory.Delivery,
53
+ meta: { adapter: DeliverySwissTax.key },
54
+ });
55
+ }
56
+ });
57
+ return pricingAdapter.calculate();
58
+ },
59
+ };
60
+ },
61
+ };
62
+ 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 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;
@@ -0,0 +1,30 @@
1
+ import { OrderDiscountAdapter, } from '@unchainedshop/core';
2
+ export const HalfPriceManual = {
3
+ ...OrderDiscountAdapter,
4
+ key: 'shop.unchained.discount.half-price-manual',
5
+ label: 'Half Price Manual',
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 === 'HALFPRICE';
21
+ },
22
+ discountForPricingAdapterKey({ pricingAdapterKey }) {
23
+ if (pricingAdapterKey === 'shop.unchained.pricing.product-discount') {
24
+ return { rate: 0.5 };
25
+ }
26
+ return null;
27
+ },
28
+ }),
29
+ };
30
+ export default HalfPriceManual;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const HalfPriceManualPlugin: IPlugin;
3
+ export default HalfPriceManualPlugin;
4
+ export { HalfPriceManual } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { HalfPriceManual } from "./adapter.js";
3
+ export const HalfPriceManualPlugin = {
4
+ key: 'shop.unchained.discount.half-price-manual',
5
+ label: 'Half Price Manual Discount Plugin',
6
+ version: '1.0.0',
7
+ adapters: [HalfPriceManual],
8
+ };
9
+ export default HalfPriceManualPlugin;
10
+ export { HalfPriceManual } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IDeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export declare const DeliveryFreePrice: IDeliveryPricingAdapter;
3
+ export default DeliveryFreePrice;
@@ -0,0 +1,27 @@
1
+ import { DeliveryPricingAdapter } from '@unchainedshop/core';
2
+ export const DeliveryFreePrice = {
3
+ ...DeliveryPricingAdapter,
4
+ key: 'shop.unchained.pricing.delivery-free',
5
+ label: 'Free Delivery',
6
+ version: '1.0.0',
7
+ orderIndex: 0,
8
+ isActivatedFor: () => {
9
+ return true;
10
+ },
11
+ actions: (params) => {
12
+ const pricingAdapter = DeliveryPricingAdapter.actions(params);
13
+ return {
14
+ ...pricingAdapter,
15
+ calculate: async () => {
16
+ pricingAdapter.resultSheet().addFee({
17
+ amount: 0,
18
+ isTaxable: false,
19
+ isNetPrice: false,
20
+ meta: { adapter: DeliveryFreePrice.key },
21
+ });
22
+ return pricingAdapter.calculate();
23
+ },
24
+ };
25
+ },
26
+ };
27
+ export default DeliveryFreePrice;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const DeliveryFreePricePlugin: IPlugin;
3
+ export default DeliveryFreePricePlugin;
4
+ export { DeliveryFreePrice } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { DeliveryFreePrice } from "./adapter.js";
3
+ export const DeliveryFreePricePlugin = {
4
+ key: 'shop.unchained.pricing.delivery-free',
5
+ label: 'Free Delivery Pricing Plugin',
6
+ version: '1.0.0',
7
+ adapters: [DeliveryFreePrice],
8
+ };
9
+ export default DeliveryFreePricePlugin;
10
+ export { DeliveryFreePrice } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IPaymentPricingAdapter } from '@unchainedshop/core';
2
+ export declare const PaymentFreePrice: IPaymentPricingAdapter;
3
+ export default PaymentFreePrice;
@@ -0,0 +1,27 @@
1
+ import { PaymentPricingAdapter } from '@unchainedshop/core';
2
+ export const PaymentFreePrice = {
3
+ ...PaymentPricingAdapter,
4
+ key: 'shop.unchained.pricing.payment-free',
5
+ label: 'Free Payment',
6
+ version: '1.0.0',
7
+ orderIndex: 0,
8
+ isActivatedFor: () => {
9
+ return true;
10
+ },
11
+ actions: (params) => {
12
+ const pricingAdapter = PaymentPricingAdapter.actions(params);
13
+ return {
14
+ ...pricingAdapter,
15
+ calculate: async () => {
16
+ pricingAdapter.resultSheet().addFee({
17
+ amount: 0,
18
+ isNetPrice: false,
19
+ isTaxable: false,
20
+ meta: { adapter: PaymentFreePrice.key },
21
+ });
22
+ return pricingAdapter.calculate();
23
+ },
24
+ };
25
+ },
26
+ };
27
+ export default PaymentFreePrice;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const PaymentFreePricePlugin: IPlugin;
3
+ export default PaymentFreePricePlugin;
4
+ export { PaymentFreePrice } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { PaymentFreePrice } from "./adapter.js";
3
+ export const PaymentFreePricePlugin = {
4
+ key: 'shop.unchained.pricing.payment-free',
5
+ label: 'Free Payment Pricing Plugin',
6
+ version: '1.0.0',
7
+ adapters: [PaymentFreePrice],
8
+ };
9
+ export default PaymentFreePricePlugin;
10
+ export { PaymentFreePrice } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IOrderPricingAdapter } from '@unchainedshop/core';
2
+ export declare const OrderDelivery: IOrderPricingAdapter;
3
+ export default OrderDelivery;
@@ -0,0 +1,33 @@
1
+ import { OrderPricingAdapter, DeliveryPricingSheet, } from '@unchainedshop/core';
2
+ export const OrderDelivery = {
3
+ ...OrderPricingAdapter,
4
+ key: 'shop.unchained.pricing.order-delivery',
5
+ version: '1.0.0',
6
+ label: 'Add Delivery Fees to Order',
7
+ orderIndex: 10,
8
+ isActivatedFor: () => {
9
+ return true;
10
+ },
11
+ actions: (params) => {
12
+ const pricingAdapter = OrderPricingAdapter.actions(params);
13
+ const { order, orderDelivery } = params.context;
14
+ return {
15
+ ...pricingAdapter,
16
+ calculate: async () => {
17
+ if (!orderDelivery)
18
+ return null;
19
+ const pricing = DeliveryPricingSheet({
20
+ calculation: orderDelivery.calculation,
21
+ currencyCode: order.currencyCode,
22
+ });
23
+ const tax = pricing.taxSum();
24
+ const shipping = pricing.gross();
25
+ pricingAdapter
26
+ .resultSheet()
27
+ .addDelivery({ amount: shipping, taxAmount: tax, meta: { adapter: OrderDelivery.key } });
28
+ return pricingAdapter.calculate();
29
+ },
30
+ };
31
+ },
32
+ };
33
+ export default OrderDelivery;
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const OrderDeliveryPlugin: IPlugin;
3
+ export default OrderDeliveryPlugin;
4
+ export { OrderDelivery } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { OrderDelivery } from "./adapter.js";
3
+ export const OrderDeliveryPlugin = {
4
+ key: 'shop.unchained.pricing.order-delivery',
5
+ label: 'Order Delivery Pricing Plugin',
6
+ version: '1.0.0',
7
+ adapters: [OrderDelivery],
8
+ };
9
+ export default OrderDeliveryPlugin;
10
+ export { OrderDelivery } from "./adapter.js";
@@ -0,0 +1,3 @@
1
+ import { type IOrderPricingAdapter, type OrderDiscountConfiguration } from '@unchainedshop/core';
2
+ export declare const OrderDiscount: IOrderPricingAdapter<OrderDiscountConfiguration>;
3
+ export default OrderDiscount;