diff --git a/pass/app/Key.js b/pass/app/Key.js
index d83f77d830c93d6199537688500bc59a00b9c354..9c81819779eadd4dd8dc861142d7bbf25d469a6d 100644
--- a/pass/app/Key.js
+++ b/pass/app/Key.js
@@ -197,7 +197,7 @@ class Key {
     if (discharged_amount !== null) {
       return discharged_amount;
     } else {
-      throw new Error(`Cannot find order ${order_id} for discharge`);
+      return 0;
     }
   }
 
diff --git a/pass/app/PaymentReference.js b/pass/app/PaymentReference.js
index 54d02ca2a797274322073827770bf910aa3705b7..67f40f7331c171e99495d8f47f5f41ec78df397b 100644
--- a/pass/app/PaymentReference.js
+++ b/pass/app/PaymentReference.js
@@ -197,7 +197,7 @@ class PaymentReference {
       }
       resolve(
         parseInt(matcher[2]) -
-          config.get("price.number_range.payment_reference")
+        config.get("price.number_range.payment_reference")
       );
     });
   }
@@ -293,11 +293,19 @@ class PaymentReference {
         let charge_amount = Math.round(
           (payment.price / this.price) * this.amount
         );
-        key.charge_key_order(
-          charge_amount,
-          payment.public_id,
-          dayjs().add(config.get("keys.expiration_days"), "days")
-        );
+        if (charge_amount > 0) {
+          key.charge_key_order(
+            charge_amount,
+            this.public_id,
+            dayjs().add(config.get("keys.expiration_days"), "days")
+          );
+        } else {
+          key.discharge_key(
+            Math.abs(charge_amount),
+            this.public_id,
+            dayjs().add(config.get("keys.expiration_days"), "days")
+          );
+        }
         return key.save().then(() => payment);
       });
     });
diff --git a/pass/app/payment_processor/Paypal.js b/pass/app/payment_processor/Paypal.js
index e570ec020616863cf8b5d82f7c5eeb27b3439f5a..c8d1341ff8ce865b15bc56f186d1b20cd7864505 100644
--- a/pass/app/payment_processor/Paypal.js
+++ b/pass/app/payment_processor/Paypal.js
@@ -156,7 +156,7 @@ class Paypal extends PaymentProcessor {
         if (
           response_data.status !== "COMPLETED" ||
           response_data.purchase_units[0].payments.captures[0].status !==
-            "COMPLETED"
+          "COMPLETED"
         ) {
           console.error(JSON.stringify(response_data));
           throw "PAYMENT_NOT_COMPLETED_ERROR";
@@ -258,15 +258,39 @@ class Paypal extends PaymentProcessor {
           }
         );
       } else if (webhook_event.event_type === "CHECKOUT.ORDER.APPROVED") {
-        let order_id = webhook_event.resource.purchase_units[0].invoice_id;
-        if (!order_id) {
+        // Check for a completed payment that did not get processed by us
+        let payment_reference = webhook_event.resource.invoice_id;
+        if (!payment_reference) {
           throw "No Order ID attached";
-        } else {
-          order_id = order_id.replace(/^INV_/, "");
         }
-        return Order.LOAD_ORDER_FROM_ID(order_id).then(
-          /** @param {Order} order */ (order) => order.captureOrder()
-        );
+        return PaymentReference.LOAD_FROM_PUBLIC_ID(payment_reference).then(
+          (payment_reference) => {
+            let order = webhook_event.resource;
+            let payment_promises = [];
+            for (let i = 0; i < order.purchase_units.length; i++) {
+              let purchase_unit = order.purchase_units[i];
+              for (let j = 0; j < purchase_unit.payments.captures.length; j++) {
+                let capture = purchase_unit.payments.captures[j];
+                if (
+                  capture.status !== "COMPLETED" ||
+                  capture.amount.currency_code !== "EUR"
+                ) {
+                  continue;
+                }
+                payment_promises.push(
+                  payment_reference.createPayment({
+                    price: parseFloat(capture.amount.value),
+                    converted_price: parseFloat(capture.amount.value),
+                    converted_currency: capture.amount.currency_code,
+                    payment_reference_id: payment_reference.id,
+                    payment_processor: Paypal.NAME,
+                    payment_processor_id: capture.id,
+                    payment_processor_data: capture,
+                  })
+                );
+              }
+            }
+          });
       } else {
         console.log(req.body);
         throw "Webhook not implemented";
diff --git a/pass/routes/orders/orders.js b/pass/routes/orders/orders.js
index bf84f2dc8d5a2d2e54e746b50c8e8cfc2316c397..1f0188c46123dd2facb0e3365bd9b0d919ad66f4 100644
--- a/pass/routes/orders/orders.js
+++ b/pass/routes/orders/orders.js
@@ -119,7 +119,6 @@ router.use(
         req.data.order.payments = payments;
 
         req.data.css.push(`${res.locals.baseDir}/styles/orders/order.css`);
-        req.data.js.push(`${res.locals.baseDir}/js/orders.js`);
         req.data.links.order_url = `${res.locals.baseDir
           }/key/${req.data.key.key.get_key()}/orders/${queryData.payment_reference.public_id
           }#order`;
diff --git a/pass/routes/orders/refund.js b/pass/routes/orders/refund.js
index 35015e525d1b4242a3be898bf0d8e8601174df40..59d8f96b1c17c8b7849f3d72162b2a42c4296106 100644
--- a/pass/routes/orders/refund.js
+++ b/pass/routes/orders/refund.js
@@ -6,7 +6,7 @@ const Key = require("../../app/Key");
 
 // Base URL: /key/:key/orders/:order/refund
 router.use("/", (req, res, next) => {
-  let refund_count = req.data.order.payment_reference.key.get_charge(req.data.order.payment.public_id);
+  let refund_count = req.data.order.payment_reference.key.get_charge(req.data.order.payment_reference.public_id);
   let payment_count = Math.round((req.data.order.payment.price / req.data.order.payment_reference.price) * req.data.order.payment_reference.amount);
   req.data.order.refund = {
     count: refund_count,
@@ -71,7 +71,7 @@ router.post("/", (req, res, next) => {
         }
       })
       .then((key) => {
-        key.discharge_key(req.data.order.refund.count, req.data.order.payment.public_id);
+        key.discharge_key(req.data.order.refund.count, req.data.order.payment_reference.public_id);
         return key.save();
       })
       .then((new_key) => {
diff --git a/pass/views/orders/order_details.ejs b/pass/views/orders/order_details.ejs
index 45a618764f93df9828f721a7eaae3944ab0da3d7..9edf6af8251ffb4cce1c1971501899a4fe04d8aa 100644
--- a/pass/views/orders/order_details.ejs
+++ b/pass/views/orders/order_details.ejs
@@ -33,7 +33,7 @@
       <span><%= req.t("summary.actions.download-receipt", {ns: "order"}) _%></span>
     </a>
     <%_ } _%>
-    <%_ if (payment_reference.key.get_charge(payment.public_id) > 0 && payment.isRefundAllowed()) { _%>
+    <%_ if (payment_reference.key.get_charge(payment_reference.public_id) > 0 && payment.isRefundAllowed()) { _%>
     <a href="<%= links.order_actions_base + "/" + payment.public_id %>/refund" class="button">
       <img src="<%= baseDir _%>/images/money.svg" alt="" />
       <span><%= req.t("summary.actions.refund", {ns: "order"}) _%></span>