fix: allow swaps with total < 0 (#143)

This commit is contained in:
Sebastian Rindom
2020-12-02 17:37:46 +01:00
committed by GitHub
parent 454504cdf4
commit 304431e7c3
5 changed files with 130 additions and 55 deletions

View File

@@ -477,7 +477,7 @@ class BrightpearlService extends BaseService {
const soId =
fromSwap.metadata && fromSwap.metadata.brightpearl_sales_order_id
if (!soId) {
if (!soId || fromSwap.amount_paid <= 0) {
return
}
@@ -558,6 +558,10 @@ class BrightpearlService extends BaseService {
const order = await client.orders.retrieve(salesOrderId)
await client.warehouses.createReservation(order, this.options.warehouse)
const total = order.rows.reduce((acc, next) => {
return acc + parseFloat(next.net) + parseFloat(next.tax)
}, 0)
const paymentMethod = fromOrder.payment_method
const paymentType = "RECEIPT"
const payment = {
@@ -566,7 +570,7 @@ class BrightpearlService extends BaseService {
paymentMethodCode: this.options.payment_method_code || "1220",
orderId: salesOrderId,
currencyIsoCode: fromOrder.currency_code,
amountPaid: fromSwap.return.refund_amount,
amountPaid: total,
paymentDate: new Date(),
paymentType,
}

View File

@@ -128,8 +128,8 @@ export default app => {
* Captures the payment associated with a swap
*/
route.post(
"/:id/swaps/:swap_id/capture",
middlewares.wrap(require("./capture-swap").default)
"/:id/swaps/:swap_id/process-payment",
middlewares.wrap(require("./process-swap-payment").default)
)
/**

View File

@@ -7,7 +7,7 @@ export default async (req, res) => {
const order = await orderService.retrieve(id)
await swapService.capturePayment(swap_id)
await swapService.processDifference(swap_id)
// Decorate the order
const data = await orderService.decorate(

View File

@@ -25,6 +25,7 @@ class SwapModel extends BaseModel {
amount_paid: { type: Number },
region_id: { type: String },
currency_code: { type: String },
order_payment: { type: PaymentMethodSchema },
order_id: { type: String },
cart_id: { type: String },
created: { type: String, default: Date.now },

View File

@@ -12,6 +12,8 @@ class SwapService extends BaseService {
PAYMENT_COMPLETED: "swap.payment_completed",
PAYMENT_CAPTURED: "swap.payment_captured",
PAYMENT_CAPTURE_FAILED: "swap.payment_capture_failed",
PROCESS_REFUND_FAILED: "swap.process_refund_failed",
REFUND_PROCESSED: "swap.refund_processed",
}
constructor({
@@ -189,6 +191,7 @@ class SwapService extends BaseService {
return this.swapModel_.create({
order_id: order._id,
order_payment: order.payment_method,
region_id: order.region_id,
currency_code: order.currency_code,
return_items: validatedReturnItems,
@@ -197,6 +200,70 @@ class SwapService extends BaseService {
})
}
async processDifference(swapId) {
const swap = await this.retrieve(swapId)
if (!swap.is_paid) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
"Cannot process a swap that hasn't been confirmed by the customer"
)
}
if (swap.amount_paid < 0) {
const { provider_id, data } = swap.order_payment
const paymentProvider = this.paymentProviderService_.retrieveProvider(
provider_id
)
try {
await paymentProvider.refundPayment(data, -1 * swap.amount_paid)
} catch (err) {
return this.swapModel_
.updateOne(
{
_id: swapId,
},
{
$set: { payment_status: "requires_action" },
}
)
.then(result => {
this.eventBus_.emit(
SwapService.Events.PROCESS_REFUND_FAILED,
result
)
return result
})
}
return this.swapModel_
.updateOne(
{
_id: swapId,
},
{
$set: { payment_status: "difference_refunded" },
}
)
.then(result => {
this.eventBus_.emit(SwapService.Events.REFUND_PROCESSED, result)
return result
})
} else if (swap.amount_paid === 0) {
return this.swapModel_.updateOne(
{
_id: swapId,
},
{
$set: { payment_status: "difference_refunded" },
}
)
}
return capturePayment(swapId)
}
async capturePayment(swapId) {
const swap = await this.retrieve(swapId)
@@ -351,61 +418,64 @@ class SwapService extends BaseService {
)
}
let paymentSession = {}
let paymentData = {}
const { payment_method, payment_sessions } = cart
if (!payment_method) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Cart does not contain a payment method"
)
}
if (!payment_sessions || !payment_sessions.length) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"cart must have payment sessions"
)
}
paymentSession = payment_sessions.find(
ps => ps.provider_id === payment_method.provider_id
)
// Throw if payment method does not exist
if (!paymentSession) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Cart does not have an authorized payment session"
)
}
const paymentProvider = this.paymentProviderService_.retrieveProvider(
paymentSession.provider_id
)
const paymentStatus = await paymentProvider.getStatus(paymentSession.data)
// If payment status is not authorized, we throw
if (paymentStatus !== "authorized" && paymentStatus !== "succeeded") {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Payment method is not authorized"
)
}
paymentData = await paymentProvider.retrievePayment(paymentSession.data)
const total = await this.totalsService_.getTotal(cart)
let payment = {}
if (paymentSession.provider_id) {
payment = {
provider_id: paymentSession.provider_id,
data: paymentData,
if (total > 0) {
let paymentSession = {}
let paymentData = {}
const { payment_method, payment_sessions } = cart
if (!payment_method) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Cart does not contain a payment method"
)
}
if (!payment_sessions || !payment_sessions.length) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"cart must have payment sessions"
)
}
paymentSession = payment_sessions.find(
ps => ps.provider_id === payment_method.provider_id
)
// Throw if payment method does not exist
if (!paymentSession) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Cart does not have an authorized payment session"
)
}
const paymentProvider = this.paymentProviderService_.retrieveProvider(
paymentSession.provider_id
)
const paymentStatus = await paymentProvider.getStatus(paymentSession.data)
// If payment status is not authorized, we throw
if (paymentStatus !== "authorized" && paymentStatus !== "succeeded") {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Payment method is not authorized"
)
}
paymentData = await paymentProvider.retrievePayment(paymentSession.data)
if (paymentSession.provider_id) {
payment = {
provider_id: paymentSession.provider_id,
data: paymentData,
}
}
}
const total = await this.totalsService_.getTotal(cart)
return this.swapModel_
.updateOne(
{ _id: swap._id },