@unchainedshop/plugins 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/payment/payrexx/api/index.d.ts +35 -0
  2. package/lib/payment/payrexx/api/index.js +100 -0
  3. package/lib/payment/payrexx/api/index.js.map +1 -0
  4. package/lib/payment/payrexx/index.d.ts +1 -0
  5. package/lib/payment/payrexx/index.js +139 -0
  6. package/lib/payment/payrexx/index.js.map +1 -0
  7. package/lib/payment/payrexx/middleware.d.ts +1 -0
  8. package/lib/payment/payrexx/middleware.js +55 -0
  9. package/lib/payment/payrexx/middleware.js.map +1 -0
  10. package/lib/payment/payrexx/payrexx.d.ts +16 -0
  11. package/lib/payment/payrexx/payrexx.js +19 -0
  12. package/lib/payment/payrexx/payrexx.js.map +1 -0
  13. package/lib/payment/stripe/middleware.d.ts +4 -0
  14. package/lib/payment/stripe/middleware.js +54 -47
  15. package/lib/payment/stripe/middleware.js.map +1 -1
  16. package/lib/plugins-index.js +3 -1
  17. package/lib/plugins-index.js.map +1 -1
  18. package/lib/pricing/discount-100-off.d.ts +2 -1
  19. package/lib/pricing/discount-100-off.js.map +1 -1
  20. package/lib/pricing/discount-half-price-manual.d.ts +2 -1
  21. package/lib/pricing/discount-half-price-manual.js.map +1 -1
  22. package/lib/pricing/discount-half-price.d.ts +2 -1
  23. package/lib/pricing/discount-half-price.js.map +1 -1
  24. package/lib/pricing/order-discount.d.ts +2 -1
  25. package/lib/pricing/order-discount.js +2 -8
  26. package/lib/pricing/order-discount.js.map +1 -1
  27. package/lib/pricing/order-items-discount.js +4 -3
  28. package/lib/pricing/order-items-discount.js.map +1 -1
  29. package/lib/pricing/product-discount.js +24 -18
  30. package/lib/pricing/product-discount.js.map +1 -1
  31. package/package.json +22 -22
  32. package/src/payment/payrexx/api/index.ts +132 -0
  33. package/src/payment/payrexx/index.ts +184 -0
  34. package/src/payment/payrexx/middleware.ts +64 -0
  35. package/src/payment/payrexx/payrexx.ts +25 -0
  36. package/src/payment/payrexx/readme.md +4 -0
  37. package/src/payment/stripe/middleware.ts +58 -51
  38. package/src/plugins-index.ts +10 -0
  39. package/src/pricing/discount-100-off.ts +2 -1
  40. package/src/pricing/discount-half-price-manual.ts +2 -1
  41. package/src/pricing/discount-half-price.ts +2 -1
  42. package/src/pricing/order-discount.ts +4 -10
  43. package/src/pricing/order-items-discount.ts +9 -4
  44. package/src/pricing/product-discount.ts +37 -21
@@ -1 +1 @@
1
- {"version":3,"file":"discount-100-off.js","sourceRoot":"","sources":["../../src/pricing/discount-100-off.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEzF,MAAM,CAAC,MAAM,UAAU,GAAqB;IAC1C,GAAG,oBAAoB;IAEvB,GAAG,EAAE,iCAAiC;IACtC,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wBAAwB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC3C,OAAO,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC;QACzC,CAAC;QAED,qEAAqE;QACrE,4BAA4B,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE;YACtD,IAAI,iBAAiB,KAAK,uCAAuC,EAAE,CAAC;gBAClE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC9B,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"discount-100-off.js","sourceRoot":"","sources":["../../src/pricing/discount-100-off.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzF,MAAM,CAAC,MAAM,UAAU,GAAiD;IACtE,GAAG,oBAAoB;IAEvB,GAAG,EAAE,iCAAiC;IACtC,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wBAAwB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC3C,OAAO,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC;QACzC,CAAC;QAED,qEAAqE;QACrE,4BAA4B,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE;YACtD,IAAI,iBAAiB,KAAK,uCAAuC,EAAE,CAAC;gBAClE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC9B,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC"}
@@ -1,2 +1,3 @@
1
1
  import { IDiscountAdapter } from '@unchainedshop/types/discount.js';
2
- export declare const HalfPriceManual: IDiscountAdapter;
2
+ import { ProductDiscountConfiguration } from '@unchainedshop/core-products/director/ProductDiscountConfiguration.js';
3
+ export declare const HalfPriceManual: IDiscountAdapter<ProductDiscountConfiguration>;
@@ -1 +1 @@
1
- {"version":3,"file":"discount-half-price-manual.js","sourceRoot":"","sources":["../../src/pricing/discount-half-price-manual.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEzF,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,GAAG,oBAAoB;IAEvB,GAAG,EAAE,2CAA2C;IAChD,KAAK,EAAE,mBAAmB;IAC1B,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wBAAwB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC3C,OAAO,IAAI,KAAK,WAAW,CAAC;QAC9B,CAAC;QAED,qEAAqE;QACrE,4BAA4B,CAAC,EAAE,iBAAiB,EAAE;YAChD,IAAI,iBAAiB,KAAK,yCAAyC,EAAE,CAAC;gBACpE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"discount-half-price-manual.js","sourceRoot":"","sources":["../../src/pricing/discount-half-price-manual.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzF,MAAM,CAAC,MAAM,eAAe,GAAmD;IAC7E,GAAG,oBAAoB;IAEvB,GAAG,EAAE,2CAA2C;IAChD,KAAK,EAAE,mBAAmB;IAC1B,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wBAAwB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC3C,OAAO,IAAI,KAAK,WAAW,CAAC;QAC9B,CAAC;QAED,qEAAqE;QACrE,4BAA4B,CAAC,EAAE,iBAAiB,EAAE;YAChD,IAAI,iBAAiB,KAAK,yCAAyC,EAAE,CAAC;gBACpE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC"}
@@ -1,2 +1,3 @@
1
1
  import { IDiscountAdapter } from '@unchainedshop/types/discount.js';
2
- export declare const HalfPrice: IDiscountAdapter;
2
+ import { ProductDiscountConfiguration } from '@unchainedshop/core-products/director/ProductDiscountConfiguration.js';
3
+ export declare const HalfPrice: IDiscountAdapter<ProductDiscountConfiguration>;
@@ -1 +1 @@
1
- {"version":3,"file":"discount-half-price.js","sourceRoot":"","sources":["../../src/pricing/discount-half-price.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEzF,MAAM,CAAC,MAAM,SAAS,GAAqB;IACzC,GAAG,oBAAoB;IAEvB,GAAG,EAAE,oCAAoC;IACzC,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpE,MAAM,0BAA0B,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,CAAC,0BAA0B,CAAC;QACtC,CAAC;QAED,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qEAAqE;QACrE,4BAA4B,CAAC,EAAE,iBAAiB,EAAE;YAChD,IAAI,iBAAiB,KAAK,yCAAyC,EAAE,CAAC;gBACpE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"discount-half-price.js","sourceRoot":"","sources":["../../src/pricing/discount-half-price.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzF,MAAM,CAAC,MAAM,SAAS,GAAmD;IACvE,GAAG,oBAAoB;IAEvB,GAAG,EAAE,oCAAoC;IACzC,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,EAAE;IAEd,uEAAuE;IACvE,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpD,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpE,MAAM,0BAA0B,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,CAAC,0BAA0B,CAAC;QACtC,CAAC;QAED,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qEAAqE;QACrE,4BAA4B,CAAC,EAAE,iBAAiB,EAAE;YAChD,IAAI,iBAAiB,KAAK,yCAAyC,EAAE,CAAC;gBACpE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC;AAEF,qBAAqB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC"}
@@ -1,2 +1,3 @@
1
1
  import { IOrderPricingAdapter } from '@unchainedshop/types/orders.pricing.js';
2
- export declare const OrderDiscount: IOrderPricingAdapter;
2
+ import { OrderDiscountConfiguration } from '@unchainedshop/core-orders/director/OrderDiscountConfiguration.js';
3
+ export declare const OrderDiscount: IOrderPricingAdapter<OrderDiscountConfiguration>;
@@ -16,9 +16,6 @@ export const OrderDiscount = {
16
16
  return {
17
17
  ...pricingAdapter,
18
18
  calculate: async () => {
19
- // discounts need to provide a *fixedRate*
20
- // if you want to add percentual discounts,
21
- // add it to the order item calculation
22
19
  const totalAmountOfItems = params.calculationSheet.total({
23
20
  category: OrderPricingRowCategory.Items,
24
21
  useNetPrice: false,
@@ -39,16 +36,13 @@ export const OrderDiscount = {
39
36
  let amountLeft = totalAmountOfPaymentAndDelivery + totalAmountOfItems;
40
37
  params.discounts.forEach(({ configuration, discountId }) => {
41
38
  // First, we deduce the discount from the items
42
- let alreadyDeducted = 0;
43
- const leftInDiscountToSplit = calcUtils.calculateAmountToSplit({ ...configuration, alreadyDeducted }, totalAmountOfItems);
39
+ const leftInDiscountToSplit = calcUtils.calculateAmountToSplit({ ...configuration }, totalAmountOfItems);
44
40
  const [itemsDiscountAmount, itemsTaxAmount] = calcUtils.applyDiscountToMultipleShares(itemShares, Math.max(0, Math.min(amountLeft, leftInDiscountToSplit)));
45
41
  amountLeft -= itemsDiscountAmount;
46
- alreadyDeducted += itemsDiscountAmount;
47
42
  // After the items, we deduct the remaining discount from payment & delivery fees
48
- const leftInFeesToSplit = calcUtils.calculateAmountToSplit({ ...configuration, alreadyDeducted }, totalAmountOfPaymentAndDelivery);
43
+ const leftInFeesToSplit = calcUtils.calculateAmountToSplit({ ...configuration }, totalAmountOfPaymentAndDelivery);
49
44
  const [deliveryAndPaymentDiscountAmount, deliveryAndPaymentTaxAmount] = calcUtils.applyDiscountToMultipleShares([deliveryShare, paymentShare], Math.max(0, Math.min(amountLeft, leftInFeesToSplit)));
50
45
  amountLeft -= deliveryAndPaymentDiscountAmount;
51
- alreadyDeducted += itemsDiscountAmount;
52
46
  const discountAmount = (itemsDiscountAmount + deliveryAndPaymentDiscountAmount) * -1;
53
47
  const taxAmount = (itemsTaxAmount + deliveryAndPaymentTaxAmount) * -1;
54
48
  if (discountAmount) {
@@ -1 +1 @@
1
- {"version":3,"file":"order-discount.js","sourceRoot":"","sources":["../../src/pricing/order-discount.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"order-discount.js","sourceRoot":"","sources":["../../src/pricing/order-discount.ts"],"names":[],"mappings":"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"}
@@ -24,11 +24,12 @@ const OrderItemsDiscount = {
24
24
  useNetPrice: false,
25
25
  }).amount;
26
26
  const itemShares = orderPositions.map((orderPosition) => calcUtils.resolveRatioAndTaxDivisorForPricingSheet(modules.orders.positions.pricingSheet(orderPosition, order.currency, params.context), totalAmountOfItems));
27
- let alreadyDeducted = 0;
27
+ let amountLeft = totalAmountOfItems;
28
28
  params.discounts.forEach(({ configuration, discountId }) => {
29
29
  // First, we deduce the discount from the items
30
- const [itemsDiscountAmount, itemsTaxAmount] = calcUtils.applyDiscountToMultipleShares(itemShares, calcUtils.calculateAmountToSplit({ ...configuration, alreadyDeducted }, totalAmountOfItems));
31
- alreadyDeducted = +itemsDiscountAmount;
30
+ const leftInItemsToSplit = calcUtils.calculateAmountToSplit({ ...configuration }, totalAmountOfItems);
31
+ const [itemsDiscountAmount, itemsTaxAmount] = calcUtils.applyDiscountToMultipleShares(itemShares, Math.max(0, Math.min(amountLeft, leftInItemsToSplit)));
32
+ amountLeft -= itemsDiscountAmount;
32
33
  const discountAmount = itemsDiscountAmount * -1;
33
34
  const taxAmount = itemsTaxAmount * -1;
34
35
  if (discountAmount) {
@@ -1 +1 @@
1
- {"version":3,"file":"order-items-discount.js","sourceRoot":"","sources":["../../src/pricing/order-items-discount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,kBAAkB,GAAyB;IAC/C,GAAG,mBAAmB;IAEtB,GAAG,EAAE,6CAA6C;IAClD,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,yCAAyC;IAChD,UAAU,EAAE,EAAE;IAEd,cAAc,EAAE,GAAG,EAAE;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;QAClB,MAAM,cAAc,GAAG,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;QAE1D,OAAO;YACL,GAAG,cAAc;YAEjB,SAAS,EAAE,KAAK,IAAI,EAAE;gBACpB,0CAA0C;gBAC1C,2CAA2C;gBAC3C,uCAAuC;gBAEvC,MAAM,kBAAkB,GAAG,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;oBACvD,QAAQ,EAAE,uBAAuB,CAAC,KAAK;oBACvC,WAAW,EAAE,KAAK;iBACnB,CAAC,CAAC,MAAM,CAAC;gBAEV,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACtD,SAAS,CAAC,wCAAwC,CAChD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,EACpF,kBAAkB,CACnB,CACF,CAAC;gBAEF,IAAI,eAAe,GAAG,CAAC,CAAC;gBAExB,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,EAAE;oBACzD,+CAA+C;oBAC/C,MAAM,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG,SAAS,CAAC,6BAA6B,CACnF,UAAU,EACV,SAAS,CAAC,sBAAsB,CAAC,EAAE,GAAG,aAAa,EAAE,eAAe,EAAE,EAAE,kBAAkB,CAAC,CAC5F,CAAC;oBACF,eAAe,GAAG,CAAC,mBAAmB,CAAC;oBAEvC,MAAM,cAAc,GAAG,mBAAmB,GAAG,CAAC,CAAC,CAAC;oBAChD,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC;oBACtC,IAAI,cAAc,EAAE,CAAC;wBACnB,cAAc,CAAC,WAAW,EAAE,CAAC,WAAW,CAAC;4BACvC,MAAM,EAAE,cAAc;4BACtB,SAAS;4BACT,UAAU;4BACV,IAAI,EAAE;gCACJ,OAAO,EAAE,kBAAkB,CAAC,GAAG;6BAChC;yBACF,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,OAAO,cAAc,CAAC,SAAS,EAAE,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,oBAAoB,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"order-items-discount.js","sourceRoot":"","sources":["../../src/pricing/order-items-discount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGhE,MAAM,kBAAkB,GAAqD;IAC3E,GAAG,mBAAmB;IAEtB,GAAG,EAAE,6CAA6C;IAClD,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,yCAAyC;IAChD,UAAU,EAAE,EAAE;IAEd,cAAc,EAAE,GAAG,EAAE;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;QAClB,MAAM,cAAc,GAAG,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;QAE1D,OAAO;YACL,GAAG,cAAc;YAEjB,SAAS,EAAE,KAAK,IAAI,EAAE;gBACpB,0CAA0C;gBAC1C,2CAA2C;gBAC3C,uCAAuC;gBAEvC,MAAM,kBAAkB,GAAG,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;oBACvD,QAAQ,EAAE,uBAAuB,CAAC,KAAK;oBACvC,WAAW,EAAE,KAAK;iBACnB,CAAC,CAAC,MAAM,CAAC;gBAEV,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACtD,SAAS,CAAC,wCAAwC,CAChD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,EACpF,kBAAkB,CACnB,CACF,CAAC;gBAEF,IAAI,UAAU,GAAG,kBAAkB,CAAC;gBAEpC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,EAAE;oBACzD,+CAA+C;oBAC/C,MAAM,kBAAkB,GAAG,SAAS,CAAC,sBAAsB,CACzD,EAAE,GAAG,aAAa,EAAE,EACpB,kBAAkB,CACnB,CAAC;oBACF,MAAM,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG,SAAS,CAAC,6BAA6B,CACnF,UAAU,EACV,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,CACtD,CAAC;oBACF,UAAU,IAAI,mBAAmB,CAAC;oBAElC,MAAM,cAAc,GAAG,mBAAmB,GAAG,CAAC,CAAC,CAAC;oBAChD,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC;oBACtC,IAAI,cAAc,EAAE,CAAC;wBACnB,cAAc,CAAC,WAAW,EAAE,CAAC,WAAW,CAAC;4BACvC,MAAM,EAAE,cAAc;4BACtB,SAAS;4BACT,UAAU;4BACV,IAAI,EAAE;gCACJ,OAAO,EAAE,kBAAkB,CAAC,GAAG;6BAChC;yBACF,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,OAAO,cAAc,CAAC,SAAS,EAAE,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,oBAAoB,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC"}
@@ -12,10 +12,11 @@ const ProductDiscount = {
12
12
  },
13
13
  actions: (params) => {
14
14
  const pricingAdapter = ProductPricingAdapter.actions(params);
15
- const addDiscount = (discount, total, isTaxable) => {
16
- const { configuration, discountId } = discount;
17
- const { isNetPrice = false, ...meta } = configuration;
18
- const amount = calcUtils.applyRate(configuration, total);
15
+ const addDiscounts = (discount, total, resolvedConfiguration) => {
16
+ const { discountId } = discount;
17
+ const { isNetPrice = false, taxRate, ...meta } = resolvedConfiguration;
18
+ const amount = calcUtils.applyRate(resolvedConfiguration, total);
19
+ const isTaxable = taxRate === undefined || taxRate === null;
19
20
  pricingAdapter.resultSheet().addDiscount({
20
21
  amount: amount * -1,
21
22
  discountId,
@@ -23,25 +24,30 @@ const ProductDiscount = {
23
24
  isTaxable,
24
25
  meta: { adapter: ProductDiscount.key, ...meta },
25
26
  });
27
+ if (!isTaxable && taxRate) {
28
+ const taxAmount = calcUtils.getTaxAmount(amount, taxRate, isNetPrice);
29
+ pricingAdapter.resultSheet().addTax({
30
+ amount: taxAmount * -1,
31
+ rate: taxRate,
32
+ meta: { adapter: ProductDiscount.key, discountId, ...meta },
33
+ });
34
+ }
26
35
  };
27
36
  return {
28
37
  ...pricingAdapter,
29
38
  calculate: async () => {
30
- const taxableTotal = params.calculationSheet.sum({
31
- category: ProductPricingRowCategory.Item,
32
- isTaxable: true,
33
- });
34
- const nonTaxableTotal = params.calculationSheet.sum({
35
- category: ProductPricingRowCategory.Item,
36
- isTaxable: false,
37
- });
38
39
  params.discounts.forEach((discount) => {
39
- if (taxableTotal !== 0) {
40
- addDiscount(discount, taxableTotal, true);
41
- }
42
- if (nonTaxableTotal !== 0) {
43
- addDiscount(discount, nonTaxableTotal, false);
44
- }
40
+ const { configuration } = discount;
41
+ const resolvedConfiguration = configuration.customPriceConfigurationResolver
42
+ ? configuration.customPriceConfigurationResolver(params.context.product, params.context.quantity, params.context.configuration)
43
+ : configuration;
44
+ if (!resolvedConfiguration)
45
+ return;
46
+ const total = params.calculationSheet.total({
47
+ category: ProductPricingRowCategory.Item,
48
+ useNetPrice: resolvedConfiguration.isNetPrice,
49
+ });
50
+ addDiscounts(discount, total.amount, resolvedConfiguration);
45
51
  });
46
52
  return pricingAdapter.calculate();
47
53
  },
@@ -1 +1 @@
1
- {"version":3,"file":"product-discount.js","sourceRoot":"","sources":["../../src/pricing/product-discount.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,yBAAyB,GAC1B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,eAAe,GAA2B;IAC9C,GAAG,qBAAqB;IAExB,GAAG,EAAE,yCAAyC;IAC9C,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,kCAAkC;IACzC,UAAU,EAAE,EAAE;IAEd,cAAc,EAAE,GAAG,EAAE;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;QAClB,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE7D,MAAM,WAAW,GAAG,CAAC,QAAkB,EAAE,KAAa,EAAE,SAAkB,EAAE,EAAE;YAC5E,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;YAC/C,MAAM,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,aAAa,CAAC;YACtD,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAEzD,cAAc,CAAC,WAAW,EAAE,CAAC,WAAW,CAAC;gBACvC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;gBACnB,UAAU;gBACV,UAAU;gBACV,SAAS;gBACT,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE;aAChD,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO;YACL,GAAG,cAAc;YAEjB,SAAS,EAAE,KAAK,IAAI,EAAE;gBACpB,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC;oBAC/C,QAAQ,EAAE,yBAAyB,CAAC,IAAI;oBACxC,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;gBACH,MAAM,eAAe,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC;oBAClD,QAAQ,EAAE,yBAAyB,CAAC,IAAI;oBACxC,SAAS,EAAE,KAAK;iBACjB,CAAC,CAAC;gBAEH,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACpC,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;wBACvB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;oBAC5C,CAAC;oBACD,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;wBAC1B,WAAW,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,OAAO,cAAc,CAAC,SAAS,EAAE,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,sBAAsB,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"product-discount.js","sourceRoot":"","sources":["../../src/pricing/product-discount.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unchainedshop/plugins",
3
- "version": "2.6.1",
3
+ "version": "2.7.0",
4
4
  "main": "lib/plugins-index.js",
5
5
  "types": "lib/plugins-index.d.ts",
6
6
  "exports": {
@@ -75,35 +75,35 @@
75
75
  "@redis/client": "^1.5.8",
76
76
  "bip32": "^4.0.0",
77
77
  "escape-string-regexp": "^5.0.0",
78
- "ethers": "^6.10.0",
78
+ "ethers": "^6.11.0",
79
79
  "express": "^4.18.2",
80
80
  "lru-cache": "^10.0.0",
81
81
  "open": "^10.0.0",
82
82
  "postfinancecheckout": "^4.1.1",
83
83
  "stripe": "^13.11.0",
84
84
  "tiny-secp256k1": "^2.2.3",
85
- "twilio": "^4.21.0",
85
+ "twilio": "^4.22.0",
86
86
  "web-push": "^3.6.3"
87
87
  },
88
88
  "devDependencies": {
89
- "@redis/client": "^1.5.13",
90
- "@types/node": "^20.11.10",
91
- "@unchainedshop/api": "^2.6.1",
92
- "@unchainedshop/core-delivery": "^2.6.1",
93
- "@unchainedshop/core-enrollments": "^2.6.1",
94
- "@unchainedshop/core-filters": "^2.6.1",
95
- "@unchainedshop/core-messaging": "^2.6.1",
96
- "@unchainedshop/core-orders": "^2.6.1",
97
- "@unchainedshop/core-payment": "^2.6.1",
98
- "@unchainedshop/core-products": "^2.6.1",
99
- "@unchainedshop/core-quotations": "^2.6.1",
100
- "@unchainedshop/core-warehousing": "^2.6.1",
101
- "@unchainedshop/core-worker": "^2.6.1",
102
- "@unchainedshop/events": "^2.6.1",
103
- "@unchainedshop/file-upload": "^2.6.1",
104
- "@unchainedshop/logger": "^2.6.1",
105
- "@unchainedshop/types": "^2.6.1",
106
- "@unchainedshop/utils": "^2.6.1",
89
+ "@redis/client": "^1.5.14",
90
+ "@types/node": "^20.11.17",
91
+ "@unchainedshop/api": "^2.7.0",
92
+ "@unchainedshop/core-delivery": "^2.7.0",
93
+ "@unchainedshop/core-enrollments": "^2.7.0",
94
+ "@unchainedshop/core-filters": "^2.7.0",
95
+ "@unchainedshop/core-messaging": "^2.7.0",
96
+ "@unchainedshop/core-orders": "^2.7.0",
97
+ "@unchainedshop/core-payment": "^2.7.0",
98
+ "@unchainedshop/core-products": "^2.7.0",
99
+ "@unchainedshop/core-quotations": "^2.7.0",
100
+ "@unchainedshop/core-warehousing": "^2.7.0",
101
+ "@unchainedshop/core-worker": "^2.7.0",
102
+ "@unchainedshop/events": "^2.7.0",
103
+ "@unchainedshop/file-upload": "^2.7.0",
104
+ "@unchainedshop/logger": "^2.7.0",
105
+ "@unchainedshop/types": "^2.7.0",
106
+ "@unchainedshop/utils": "^2.7.0",
107
107
  "bluebird": "^3.7.2",
108
108
  "event-iterator": "^2.0.0",
109
109
  "express": "^4.18.2",
@@ -112,7 +112,7 @@
112
112
  "lru-cache": "^10.2.0",
113
113
  "minio": "^7.1.3",
114
114
  "node-sheets": "^1.2.0",
115
- "nodemailer": "^6.9.8",
115
+ "nodemailer": "^6.9.9",
116
116
  "open": "^10.0.3",
117
117
  "postfinancecheckout": "^4.5.0",
118
118
  "request": "^2.88.2",
@@ -0,0 +1,132 @@
1
+ const baseUrl = 'https://api.payrexx.com/v1.0/';
2
+
3
+ export enum GatewayObjectStatus {
4
+ waiting = 'waiting',
5
+ confirmed = 'confirmed',
6
+ cancelled = 'cancelled',
7
+ declined = 'declined',
8
+ authorized = 'authorized',
9
+ reserved = 'reserved',
10
+ refunded = 'refunded',
11
+ refundpending = 'refundpending',
12
+ 'partially-refunded' = 'partially-refunded',
13
+ chargeback = 'chargeback',
14
+ error = 'error',
15
+ uncaptured = '_',
16
+ }
17
+
18
+ export type GatewayObject = {
19
+ status: GatewayObjectStatus;
20
+ currency: string;
21
+ amount: number;
22
+ referenceId: string;
23
+ invoices: {
24
+ transactions: {
25
+ id: string;
26
+ }[];
27
+ }[];
28
+ };
29
+
30
+ export type TransactionObject = any;
31
+
32
+ const createPayrexxAPI = (instance: string, secret: string) => ({
33
+ async buildSignature(query = '') {
34
+ const key = await crypto.subtle.importKey(
35
+ 'raw',
36
+ new TextEncoder().encode(secret),
37
+ { name: 'HMAC', hash: 'SHA-256' },
38
+ false,
39
+ ['sign', 'verify'],
40
+ );
41
+ const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(query));
42
+ return btoa(String.fromCharCode(...new Uint8Array(signature)));
43
+ },
44
+
45
+ buildUrl(path, params = {}) {
46
+ const url = new URL(path, baseUrl);
47
+ url.search = new URLSearchParams({ instance, ...params }).toString();
48
+ return url.href;
49
+ },
50
+
51
+ async chargePreAuthorized(id, params) {
52
+ const queryParams = { ...params };
53
+ const signature = await this.buildSignature(new URLSearchParams(queryParams).toString());
54
+ queryParams.ApiSignature = signature;
55
+
56
+ const url = this.buildUrl(`Transaction/${id}/`);
57
+
58
+ const result = await fetch(url, {
59
+ method: 'POST',
60
+ body: new URLSearchParams(queryParams).toString(),
61
+ headers: {
62
+ accept: 'application/json',
63
+ 'content-type': 'application/x-www-form-urlencoded',
64
+ },
65
+ });
66
+
67
+ if (result.ok) {
68
+ return result.json();
69
+ }
70
+ throw new Error(await result.text());
71
+ },
72
+
73
+ async deleteReservation(id) {
74
+ const url = this.buildUrl(`Transaction/${id}/`, { ApiSignature: await this.buildSignature() });
75
+ const result = await fetch(url, {
76
+ method: 'DELETE',
77
+ headers: {
78
+ accept: 'application/json',
79
+ 'content-type': 'application/x-www-form-urlencoded',
80
+ },
81
+ });
82
+
83
+ if (result.ok) {
84
+ return result.json();
85
+ }
86
+ throw new Error(await result.text());
87
+ },
88
+
89
+ async getGateway(id): Promise<GatewayObject> {
90
+ const url = this.buildUrl(`Gateway/${id}/`, { ApiSignature: await this.buildSignature() });
91
+ const result = await fetch(url);
92
+ if (!result.ok) throw new Error(await result.text());
93
+ const { status, data } = await result.json();
94
+ if (status !== 'success') return null;
95
+ return data?.[0];
96
+ },
97
+
98
+ async createGateway(params): Promise<GatewayObject> {
99
+ const queryParams = { ...params };
100
+ const signature = await this.buildSignature(new URLSearchParams(queryParams).toString());
101
+ queryParams.ApiSignature = signature;
102
+
103
+ const url = this.buildUrl('Gateway/');
104
+ const result = await fetch(url, {
105
+ method: 'POST',
106
+ body: new URLSearchParams(queryParams).toString(),
107
+ headers: {
108
+ accept: 'application/json',
109
+ 'content-type': 'application/x-www-form-urlencoded',
110
+ },
111
+ });
112
+
113
+ if (result.ok) {
114
+ return result.json();
115
+ }
116
+ throw new Error(await result.text());
117
+ },
118
+ });
119
+
120
+ export default createPayrexxAPI;
121
+
122
+ // where you want to consume the payrexx module:
123
+ // const payrexx = payrexx.init(instance, api_secret);
124
+ // const response = await payrexx.createGateway({
125
+ // amount: 100,
126
+ // // add more fields here
127
+ // });
128
+
129
+ // if (response.status === 200) {
130
+ // const gateway = response.data.data[0];
131
+ // // here you will get the gateway
132
+ // }
@@ -0,0 +1,184 @@
1
+ import { IPaymentAdapter } from '@unchainedshop/types/payments.js';
2
+ import { PaymentAdapter, PaymentDirector, PaymentError } from '@unchainedshop/core-payment';
3
+ import { createLogger } from '@unchainedshop/logger';
4
+ import { mapOrderDataToGatewayObject } from './payrexx.js';
5
+ import createPayrexxAPI, { GatewayObjectStatus } from './api/index.js';
6
+
7
+ export * from './middleware.js';
8
+
9
+ const logger = createLogger('unchained:core-payment:payrexx');
10
+
11
+ const Payrexx: IPaymentAdapter = {
12
+ ...PaymentAdapter,
13
+
14
+ key: 'shop.unchained.payment.payrexx',
15
+ label: 'Payrexx',
16
+ version: '1.0.0',
17
+
18
+ typeSupported(type) {
19
+ return type === 'GENERIC';
20
+ },
21
+
22
+ actions: (params) => {
23
+ const { modules } = params.context;
24
+
25
+ const getInstance = () => {
26
+ return params.config.find((c) => c.key === 'instance')?.value;
27
+ };
28
+
29
+ const api = createPayrexxAPI(getInstance(), process.env.PAYREXX_SECRET);
30
+
31
+ const adapterActions = {
32
+ ...PaymentAdapter.actions(params),
33
+
34
+ configurationError() {
35
+ if (!process.env.PAYREXX_SECRET) {
36
+ return PaymentError.INCOMPLETE_CONFIGURATION;
37
+ }
38
+ if (!getInstance()) {
39
+ return PaymentError.INCOMPLETE_CONFIGURATION;
40
+ }
41
+ return null;
42
+ },
43
+
44
+ isActive: () => {
45
+ if (adapterActions.configurationError() === null) return true;
46
+ return false;
47
+ },
48
+
49
+ isPayLaterAllowed() {
50
+ return false;
51
+ },
52
+
53
+ validate: async ({ token }) => {
54
+ throw new Error('Token Registration Flow not implemented yet');
55
+ },
56
+
57
+ register: async ({ setupIntentId }) => {
58
+ throw new Error('Token Registration Flow not implemented yet');
59
+ },
60
+
61
+ sign: async (transactionContext = {}) => {
62
+ const { orderPayment, order } = params.paymentContext;
63
+ if (orderPayment) {
64
+ const pricing = await modules.orders.pricingSheet(order);
65
+ const gatewayObject = mapOrderDataToGatewayObject(
66
+ { order, orderPayment, pricing },
67
+ transactionContext,
68
+ );
69
+ const gateway = await api.createGateway(gatewayObject);
70
+ return JSON.stringify(gateway);
71
+ }
72
+
73
+ throw new Error('Token Registration Flow not implemented yet');
74
+ },
75
+
76
+ async confirm() {
77
+ const { orderPayment } = params.paymentContext;
78
+ const { transactionId } = orderPayment;
79
+
80
+ if (!transactionId) {
81
+ return false;
82
+ }
83
+
84
+ const gatewayObject = await api.getGateway(transactionId);
85
+
86
+ if (!gatewayObject) {
87
+ return false;
88
+ }
89
+
90
+ if (
91
+ gatewayObject.status === GatewayObjectStatus.authorized ||
92
+ gatewayObject.status === GatewayObjectStatus.reserved
93
+ ) {
94
+ const allTransactions = gatewayObject.invoices?.flatMap((invoice) => invoice.transactions);
95
+ await Promise.all(
96
+ allTransactions.map(async (transaction) =>
97
+ api.chargePreAuthorized(transaction.id, { referenceId: orderPayment._id }),
98
+ ),
99
+ );
100
+ return true;
101
+ }
102
+ return false;
103
+ },
104
+
105
+ async cancel() {
106
+ const { orderPayment } = params.paymentContext;
107
+ const { transactionId } = orderPayment;
108
+ if (!transactionId) {
109
+ return false;
110
+ }
111
+
112
+ const gatewayObject = await api.getGateway(transactionId);
113
+
114
+ if (!gatewayObject) {
115
+ return false;
116
+ }
117
+
118
+ if (gatewayObject.status === GatewayObjectStatus.reserved) {
119
+ const allTransactions = gatewayObject.invoices?.flatMap((invoice) => invoice.transactions);
120
+ await Promise.all(
121
+ allTransactions.map(async (transaction) => api.deleteReservation(transaction.id)),
122
+ );
123
+ return true;
124
+ }
125
+ return false;
126
+ },
127
+
128
+ charge: async ({ gatewayId, paymentCredentials }) => {
129
+ if (!gatewayId && !paymentCredentials) {
130
+ throw new Error('You have to provide gatewayId or paymentCredentials');
131
+ }
132
+
133
+ const { order } = params.paymentContext;
134
+ const orderPayment = await modules.orders.payments.findOrderPayment({
135
+ orderPaymentId: order.paymentId,
136
+ });
137
+
138
+ const gatewayObject = await api.getGateway(gatewayId);
139
+
140
+ const pricing = await modules.orders.pricingSheet(order);
141
+ const { currency, amount } = pricing.total({ useNetPrice: false });
142
+
143
+ if (
144
+ gatewayObject.currency !== currency.toUpperCase() ||
145
+ gatewayObject.amount !== Math.round(amount)
146
+ ) {
147
+ throw new Error('The price has changed since the intent has been created');
148
+ }
149
+ if (gatewayObject.referenceId !== orderPayment?._id) {
150
+ throw new Error('The order payment is different from the initiating intent');
151
+ }
152
+
153
+ switch (gatewayObject.status) {
154
+ case GatewayObjectStatus.waiting:
155
+ logger.verbose('Charge postponed because Gateway is pending', {
156
+ orderPaymentId: gatewayObject.referenceId,
157
+ });
158
+ return false;
159
+ case GatewayObjectStatus.authorized:
160
+ case GatewayObjectStatus.reserved:
161
+ case GatewayObjectStatus.confirmed:
162
+ // confirm will do the transition, to do a checkout those stati above are fine
163
+ logger.verbose(`Mark as charged, status is ${gatewayObject.status}`, {
164
+ orderPaymentId: gatewayObject.referenceId,
165
+ });
166
+ return {
167
+ transactionId: gatewayId,
168
+ gatewayObject,
169
+ };
170
+ default:
171
+ logger.verbose('Charge not possible', {
172
+ orderPaymentId: gatewayObject.referenceId,
173
+ status: gatewayObject.status,
174
+ });
175
+ throw new Error(`Gateway Status ${gatewayObject.status} does not allow checkout`);
176
+ }
177
+ },
178
+ };
179
+
180
+ return adapterActions;
181
+ },
182
+ };
183
+
184
+ PaymentDirector.registerAdapter(Payrexx);
@@ -0,0 +1,64 @@
1
+ import { Context } from '@unchainedshop/types/api.js';
2
+ import { createLogger } from '@unchainedshop/logger';
3
+
4
+ const logger = createLogger('unchained:core-payment:payrexx:webhook');
5
+
6
+ export const payrexxHandler = async (request, response) => {
7
+ const resolvedContext = request.unchainedContext as Context;
8
+ const { modules } = resolvedContext;
9
+
10
+ const { transaction } = request.body;
11
+
12
+ if (!transaction) {
13
+ logger.verbose(`unhandled event type`, {
14
+ type: Object.keys(request.body).join(','),
15
+ });
16
+ response.writeHead(200);
17
+ response.end({
18
+ ignored: true,
19
+ message: `Unhandled event type: ${Object.keys(request.body).join(',')}. Supported type: transaction`,
20
+ });
21
+ }
22
+
23
+ logger.verbose(`Processing event`, {
24
+ transactionId: transaction.id,
25
+ });
26
+ try {
27
+ const { referenceId: orderPaymentId } = transaction;
28
+
29
+ logger.verbose(`checkout with orderPaymentId: ${orderPaymentId}`);
30
+ await modules.orders.payments.logEvent(orderPaymentId, {
31
+ transactionId: transaction.id,
32
+ });
33
+ const orderPayment = await modules.orders.payments.findOrderPayment({
34
+ orderPaymentId,
35
+ });
36
+ if (!orderPayment) {
37
+ throw new Error(`order payment not found with orderPaymentId: ${orderPaymentId}`);
38
+ }
39
+ const order = await modules.orders.checkout(
40
+ orderPayment.orderId,
41
+ {
42
+ paymentContext: {
43
+ transactionId: transaction.id,
44
+ },
45
+ },
46
+ resolvedContext,
47
+ );
48
+ logger.info(`checkout successful`, {
49
+ orderPaymentId,
50
+ orderId: order._id,
51
+ });
52
+ response.writeHead(200);
53
+ response.end({
54
+ message: 'checkout successful',
55
+ orderId: order._id,
56
+ });
57
+ } catch (error) {
58
+ logger.error(error, {
59
+ transactionId: transaction.id,
60
+ });
61
+ response.writeHead(500);
62
+ response.end(error.message);
63
+ }
64
+ };