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>