Procházet zdrojové kódy

fix(payments-plugin): Idempotent 'paid' Mollie webhooks (#2462)

Martijn před 2 roky
rodič
revize
2f7a8d5f58

+ 10 - 8
packages/payments-plugin/src/mollie/mollie.helpers.ts

@@ -61,14 +61,16 @@ export function toMollieOrderLines(order: Order, alreadyPaid: number): CreatePar
         vatAmount: toAmount(surcharge.priceWithTax - surcharge.price, order.currencyCode),
         vatAmount: toAmount(surcharge.priceWithTax - surcharge.price, order.currencyCode),
     })));
     })));
     // Deduct amount already paid
     // Deduct amount already paid
-    lines.push({
-        name: 'Already paid',
-        quantity: 1,
-        unitPrice: toAmount(-alreadyPaid, order.currencyCode),
-        totalAmount: toAmount(-alreadyPaid, order.currencyCode),
-        vatRate: String(0),
-        vatAmount: toAmount(0, order.currencyCode),
-    });
+    if (alreadyPaid) {
+        lines.push({
+            name: 'Already paid',
+            quantity: 1,
+            unitPrice: toAmount(-alreadyPaid, order.currencyCode),
+            totalAmount: toAmount(-alreadyPaid, order.currencyCode),
+            vatRate: String(0),
+            vatAmount: toAmount(0, order.currencyCode),
+        });
+    }
     return lines;
     return lines;
 }
 }
 
 

+ 7 - 7
packages/payments-plugin/src/mollie/mollie.service.ts

@@ -227,6 +227,13 @@ export class MollieService {
                 `Unable to find order ${mollieOrder.orderNumber}, unable to process Mollie order ${mollieOrder.id}`,
                 `Unable to find order ${mollieOrder.orderNumber}, unable to process Mollie order ${mollieOrder.id}`,
             );
             );
         }
         }
+        if (order.state === 'PaymentSettled') {
+            Logger.info(
+                `Order ${order.code} is already 'PaymentSettled', no need for handling Mollie status '${mollieOrder.status}'`,
+                loggerCtx,
+            );
+            return;
+        }
         if (mollieOrder.status === OrderStatus.expired) {
         if (mollieOrder.status === OrderStatus.expired) {
             // Expired is fine, a customer can retry the payment later
             // Expired is fine, a customer can retry the payment later
             return;
             return;
@@ -248,13 +255,6 @@ export class MollieService {
         if (order.state === 'PaymentAuthorized' && mollieOrder.status === OrderStatus.completed) {
         if (order.state === 'PaymentAuthorized' && mollieOrder.status === OrderStatus.completed) {
             return this.settleExistingPayment(ctx, order, mollieOrder.id);
             return this.settleExistingPayment(ctx, order, mollieOrder.id);
         }
         }
-        if (order.state === 'PaymentAuthorized' || order.state === 'PaymentSettled') {
-            Logger.info(
-                `Order ${order.code} is '${order.state}', no need for handling Mollie status '${mollieOrder.status}'`,
-                loggerCtx,
-            );
-            return;
-        }
         // Any other combination of Mollie status and Vendure status indicates something is wrong.
         // Any other combination of Mollie status and Vendure status indicates something is wrong.
         throw Error(
         throw Error(
             `Unhandled incoming Mollie status '${mollieOrder.status}' for order ${order.code} with status '${order.state}'`,
             `Unhandled incoming Mollie status '${mollieOrder.status}' for order ${order.code} with status '${order.state}'`,