@webbers/pay-payments-medusa 2.2.51 → 2.2.52

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 (39) hide show
  1. package/.medusa/server/package.json +1 -1
  2. package/.medusa/server/src/admin/index.js +171 -11
  3. package/.medusa/server/src/admin/index.mjs +172 -12
  4. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/exchange/route.d.ts +12 -0
  5. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/exchange/route.d.ts.map +1 -0
  6. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/exchange/route.js +42 -0
  7. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/route.d.ts +9 -0
  8. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/route.d.ts.map +1 -0
  9. package/.medusa/server/src/api/admin/pay/orders/[id]/direct-debit/route.js +19 -0
  10. package/.medusa/server/src/api/admin/pay/settings/route.d.ts +12 -0
  11. package/.medusa/server/src/api/admin/pay/settings/route.d.ts.map +1 -0
  12. package/.medusa/server/src/api/admin/pay/settings/route.js +24 -0
  13. package/.medusa/server/src/providers/pay/core/pay-base.d.ts +6 -0
  14. package/.medusa/server/src/providers/pay/core/pay-base.d.ts.map +1 -1
  15. package/.medusa/server/src/providers/pay/core/pay-base.js +24 -1
  16. package/.medusa/server/src/providers/pay/services/pay-direct-debit.d.ts +6 -1
  17. package/.medusa/server/src/providers/pay/services/pay-direct-debit.d.ts.map +1 -1
  18. package/.medusa/server/src/providers/pay/services/pay-direct-debit.js +34 -15
  19. package/.medusa/server/src/providers/pay/types/index.d.ts +6 -5
  20. package/.medusa/server/src/providers/pay/types/index.d.ts.map +1 -1
  21. package/.medusa/server/src/providers/pay/types/index.js +1 -1
  22. package/.medusa/server/src/subscribers/direct-debit-exchange.d.ts.map +1 -1
  23. package/.medusa/server/src/subscribers/direct-debit-exchange.js +95 -24
  24. package/.medusa/server/src/subscribers/payment-failed.d.ts.map +1 -1
  25. package/.medusa/server/src/subscribers/payment-failed.js +23 -4
  26. package/.medusa/server/src/utils/directDebitExchange.d.ts +15 -0
  27. package/.medusa/server/src/utils/directDebitExchange.d.ts.map +1 -1
  28. package/.medusa/server/src/utils/directDebitExchange.js +59 -2
  29. package/.medusa/server/src/utils/directDebitSimulation.d.ts +93 -0
  30. package/.medusa/server/src/utils/directDebitSimulation.d.ts.map +1 -0
  31. package/.medusa/server/src/utils/directDebitSimulation.js +170 -0
  32. package/.medusa/server/src/utils/index.d.ts +1 -0
  33. package/.medusa/server/src/utils/index.d.ts.map +1 -1
  34. package/.medusa/server/src/utils/index.js +2 -1
  35. package/.medusa/server/src/utils/reverseCapturedPayment.d.ts +30 -0
  36. package/.medusa/server/src/utils/reverseCapturedPayment.d.ts.map +1 -0
  37. package/.medusa/server/src/utils/reverseCapturedPayment.js +72 -0
  38. package/README.md +43 -0
  39. package/package.json +1 -1
@@ -7,6 +7,7 @@ exports.config = void 0;
7
7
  exports.default = payPaymentFailedHandler;
8
8
  const utils_1 = require("@medusajs/framework/utils");
9
9
  const getPayPaymentSession_1 = __importDefault(require("../utils/getPayPaymentSession"));
10
+ const reverseCapturedPayment_1 = require("../utils/reverseCapturedPayment");
10
11
  const constants_1 = require("../providers/pay/core/constants");
11
12
  async function payPaymentFailedHandler({ event: { data }, container, }) {
12
13
  const logger = container.resolve("logger");
@@ -21,6 +22,8 @@ async function payPaymentFailedHandler({ event: { data }, container, }) {
21
22
  "payment_collections.*",
22
23
  "payment_collections.payments.captured_at",
23
24
  "payment_collections.payment_sessions.*",
25
+ "payment_collections.payment_sessions.payment.id",
26
+ "payment_collections.payment_sessions.payment.captured_at",
24
27
  ],
25
28
  filters: {
26
29
  display_id: data.id,
@@ -38,11 +41,27 @@ async function payPaymentFailedHandler({ event: { data }, container, }) {
38
41
  return;
39
42
  }
40
43
  const payPaymentSession = (0, getPayPaymentSession_1.default)(order);
41
- if (payPaymentSession) {
42
- await paymentModuleService.updatePaymentCollections(payPaymentSession.payment_collection_id, {
43
- status: utils_1.PaymentCollectionStatus.FAILED,
44
+ if (!payPaymentSession) {
45
+ logger.warn(`No Pay. payment session found for order ${order.id}, ignoring failed payment`);
46
+ return;
47
+ }
48
+ const paymentCollectionId = payPaymentSession.payment_collection_id;
49
+ const capturedPayment = payPaymentSession.payment?.captured_at
50
+ ? payPaymentSession.payment
51
+ : undefined;
52
+ if (data.statusCode === constants_1.PayPaymentStatus.CHARGEBACK && capturedPayment) {
53
+ // The money went back to the customer, make the order payable again
54
+ await (0, reverseCapturedPayment_1.reverseCapturedPayment)(container, {
55
+ orderId: order.id,
56
+ paymentId: capturedPayment.id,
57
+ paymentCollectionId,
58
+ reason: `Pay. chargeback (status ${data.statusCode})`,
44
59
  });
60
+ return;
45
61
  }
62
+ await paymentModuleService.updatePaymentCollections(paymentCollectionId, {
63
+ status: utils_1.PaymentCollectionStatus.FAILED,
64
+ });
46
65
  }
47
66
  catch (e) {
48
67
  logger.error(e);
@@ -52,4 +71,4 @@ async function payPaymentFailedHandler({ event: { data }, container, }) {
52
71
  exports.config = {
53
72
  event: ["pay_payment.failed"],
54
73
  };
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1mYWlsZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc3Vic2NyaWJlcnMvcGF5bWVudC1mYWlsZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBWUEsMENBZ0VDO0FBMUVELHFEQUtrQztBQUVsQyx5RkFBZ0U7QUFDaEUsK0RBQWdFO0FBRWpELEtBQUssVUFBVSx1QkFBdUIsQ0FBQyxFQUNwRCxLQUFLLEVBQUUsRUFBQyxJQUFJLEVBQUMsRUFDYixTQUFTLEdBQ3lDO0lBQ2xELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDMUMsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRSxNQUFNLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQzVDLGVBQU8sQ0FBQyxPQUFPLENBQ2hCLENBQUE7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7SUFFMUMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUNKLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUNkLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ3BCLE1BQU0sRUFBRSxPQUFPO1lBQ2YsTUFBTSxFQUFFO2dCQUNOLElBQUk7Z0JBQ0osdUJBQXVCO2dCQUN2QiwwQ0FBMEM7Z0JBQzFDLHdDQUF3QzthQUN6QztZQUNELE9BQU8sRUFBRTtnQkFDUCxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQUU7YUFDcEI7U0FDRixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMzQixxQ0FBcUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUMvQyxDQUFBO1FBQ0gsQ0FBQztRQUVELDBFQUEwRTtRQUMxRSw4RUFBOEU7UUFDOUUsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQy9ELENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FDTCxFQUFFLENBQUMsTUFBTSxLQUFLLCtCQUF1QixDQUFDLFNBQVM7WUFDL0MsQ0FBQyxFQUFFLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FDL0QsQ0FBQTtRQUVELElBQUksa0JBQWtCLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyw0QkFBZ0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMxRSxNQUFNLENBQUMsSUFBSSxDQUNULG9DQUFvQyxLQUFLLENBQUMsRUFBRSw2QkFBNkIsQ0FDMUUsQ0FBQTtZQUNELE9BQU07UUFDUixDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLDhCQUFvQixFQUFDLEtBQUssQ0FBQyxDQUFBO1FBRXJELElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixNQUFNLG9CQUFvQixDQUFDLHdCQUF3QixDQUNqRCxpQkFBaUIsQ0FBQyxxQkFBK0IsRUFDakQ7Z0JBQ0UsTUFBTSxFQUFFLCtCQUF1QixDQUFDLE1BQU07YUFDdkMsQ0FDRixDQUFBO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNmLE1BQU0sQ0FBQyxDQUFBO0lBQ1QsQ0FBQztBQUNILENBQUM7QUFFWSxRQUFBLE1BQU0sR0FBcUI7SUFDdEMsS0FBSyxFQUFFLENBQUMsb0JBQW9CLENBQUM7Q0FDOUIsQ0FBQSJ9
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1mYWlsZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc3Vic2NyaWJlcnMvcGF5bWVudC1mYWlsZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBYUEsMENBcUZDO0FBaEdELHFEQUtrQztBQUVsQyx5RkFBZ0U7QUFDaEUsNEVBQXNFO0FBQ3RFLCtEQUFnRTtBQUVqRCxLQUFLLFVBQVUsdUJBQXVCLENBQUMsRUFDcEQsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFDLEVBQ2IsU0FBUyxHQUN5QztJQUNsRCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzFDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsTUFBTSxvQkFBb0IsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUM1QyxlQUFPLENBQUMsT0FBTyxDQUNoQixDQUFBO0lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFBO0lBRTFDLElBQUksQ0FBQztRQUNILE1BQU0sRUFDSixJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FDZCxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztZQUNwQixNQUFNLEVBQUUsT0FBTztZQUNmLE1BQU0sRUFBRTtnQkFDTixJQUFJO2dCQUNKLHVCQUF1QjtnQkFDdkIsMENBQTBDO2dCQUMxQyx3Q0FBd0M7Z0JBQ3hDLGlEQUFpRDtnQkFDakQsMERBQTBEO2FBQzNEO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLFVBQVUsRUFBRSxJQUFJLENBQUMsRUFBRTthQUNwQjtTQUNGLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzNCLHFDQUFxQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQy9DLENBQUE7UUFDSCxDQUFDO1FBRUQsMEVBQTBFO1FBQzFFLDhFQUE4RTtRQUM5RSxNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBSyxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDL0QsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUNMLEVBQUUsQ0FBQyxNQUFNLEtBQUssK0JBQXVCLENBQUMsU0FBUztZQUMvQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUMvRCxDQUFBO1FBRUQsSUFBSSxrQkFBa0IsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLDRCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzFFLE1BQU0sQ0FBQyxJQUFJLENBQ1Qsb0NBQW9DLEtBQUssQ0FBQyxFQUFFLDZCQUE2QixDQUMxRSxDQUFBO1lBQ0QsT0FBTTtRQUNSLENBQUM7UUFFRCxNQUFNLGlCQUFpQixHQUFHLElBQUEsOEJBQW9CLEVBQUMsS0FBSyxDQUFDLENBQUE7UUFFckQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDdkIsTUFBTSxDQUFDLElBQUksQ0FDVCwyQ0FBMkMsS0FBSyxDQUFDLEVBQUUsMkJBQTJCLENBQy9FLENBQUE7WUFDRCxPQUFNO1FBQ1IsQ0FBQztRQUVELE1BQU0sbUJBQW1CLEdBQ3ZCLGlCQUFpQixDQUFDLHFCQUErQixDQUFBO1FBQ25ELE1BQU0sZUFBZSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxXQUFXO1lBQzVELENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPO1lBQzNCLENBQUMsQ0FBQyxTQUFTLENBQUE7UUFFYixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssNEJBQWdCLENBQUMsVUFBVSxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ3ZFLG9FQUFvRTtZQUNwRSxNQUFNLElBQUEsK0NBQXNCLEVBQUMsU0FBUyxFQUFFO2dCQUN0QyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQ2pCLFNBQVMsRUFBRSxlQUFlLENBQUMsRUFBRTtnQkFDN0IsbUJBQW1CO2dCQUNuQixNQUFNLEVBQUUsMkJBQTJCLElBQUksQ0FBQyxVQUFVLEdBQUc7YUFDdEQsQ0FBQyxDQUFBO1lBQ0YsT0FBTTtRQUNSLENBQUM7UUFFRCxNQUFNLG9CQUFvQixDQUFDLHdCQUF3QixDQUFDLG1CQUFtQixFQUFFO1lBQ3ZFLE1BQU0sRUFBRSwrQkFBdUIsQ0FBQyxNQUFNO1NBQ3ZDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNmLE1BQU0sQ0FBQyxDQUFBO0lBQ1QsQ0FBQztBQUNILENBQUM7QUFFWSxRQUFBLE1BQU0sR0FBcUI7SUFDdEMsS0FBSyxFQUFFLENBQUMsb0JBQW9CLENBQUM7Q0FDOUIsQ0FBQSJ9
@@ -25,4 +25,19 @@ export declare function parseDirectDebitDisplayId(payload: Record<string, any>):
25
25
  export declare function extractDirectDebit(info?: DirectDebitInfoResponse | DirectDebit | Record<string, any> | null): DirectDebit | null;
26
26
  export declare function extractDirectDebitReference(info: DirectDebitInfoResponse | DirectDebit | Record<string, any> | null, directDebit: DirectDebit | Record<string, any> | null): string | null;
27
27
  export declare function normalizeDirectDebitStatusAction(payloadAction: string, statusAction?: string): string;
28
+ /**
29
+ * Mandates created while the provider runs in test mode are not known at
30
+ * Pay. (see PayDirectDebitService.updatePayment), their code is
31
+ * `TEST-<payment session id>`.
32
+ */
33
+ export declare const SIMULATED_MANDATE_PREFIX = "TEST-";
34
+ export declare function isSimulatedDirectDebitMandate(code: unknown): code is string;
35
+ export declare function readSimulatedMandateSessionId(code: string): string | null;
36
+ /**
37
+ * Builds the direct debit a simulated exchange describes, so a test server can
38
+ * walk through the collection flow (collected, storno, ...) without Pay. The
39
+ * status comes from `status.code` in the body when present, otherwise from the
40
+ * legacy action. Only used for simulated mandates while test mode is active.
41
+ */
42
+ export declare function buildSimulatedDirectDebit(payload: Record<string, any>, mandateId: string, reference: string): DirectDebit;
28
43
  //# sourceMappingURL=directDebitExchange.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directDebitExchange.d.ts","sourceRoot":"","sources":["../../../../src/utils/directDebitExchange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,uBAAuB,EAAC,MAAM,wBAAwB,CAAA;AAG3E,eAAO,MAAM,+BAA+B,sCACP,CAAA;AASrC,eAAO,MAAM,yBAAyB,aAGpC,CAAA;AAEF,eAAO,MAAM,2BAA2B,aAItC,CAAA;AAEF,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE/D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAElE;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAgBtE;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAYf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,CAAC,EAAE,uBAAuB,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GACxE,WAAW,GAAG,IAAI,CAgBpB;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,uBAAuB,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EACxE,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GACpD,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAQR"}
1
+ {"version":3,"file":"directDebitExchange.d.ts","sourceRoot":"","sources":["../../../../src/utils/directDebitExchange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,uBAAuB,EAAC,MAAM,wBAAwB,CAAA;AAG3E,eAAO,MAAM,+BAA+B,sCACP,CAAA;AASrC,eAAO,MAAM,yBAAyB,aAGpC,CAAA;AAEF,eAAO,MAAM,2BAA2B,aAItC,CAAA;AAEF,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE/D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAElE;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAIf;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAgBtE;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,MAAM,GAAG,IAAI,CAYf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,CAAC,EAAE,uBAAuB,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GACxE,WAAW,GAAG,IAAI,CAgBpB;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,uBAAuB,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EACxE,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GACpD,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAQR;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,UAAU,CAAA;AAE/C,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAE3E;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEzE;AASD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,WAAW,CAgCb"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DIRECT_DEBIT_AWAITING_CODES = exports.DIRECT_DEBIT_FAILED_CODES = exports.PAY_DIRECT_DEBIT_EXCHANGE_EVENT = void 0;
3
+ exports.SIMULATED_MANDATE_PREFIX = exports.DIRECT_DEBIT_AWAITING_CODES = exports.DIRECT_DEBIT_FAILED_CODES = exports.PAY_DIRECT_DEBIT_EXCHANGE_EVENT = void 0;
4
4
  exports.normalizeAction = normalizeAction;
5
5
  exports.readPayloadString = readPayloadString;
6
6
  exports.isLegacyDirectDebitAction = isLegacyDirectDebitAction;
@@ -11,6 +11,9 @@ exports.parseDirectDebitDisplayId = parseDirectDebitDisplayId;
11
11
  exports.extractDirectDebit = extractDirectDebit;
12
12
  exports.extractDirectDebitReference = extractDirectDebitReference;
13
13
  exports.normalizeDirectDebitStatusAction = normalizeDirectDebitStatusAction;
14
+ exports.isSimulatedDirectDebitMandate = isSimulatedDirectDebitMandate;
15
+ exports.readSimulatedMandateSessionId = readSimulatedMandateSessionId;
16
+ exports.buildSimulatedDirectDebit = buildSimulatedDirectDebit;
14
17
  const constants_1 = require("../providers/pay/core/constants");
15
18
  exports.PAY_DIRECT_DEBIT_EXCHANGE_EVENT = "pay_payment.direct_debit_exchange";
16
19
  const LEGACY_DIRECT_DEBIT_ACTIONS = new Set([
@@ -105,4 +108,58 @@ function normalizeDirectDebitStatusAction(payloadAction, statusAction) {
105
108
  }
106
109
  return payloadAction.replace(/^incasso/, "");
107
110
  }
108
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0RGViaXRFeGNoYW5nZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9kaXJlY3REZWJpdEV4Y2hhbmdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXdCQSwwQ0FFQztBQUVELDhDQUVDO0FBRUQsOERBRUM7QUFFRCxnRUFNQztBQUVELDREQU1DO0FBV0QsNEVBZ0JDO0FBRUQsOERBY0M7QUFNRCxnREFrQkM7QUFFRCxrRUFZQztBQUVELDRFQVdDO0FBL0lELCtEQUF3RTtBQUUzRCxRQUFBLCtCQUErQixHQUMxQyxtQ0FBbUMsQ0FBQTtBQUVyQyxNQUFNLDJCQUEyQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQzFDLGdCQUFnQjtJQUNoQixhQUFhO0lBQ2Isa0JBQWtCO0lBQ2xCLGVBQWU7Q0FDaEIsQ0FBQyxDQUFBO0FBRVcsUUFBQSx5QkFBeUIsR0FBRyxJQUFJLEdBQUcsQ0FBUztJQUN2RCxvQ0FBd0IsQ0FBQyxNQUFNO0lBQy9CLG9DQUF3QixDQUFDLE1BQU07Q0FDaEMsQ0FBQyxDQUFBO0FBRVcsUUFBQSwyQkFBMkIsR0FBRyxJQUFJLEdBQUcsQ0FBUztJQUN6RCxvQ0FBd0IsQ0FBQyxPQUFPO0lBQ2hDLG9DQUF3QixDQUFDLElBQUk7SUFDN0Isb0NBQXdCLENBQUMsVUFBVTtDQUNwQyxDQUFDLENBQUE7QUFFRixTQUFnQixlQUFlLENBQUMsTUFBZTtJQUM3QyxPQUFPLE9BQU8sTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7QUFDdEUsQ0FBQztBQUVELFNBQWdCLGlCQUFpQixDQUFDLEtBQWM7SUFDOUMsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FB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
111
+ /**
112
+ * Mandates created while the provider runs in test mode are not known at
113
+ * Pay. (see PayDirectDebitService.updatePayment), their code is
114
+ * `TEST-<payment session id>`.
115
+ */
116
+ exports.SIMULATED_MANDATE_PREFIX = "TEST-";
117
+ function isSimulatedDirectDebitMandate(code) {
118
+ return typeof code === "string" && code.startsWith(exports.SIMULATED_MANDATE_PREFIX);
119
+ }
120
+ function readSimulatedMandateSessionId(code) {
121
+ return readPayloadString(code.slice(exports.SIMULATED_MANDATE_PREFIX.length));
122
+ }
123
+ const LEGACY_ACTION_STATUS_CODES = {
124
+ incassopending: constants_1.PayDirectDebitStatusCode.PENDING,
125
+ incassosend: constants_1.PayDirectDebitStatusCode.SENT,
126
+ incassocollected: constants_1.PayDirectDebitStatusCode.COLLECTED,
127
+ incassostorno: constants_1.PayDirectDebitStatusCode.STORNO,
128
+ };
129
+ /**
130
+ * Builds the direct debit a simulated exchange describes, so a test server can
131
+ * walk through the collection flow (collected, storno, ...) without Pay. The
132
+ * status comes from `status.code` in the body when present, otherwise from the
133
+ * legacy action. Only used for simulated mandates while test mode is active.
134
+ */
135
+ function buildSimulatedDirectDebit(payload, mandateId, reference) {
136
+ const action = normalizeAction(payload.action);
137
+ const bodyCode = payload.status?.code ?? payload.statusCode;
138
+ const code = bodyCode !== undefined && bodyCode !== null && bodyCode !== ""
139
+ ? Number(bodyCode)
140
+ : LEGACY_ACTION_STATUS_CODES[action] ?? NaN;
141
+ return {
142
+ id: mandateId,
143
+ description: `Simulated direct debit exchange for #${reference}`,
144
+ url: "",
145
+ processDate: new Date().toISOString(),
146
+ orderId: "",
147
+ paymentSessionId: readSimulatedMandateSessionId(mandateId) ?? "",
148
+ type: "SINGLE",
149
+ amount: {
150
+ value: Number(payload.amount?.value ?? 0),
151
+ currency: String(payload.amount?.currency ?? ""),
152
+ },
153
+ status: {
154
+ code,
155
+ action: readPayloadString(payload.status?.action) ??
156
+ action.replace(/^incasso/, ""),
157
+ phase: "",
158
+ },
159
+ declined: payload.declined === true,
160
+ decline: null,
161
+ bankAccount: { iban: "", bic: "", owner: "" },
162
+ mandate: { code: mandateId, reference, description: "" },
163
+ };
164
+ }
165
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0RGViaXRFeGNoYW5nZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9kaXJlY3REZWJpdEV4Y2hhbmdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXdCQSwwQ0FFQztBQUVELDhDQUVDO0FBRUQsOERBRUM7QUFFRCxnRUFNQztBQUVELDREQU1DO0FBV0QsNEVBZ0JDO0FBRUQsOERBY0M7QUFNRCxnREFrQkM7QUFFRCxrRUFZQztBQUVELDRFQVdDO0FBU0Qsc0VBRUM7QUFFRCxzRUFFQztBQWVELDhEQW9DQztBQWpORCwrREFBd0U7QUFFM0QsUUFBQSwrQkFBK0IsR0FDMUMsbUNBQW1DLENBQUE7QUFFckMsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMxQyxnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQixlQUFlO0NBQ2hCLENBQUMsQ0FBQTtBQUVXLFFBQUEseUJBQXlCLEdBQUcsSUFBSSxHQUFHLENBQVM7SUFDdkQsb0NBQXdCLENBQUMsTUFBTTtJQUMvQixvQ0FBd0IsQ0FBQyxNQUFNO0NBQ2hDLENBQUMsQ0FBQTtBQUVXLFFBQUEsMkJBQTJCLEdBQUcsSUFBSSxHQUFHLENBQVM7SUFDekQsb0NBQXdCLENBQUMsT0FBTztJQUNoQyxvQ0FBd0IsQ0FBQyxJQUFJO0lBQzdCLG9DQUF3QixDQUFDLFVBQVU7Q0FDcEMsQ0FBQyxDQUFBO0FBRUYsU0FBZ0IsZUFBZSxDQUFDLE1BQWU7SUFDN0MsT0FBTyxPQUFPLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO0FBQ3RFLENBQUM7QUFFRCxTQUFnQixpQkFBaUIsQ0FBQyxLQUFjO0lBQzlDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFD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
@@ -0,0 +1,93 @@
1
+ import { MedusaContainer } from "@medusajs/types";
2
+ import { ProviderOptions } from "../providers/pay/types";
3
+ /**
4
+ * The exchanges a test server can simulate for a direct debit that only exists
5
+ * locally (see README "Testing direct debits locally"). Each preset is the body
6
+ * Pay. would send, minus the mandate and order reference that are filled in
7
+ * from the order.
8
+ */
9
+ export declare const SIMULATED_EXCHANGE_PRESETS: {
10
+ readonly pending: {
11
+ readonly label: "Pending";
12
+ readonly description: "The debit is scheduled, the collection stays awaiting.";
13
+ readonly payload: {
14
+ readonly action: "incassopending";
15
+ };
16
+ };
17
+ readonly sent: {
18
+ readonly label: "Sent to bank";
19
+ readonly description: "The debit was sent to the bank, the collection stays awaiting.";
20
+ readonly payload: {
21
+ readonly action: "incassosend";
22
+ };
23
+ };
24
+ readonly collected: {
25
+ readonly label: "Collected";
26
+ readonly description: "The bank collected the money: the payment is captured.";
27
+ readonly payload: {
28
+ readonly action: "incassocollected";
29
+ };
30
+ };
31
+ readonly storno: {
32
+ readonly label: "Storno";
33
+ readonly description: "The customer reversed the debit after collection: the payment is refunded in Medusa and the order becomes payable again.";
34
+ readonly payload: {
35
+ readonly action: "incassostorno";
36
+ };
37
+ };
38
+ readonly failed: {
39
+ readonly label: "Failed";
40
+ readonly description: "The bank rejected the debit: the collection fails.";
41
+ readonly payload: {
42
+ readonly action: "incassosend";
43
+ readonly status: {
44
+ readonly code: 106;
45
+ };
46
+ };
47
+ };
48
+ readonly declined: {
49
+ readonly label: "Declined";
50
+ readonly description: "The debit was declined: the collection fails.";
51
+ readonly payload: {
52
+ readonly action: "incassosend";
53
+ readonly declined: true;
54
+ };
55
+ };
56
+ };
57
+ export type SimulatedExchangeKey = keyof typeof SIMULATED_EXCHANGE_PRESETS;
58
+ export declare const isSimulatedExchangeKey: (value: unknown) => value is SimulatedExchangeKey;
59
+ export type DirectDebitSimulationState = {
60
+ /** Whether exchanges can be simulated for this order */
61
+ available: boolean;
62
+ /** Why not, when unavailable */
63
+ reason?: "sepa_testing_off" | "test_mode_off" | "no_direct_debit" | "not_simulated";
64
+ testMode: boolean;
65
+ /** The "SEPA testing" switch on the Pay. settings page */
66
+ sepaTesting: boolean;
67
+ orderId: string;
68
+ displayId: string;
69
+ mandateCode: string | null;
70
+ paymentCollectionId: string | null;
71
+ paymentCollectionStatus: string | null;
72
+ captured: boolean;
73
+ presets: Record<SimulatedExchangeKey, {
74
+ label: string;
75
+ description: string;
76
+ }>;
77
+ };
78
+ export declare const getPayProviderOptions: (container: MedusaContainer) => ProviderOptions | null;
79
+ /**
80
+ * The "SEPA testing" switch on the Pay. settings page lives in the store's
81
+ * metadata, so it is shared by every admin user and needs no migration. Off by
82
+ * default: it is meant for staging servers only.
83
+ */
84
+ export declare const SEPA_TESTING_METADATA_KEY = "pay_sepa_testing";
85
+ export declare function isSepaTestingEnabled(container: MedusaContainer): Promise<boolean>;
86
+ export declare function setSepaTestingEnabled(container: MedusaContainer, enabled: boolean): Promise<boolean>;
87
+ export declare function getDirectDebitSimulationState(container: MedusaContainer, orderId: string): Promise<DirectDebitSimulationState | null>;
88
+ /**
89
+ * Builds the exchange body for a preset, as Pay. would send it for the order's
90
+ * simulated mandate.
91
+ */
92
+ export declare function buildSimulatedExchangePayload(key: SimulatedExchangeKey, state: Pick<DirectDebitSimulationState, "mandateCode" | "displayId">): Record<string, unknown>;
93
+ //# sourceMappingURL=directDebitSimulation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directDebitSimulation.d.ts","sourceRoot":"","sources":["../../../../src/utils/directDebitSimulation.ts"],"names":[],"mappings":"AAKA,OAAO,EAAsB,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAGpE,OAAO,EAAsB,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAG3E;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmC7B,CAAA;AAEV,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,0BAA0B,CAAA;AAE1E,eAAO,MAAM,sBAAsB,GACjC,OAAO,OAAO,KACb,KAAK,IAAI,oBAE6D,CAAA;AAEzE,MAAM,MAAM,0BAA0B,GAAG;IACvC,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAA;IAClB,gCAAgC;IAChC,MAAM,CAAC,EACH,kBAAkB,GAClB,eAAe,GACf,iBAAiB,GACjB,eAAe,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,CACb,oBAAoB,EACpB;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CACrC,CAAA;CACF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAChC,WAAW,eAAe,KACzB,eAAe,GAAG,IASpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,qBAAqB,CAAA;AAc3D,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,OAAO,CAAC,CAIlB;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAUD,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CA6E5C;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,oBAAoB,EACzB,KAAK,EAAE,IAAI,CAAC,0BAA0B,EAAE,aAAa,GAAG,WAAW,CAAC,GACnE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SEPA_TESTING_METADATA_KEY = exports.getPayProviderOptions = exports.isSimulatedExchangeKey = exports.SIMULATED_EXCHANGE_PRESETS = void 0;
7
+ exports.isSepaTestingEnabled = isSepaTestingEnabled;
8
+ exports.setSepaTestingEnabled = setSepaTestingEnabled;
9
+ exports.getDirectDebitSimulationState = getDirectDebitSimulationState;
10
+ exports.buildSimulatedExchangePayload = buildSimulatedExchangePayload;
11
+ const utils_1 = require("@medusajs/framework/utils");
12
+ const getPayPaymentSession_1 = __importDefault(require("./getPayPaymentSession"));
13
+ const directDebitExchange_1 = require("./directDebitExchange");
14
+ const types_1 = require("../providers/pay/types");
15
+ const constants_1 = require("../providers/pay/core/constants");
16
+ /**
17
+ * The exchanges a test server can simulate for a direct debit that only exists
18
+ * locally (see README "Testing direct debits locally"). Each preset is the body
19
+ * Pay. would send, minus the mandate and order reference that are filled in
20
+ * from the order.
21
+ */
22
+ exports.SIMULATED_EXCHANGE_PRESETS = {
23
+ pending: {
24
+ label: "Pending",
25
+ description: "The debit is scheduled, the collection stays awaiting.",
26
+ payload: { action: "incassopending" },
27
+ },
28
+ sent: {
29
+ label: "Sent to bank",
30
+ description: "The debit was sent to the bank, the collection stays awaiting.",
31
+ payload: { action: "incassosend" },
32
+ },
33
+ collected: {
34
+ label: "Collected",
35
+ description: "The bank collected the money: the payment is captured.",
36
+ payload: { action: "incassocollected" },
37
+ },
38
+ storno: {
39
+ label: "Storno",
40
+ description: "The customer reversed the debit after collection: the payment is refunded in Medusa and the order becomes payable again.",
41
+ payload: { action: "incassostorno" },
42
+ },
43
+ failed: {
44
+ label: "Failed",
45
+ description: "The bank rejected the debit: the collection fails.",
46
+ payload: {
47
+ action: "incassosend",
48
+ status: { code: constants_1.PayDirectDebitStatusCode.FAILED },
49
+ },
50
+ },
51
+ declined: {
52
+ label: "Declined",
53
+ description: "The debit was declined: the collection fails.",
54
+ payload: { action: "incassosend", declined: true },
55
+ },
56
+ };
57
+ const isSimulatedExchangeKey = (value) => typeof value === "string" &&
58
+ Object.prototype.hasOwnProperty.call(exports.SIMULATED_EXCHANGE_PRESETS, value);
59
+ exports.isSimulatedExchangeKey = isSimulatedExchangeKey;
60
+ const getPayProviderOptions = (container) => {
61
+ const configModule = container.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
62
+ const payModuleConfig = configModule.modules?.payment?.options
63
+ ?.providers?.find((p) => p.id === "pay");
64
+ return payModuleConfig?.options ?? null;
65
+ };
66
+ exports.getPayProviderOptions = getPayProviderOptions;
67
+ /**
68
+ * The "SEPA testing" switch on the Pay. settings page lives in the store's
69
+ * metadata, so it is shared by every admin user and needs no migration. Off by
70
+ * default: it is meant for staging servers only.
71
+ */
72
+ exports.SEPA_TESTING_METADATA_KEY = "pay_sepa_testing";
73
+ const getStore = async (container) => {
74
+ const storeModuleService = container.resolve(utils_1.Modules.STORE);
75
+ const [store] = await storeModuleService.listStores({}, { select: ["id", "metadata"], take: 1 });
76
+ return store ?? null;
77
+ };
78
+ async function isSepaTestingEnabled(container) {
79
+ const store = await getStore(container);
80
+ return store?.metadata?.[exports.SEPA_TESTING_METADATA_KEY] === true;
81
+ }
82
+ async function setSepaTestingEnabled(container, enabled) {
83
+ const store = await getStore(container);
84
+ if (!store) {
85
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "No store found");
86
+ }
87
+ const storeModuleService = container.resolve(utils_1.Modules.STORE);
88
+ await storeModuleService.updateStores(store.id, {
89
+ metadata: { ...(store.metadata ?? {}), [exports.SEPA_TESTING_METADATA_KEY]: enabled },
90
+ });
91
+ return enabled;
92
+ }
93
+ const presetSummaries = () => Object.fromEntries(Object.entries(exports.SIMULATED_EXCHANGE_PRESETS).map(([key, preset]) => [
94
+ key,
95
+ { label: preset.label, description: preset.description },
96
+ ]));
97
+ async function getDirectDebitSimulationState(container, orderId) {
98
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
99
+ const options = (0, exports.getPayProviderOptions)(container);
100
+ // Same default as the HTTP client: an unset testMode means test mode
101
+ const testMode = options?.testMode ?? true;
102
+ const sepaTesting = await isSepaTestingEnabled(container);
103
+ const { data: [order], } = await query.graph({
104
+ entity: "order",
105
+ fields: [
106
+ "id",
107
+ "display_id",
108
+ "payment_collections.id",
109
+ "payment_collections.status",
110
+ "payment_collections.payment_sessions.*",
111
+ "payment_collections.payment_sessions.payment.id",
112
+ "payment_collections.payment_sessions.payment.captured_at",
113
+ ],
114
+ filters: { id: orderId },
115
+ });
116
+ if (!order) {
117
+ return null;
118
+ }
119
+ const base = {
120
+ testMode,
121
+ sepaTesting,
122
+ orderId: order.id,
123
+ displayId: String(order.display_id),
124
+ presets: presetSummaries(),
125
+ };
126
+ const payPaymentSession = (0, getPayPaymentSession_1.default)(order);
127
+ if (!payPaymentSession?.provider_id.includes(types_1.PaymentProviderKeys.DIRECTDEBIT)) {
128
+ return {
129
+ ...base,
130
+ available: false,
131
+ reason: "no_direct_debit",
132
+ mandateCode: null,
133
+ paymentCollectionId: null,
134
+ paymentCollectionStatus: null,
135
+ captured: false,
136
+ };
137
+ }
138
+ const sessionData = (payPaymentSession.data ?? {});
139
+ const mandateCode = typeof sessionData.code === "string" ? sessionData.code : null;
140
+ const simulated = sessionData.testMode === true && (0, directDebitExchange_1.isSimulatedDirectDebitMandate)(mandateCode);
141
+ const collection = (order.payment_collections ?? []).find((pc) => pc?.id === payPaymentSession.payment_collection_id);
142
+ const reason = !sepaTesting
143
+ ? "sepa_testing_off"
144
+ : !testMode
145
+ ? "test_mode_off"
146
+ : !simulated
147
+ ? "not_simulated"
148
+ : undefined;
149
+ return {
150
+ ...base,
151
+ available: !reason,
152
+ reason,
153
+ mandateCode,
154
+ paymentCollectionId: payPaymentSession.payment_collection_id ?? null,
155
+ paymentCollectionStatus: collection?.status ?? null,
156
+ captured: !!payPaymentSession.payment?.captured_at,
157
+ };
158
+ }
159
+ /**
160
+ * Builds the exchange body for a preset, as Pay. would send it for the order's
161
+ * simulated mandate.
162
+ */
163
+ function buildSimulatedExchangePayload(key, state) {
164
+ return {
165
+ ...exports.SIMULATED_EXCHANGE_PRESETS[key].payload,
166
+ mandateId: state.mandateCode,
167
+ reference: state.displayId,
168
+ };
169
+ }
170
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0RGViaXRTaW11bGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL2RpcmVjdERlYml0U2ltdWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFzSEEsb0RBTUM7QUFFRCxzREFtQkM7QUFVRCxzRUFnRkM7QUFNRCxzRUFTQztBQTFQRCxxREFJa0M7QUFFbEMsa0ZBQXlEO0FBQ3pELCtEQUFtRTtBQUNuRSxrREFBMkU7QUFDM0UsK0RBQXdFO0FBRXhFOzs7OztHQUtHO0FBQ1UsUUFBQSwwQkFBMEIsR0FBRztJQUN4QyxPQUFPLEVBQUU7UUFDUCxLQUFLLEVBQUUsU0FBUztRQUNoQixXQUFXLEVBQUUsd0RBQXdEO1FBQ3JFLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBQztLQUNwQztJQUNELElBQUksRUFBRTtRQUNKLEtBQUssRUFBRSxjQUFjO1FBQ3JCLFdBQVcsRUFBRSxnRUFBZ0U7UUFDN0UsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLGFBQWEsRUFBQztLQUNqQztJQUNELFNBQVMsRUFBRTtRQUNULEtBQUssRUFBRSxXQUFXO1FBQ2xCLFdBQVcsRUFBRSx3REFBd0Q7UUFDckUsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFDO0tBQ3RDO0lBQ0QsTUFBTSxFQUFFO1FBQ04sS0FBSyxFQUFFLFFBQVE7UUFDZixXQUFXLEVBQ1QsMEhBQTBIO1FBQzVILE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxlQUFlLEVBQUM7S0FDbkM7SUFDRCxNQUFNLEVBQUU7UUFDTixLQUFLLEVBQUUsUUFBUTtRQUNmLFdBQVcsRUFBRSxvREFBb0Q7UUFDakUsT0FBTyxFQUFFO1lBQ1AsTUFBTSxFQUFFLGFBQWE7WUFDckIsTUFBTSxFQUFFLEVBQUMsSUFBSSxFQUFFLG9DQUF3QixDQUFDLE1BQU0sRUFBQztTQUNoRDtLQUNGO0lBQ0QsUUFBUSxFQUFFO1FBQ1IsS0FBSyxFQUFFLFVBQVU7UUFDakIsV0FBVyxFQUFFLCtDQUErQztRQUM1RCxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUM7S0FDakQ7Q0FDTyxDQUFBO0FBSUgsTUFBTSxzQkFBc0IsR0FBRyxDQUNwQyxLQUFjLEVBQ2lCLEVBQUUsQ0FDakMsT0FBTyxLQUFLLEtBQUssUUFBUTtJQUN6QixNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsa0NBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUE7QUFKNUQsUUFBQSxzQkFBc0IsMEJBSXNDO0FBMEJsRSxNQUFNLHFCQUFxQixHQUFHLENBQ25DLFNBQTBCLEVBQ0YsRUFBRTtJQUMxQixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsT0FBTyxDQUNwQyxpQ0FBeUIsQ0FBQyxhQUFhLENBQ3hDLENBQUE7SUFFRCxNQUFNLGVBQWUsR0FBSSxZQUFZLENBQUMsT0FBTyxFQUFFLE9BQWUsRUFBRSxPQUFPO1FBQ3JFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxLQUFLLENBQUMsQ0FBQTtJQUUxQyxPQUFRLGVBQWUsRUFBRSxPQUF1QyxJQUFJLElBQUksQ0FBQTtBQUMxRSxDQUFDLENBQUE7QUFYWSxRQUFBLHFCQUFxQix5QkFXakM7QUFFRDs7OztHQUlHO0FBQ1UsUUFBQSx5QkFBeUIsR0FBRyxrQkFBa0IsQ0FBQTtBQUUzRCxNQUFNLFFBQVEsR0FBRyxLQUFLLEVBQUUsU0FBMEIsRUFBRSxFQUFFO0lBQ3BELE1BQU0sa0JBQWtCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDMUMsZUFBTyxDQUFDLEtBQUssQ0FDZCxDQUFBO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sa0JBQWtCLENBQUMsVUFBVSxDQUNqRCxFQUFFLEVBQ0YsRUFBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQyxDQUN0QyxDQUFBO0lBRUQsT0FBTyxLQUFLLElBQUksSUFBSSxDQUFBO0FBQ3RCLENBQUMsQ0FBQTtBQUVNLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsU0FBMEI7SUFFMUIsTUFBTSxLQUFLLEdBQUcsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUE7SUFFdkMsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsaUNBQXlCLENBQUMsS0FBSyxJQUFJLENBQUE7QUFDOUQsQ0FBQztBQUVNLEtBQUssVUFBVSxxQkFBcUIsQ0FDekMsU0FBMEIsRUFDMUIsT0FBZ0I7SUFFaEIsTUFBTSxLQUFLLEdBQUcsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUE7SUFFdkMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUE7SUFDdEUsQ0FBQztJQUVELE1BQU0sa0JBQWtCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDMUMsZUFBTyxDQUFDLEtBQUssQ0FDZCxDQUFBO0lBRUQsTUFBTSxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRTtRQUM5QyxRQUFRLEVBQUUsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGlDQUF5QixDQUFDLEVBQUUsT0FBTyxFQUFDO0tBQzVFLENBQUMsQ0FBQTtJQUVGLE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUM7QUFFRCxNQUFNLGVBQWUsR0FBRyxHQUFHLEVBQUUsQ0FDM0IsTUFBTSxDQUFDLFdBQVcsQ0FDaEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxrQ0FBMEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztJQUNoRSxHQUFHO0lBQ0gsRUFBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBQztDQUN2RCxDQUFDLENBQ3NDLENBQUE7QUFFckMsS0FBSyxVQUFVLDZCQUE2QixDQUNqRCxTQUEwQixFQUMxQixPQUFlO0lBRWYsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRSxNQUFNLE9BQU8sR0FBRyxJQUFBLDZCQUFxQixFQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ2hELHFFQUFxRTtJQUNyRSxNQUFNLFFBQVEsR0FBRyxPQUFPLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQTtJQUMxQyxNQUFNLFdBQVcsR0FBRyxNQUFNLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBRXpELE1BQU0sRUFDSixJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FDZCxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUNwQixNQUFNLEVBQUUsT0FBTztRQUNmLE1BQU0sRUFBRTtZQUNOLElBQUk7WUFDSixZQUFZO1lBQ1osd0JBQXdCO1lBQ3hCLDRCQUE0QjtZQUM1Qix3Q0FBd0M7WUFDeEMsaURBQWlEO1lBQ2pELDBEQUEwRDtTQUMzRDtRQUNELE9BQU8sRUFBRSxFQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUM7S0FDdkIsQ0FBQyxDQUFBO0lBRUYsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUc7UUFDWCxRQUFRO1FBQ1IsV0FBVztRQUNYLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRTtRQUNqQixTQUFTLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDbkMsT0FBTyxFQUFFLGVBQWUsRUFBRTtLQUMzQixDQUFBO0lBRUQsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLDhCQUFvQixFQUFDLEtBQVksQ0FBQyxDQUFBO0lBRTVELElBQ0UsQ0FBQyxpQkFBaUIsRUFBRSxXQUFXLENBQUMsUUFBUSxDQUFDLDJCQUFtQixDQUFDLFdBQVcsQ0FBQyxFQUN6RSxDQUFDO1FBQ0QsT0FBTztZQUNMLEdBQUcsSUFBSTtZQUNQLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLE1BQU0sRUFBRSxpQkFBaUI7WUFDekIsV0FBVyxFQUFFLElBQUk7WUFDakIsbUJBQW1CLEVBQUUsSUFBSTtZQUN6Qix1QkFBdUIsRUFBRSxJQUFJO1lBQzdCLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUF3QixDQUFBO0lBQ3pFLE1BQU0sV0FBVyxHQUNmLE9BQU8sV0FBVyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUNoRSxNQUFNLFNBQVMsR0FDYixXQUFXLENBQUMsUUFBUSxLQUFLLElBQUksSUFBSSxJQUFBLG1EQUE2QixFQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQzdFLE1BQU0sVUFBVSxHQUFHLENBQUMsS0FBSyxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDdkQsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEtBQUssaUJBQWlCLENBQUMscUJBQXFCLENBQzNELENBQUE7SUFFRCxNQUFNLE1BQU0sR0FBRyxDQUFDLFdBQVc7UUFDekIsQ0FBQyxDQUFDLGtCQUFrQjtRQUNwQixDQUFDLENBQUMsQ0FBQyxRQUFRO1lBQ1QsQ0FBQyxDQUFDLGVBQWU7WUFDakIsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDVixDQUFDLENBQUMsZUFBZTtnQkFDakIsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtJQUVqQixPQUFPO1FBQ0wsR0FBRyxJQUFJO1FBQ1AsU0FBUyxFQUFFLENBQUMsTUFBTTtRQUNsQixNQUFNO1FBQ04sV0FBVztRQUNYLG1CQUFtQixFQUFHLGlCQUFpQixDQUFDLHFCQUFnQyxJQUFJLElBQUk7UUFDaEYsdUJBQXVCLEVBQUUsVUFBVSxFQUFFLE1BQU0sSUFBSSxJQUFJO1FBQ25ELFFBQVEsRUFBRSxDQUFDLENBQUUsaUJBQXlCLENBQUMsT0FBTyxFQUFFLFdBQVc7S0FDNUQsQ0FBQTtBQUNILENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQiw2QkFBNkIsQ0FDM0MsR0FBeUIsRUFDekIsS0FBb0U7SUFFcEUsT0FBTztRQUNMLEdBQUcsa0NBQTBCLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTztRQUMxQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFdBQVc7UUFDNUIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO0tBQzNCLENBQUE7QUFDSCxDQUFDIn0=
@@ -1,2 +1,3 @@
1
1
  export * from "./createPayOrder";
2
+ export * from "./reverseCapturedPayment";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,0BAA0B,CAAA"}
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./createPayOrder"), exports);
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUFnQyJ9
18
+ __exportStar(require("./reverseCapturedPayment"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUFnQztBQUNoQywyREFBd0MifQ==
@@ -0,0 +1,30 @@
1
+ import { MedusaContainer } from "@medusajs/types";
2
+ export type ReverseCapturedPaymentInput = {
3
+ orderId: string;
4
+ paymentId: string;
5
+ paymentCollectionId: string;
6
+ /** Stored as the refund note, e.g. "Pay. chargeback (status -71)" */
7
+ reason: string;
8
+ };
9
+ /**
10
+ * A chargeback or direct debit storno reverses a payment Medusa already
11
+ * captured. Reflect that on the order so it shows as unpaid and can be paid
12
+ * again:
13
+ *
14
+ * 1. record a refund for the still-captured amount on the payment. The Pay.
15
+ * provider recognises a reversed payment and records it without asking Pay.
16
+ * for a refund, the money is already back with the customer;
17
+ * 2. add the matching negative order transaction, so the order summary shows
18
+ * the amount as outstanding again (refundPaymentWorkflow is not used
19
+ * because it would also credit the order for the refund);
20
+ * 3. mark the payment collection failed;
21
+ * 4. create a fresh not_paid payment collection for the outstanding amount,
22
+ * which is what the admin's "Copy payment link" / "Mark as paid" buttons and
23
+ * the storefront payment-collection route work with.
24
+ *
25
+ * Safe to run more than once: a payment that is already fully reversed only
26
+ * gets whatever step is still missing.
27
+ */
28
+ export declare function reverseCapturedPayment(container: MedusaContainer, input: ReverseCapturedPaymentInput): Promise<void>;
29
+ export default reverseCapturedPayment;
30
+ //# sourceMappingURL=reverseCapturedPayment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverseCapturedPayment.d.ts","sourceRoot":"","sources":["../../../../src/utils/reverseCapturedPayment.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAExB,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,IAAI,CAAC,CA+Ef;AAED,eAAe,sBAAsB,CAAA"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reverseCapturedPayment = reverseCapturedPayment;
4
+ const core_flows_1 = require("@medusajs/core-flows");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const sumAmounts = (items) => (items ?? []).reduce((total, item) => utils_1.MathBN.add(total, item.amount), utils_1.MathBN.convert(0));
7
+ /**
8
+ * A chargeback or direct debit storno reverses a payment Medusa already
9
+ * captured. Reflect that on the order so it shows as unpaid and can be paid
10
+ * again:
11
+ *
12
+ * 1. record a refund for the still-captured amount on the payment. The Pay.
13
+ * provider recognises a reversed payment and records it without asking Pay.
14
+ * for a refund, the money is already back with the customer;
15
+ * 2. add the matching negative order transaction, so the order summary shows
16
+ * the amount as outstanding again (refundPaymentWorkflow is not used
17
+ * because it would also credit the order for the refund);
18
+ * 3. mark the payment collection failed;
19
+ * 4. create a fresh not_paid payment collection for the outstanding amount,
20
+ * which is what the admin's "Copy payment link" / "Mark as paid" buttons and
21
+ * the storefront payment-collection route work with.
22
+ *
23
+ * Safe to run more than once: a payment that is already fully reversed only
24
+ * gets whatever step is still missing.
25
+ */
26
+ async function reverseCapturedPayment(container, input) {
27
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
28
+ const paymentModuleService = container.resolve(utils_1.Modules.PAYMENT);
29
+ const orderModuleService = container.resolve(utils_1.Modules.ORDER);
30
+ let payment = await paymentModuleService.retrievePayment(input.paymentId, {
31
+ relations: ["captures", "refunds"],
32
+ });
33
+ const outstanding = utils_1.MathBN.sub(sumAmounts(payment.captures), sumAmounts(payment.refunds));
34
+ if (utils_1.MathBN.gt(outstanding, 0)) {
35
+ const amount = new utils_1.BigNumber(outstanding).numeric;
36
+ payment = await paymentModuleService.refundPayment({
37
+ payment_id: payment.id,
38
+ amount,
39
+ note: input.reason,
40
+ });
41
+ logger.info(`Pay. - Recorded reversal of ${payment.currency_code} ${amount} on payment ${payment.id} for order ${input.orderId}: ${input.reason}`);
42
+ }
43
+ else {
44
+ logger.info(`Pay. - Payment ${payment.id} for order ${input.orderId} is already fully reversed`);
45
+ }
46
+ // Same bookkeeping as refundPaymentWorkflow: one negative transaction per
47
+ // refund. Refunds made earlier through the admin already have theirs.
48
+ const existingTransactions = await orderModuleService.listOrderTransactions({ order_id: input.orderId }, { select: ["reference", "reference_id"] });
49
+ const knownRefundIds = new Set(existingTransactions
50
+ .filter((transaction) => transaction.reference === "refund")
51
+ .map((transaction) => transaction.reference_id));
52
+ const missingTransactions = (payment.refunds ?? [])
53
+ .filter((refund) => !knownRefundIds.has(refund.id))
54
+ .map((refund) => ({
55
+ order_id: input.orderId,
56
+ amount: new utils_1.BigNumber(utils_1.MathBN.mult(refund.amount, -1)).numeric,
57
+ currency_code: payment.currency_code,
58
+ reference: "refund",
59
+ reference_id: refund.id,
60
+ }));
61
+ if (missingTransactions.length) {
62
+ await orderModuleService.addOrderTransactions(missingTransactions);
63
+ }
64
+ // Recording the refund recomputes the collection status from the captured
65
+ // amount (back to completed), so the failure is applied afterwards
66
+ await paymentModuleService.updatePaymentCollections(input.paymentCollectionId, { status: utils_1.PaymentCollectionStatus.FAILED });
67
+ const { result } = await (0, core_flows_1.createOrUpdateOrderPaymentCollectionWorkflow)(container).run({ input: { order_id: input.orderId } });
68
+ const collections = Array.isArray(result) ? result : result ? [result] : [];
69
+ logger.info(`Pay. - Order ${input.orderId} is payable again through payment collection ${collections.map((collection) => collection.id).join(", ") || "(none)"}`);
70
+ }
71
+ exports.default = reverseCapturedPayment;
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV2ZXJzZUNhcHR1cmVkUGF5bWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9yZXZlcnNlQ2FwdHVyZWRQYXltZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaURBLHdEQWtGQztBQW5JRCxxREFBaUY7QUFDakYscURBTWtDO0FBaUJsQyxNQUFNLFVBQVUsR0FBRyxDQUFDLEtBQTZDLEVBQUUsRUFBRSxDQUNuRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQ2xCLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsY0FBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUMvQyxjQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUNsQixDQUFBO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNJLEtBQUssVUFBVSxzQkFBc0IsQ0FDMUMsU0FBMEIsRUFDMUIsS0FBa0M7SUFFbEMsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBUyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMxRSxNQUFNLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQzVDLGVBQU8sQ0FBQyxPQUFPLENBQ2hCLENBQUE7SUFDRCxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQzFDLGVBQU8sQ0FBQyxLQUFLLENBQ2QsQ0FBQTtJQUVELElBQUksT0FBTyxHQUFHLE1BQU0sb0JBQW9CLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7UUFDeEUsU0FBUyxFQUFFLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQztLQUNuQyxDQUFDLENBQUE7SUFFRixNQUFNLFdBQVcsR0FBRyxjQUFNLENBQUMsR0FBRyxDQUM1QixVQUFVLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUM1QixVQUFVLENB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