fix(medusa-payment-paypal): Should not throw when canceling already canceled payment (#1470)
This commit is contained in:
@@ -27,7 +27,11 @@ export const PayPalMock = {
|
|||||||
|
|
||||||
payments: {
|
payments: {
|
||||||
AuthorizationsGetRequest: jest.fn().mockImplementation(() => {}),
|
AuthorizationsGetRequest: jest.fn().mockImplementation(() => {}),
|
||||||
AuthorizationsVoidRequest: jest.fn().mockImplementation(() => {}),
|
AuthorizationsVoidRequest: jest.fn().mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
status: "VOIDED"
|
||||||
|
}
|
||||||
|
}),
|
||||||
AuthorizationsCaptureRequest: jest.fn().mockImplementation(() => {
|
AuthorizationsCaptureRequest: jest.fn().mockImplementation(() => {
|
||||||
return {
|
return {
|
||||||
result: {
|
result: {
|
||||||
@@ -41,6 +45,8 @@ export const PayPalMock = {
|
|||||||
result: {
|
result: {
|
||||||
id: "test",
|
id: "test",
|
||||||
},
|
},
|
||||||
|
status: "COMPLETED",
|
||||||
|
invoice_id: 'invoice_id',
|
||||||
body: null,
|
body: null,
|
||||||
requestBody: function (d) {
|
requestBody: function (d) {
|
||||||
this.body = d
|
this.body = d
|
||||||
@@ -74,11 +80,29 @@ export const PayPalMock = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
OrdersGetRequest: jest.fn().mockImplementation(() => {
|
OrdersGetRequest: jest.fn().mockImplementation((id) => {
|
||||||
return {
|
switch (id) {
|
||||||
result: {
|
case "test-refund":
|
||||||
id: "test",
|
return {
|
||||||
},
|
result: {
|
||||||
|
id: "test-refund",
|
||||||
|
status: "COMPLETED",
|
||||||
|
invoice_id: "invoice_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "test-voided":
|
||||||
|
return {
|
||||||
|
result: {
|
||||||
|
id: "test-voided",
|
||||||
|
status: "VOIDED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
result: {
|
||||||
|
id: "test",
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ describe("PaypalProviderService", () => {
|
|||||||
"test_cap"
|
"test_cap"
|
||||||
)
|
)
|
||||||
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
|
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
|
||||||
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(2)
|
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(3)
|
||||||
|
|
||||||
expect(result.id).toEqual("test")
|
expect(result.id).toEqual("test")
|
||||||
})
|
})
|
||||||
@@ -338,9 +338,41 @@ describe("PaypalProviderService", () => {
|
|||||||
PayPalMock.payments.AuthorizationsVoidRequest
|
PayPalMock.payments.AuthorizationsVoidRequest
|
||||||
).toHaveBeenCalledWith("test_auth")
|
).toHaveBeenCalledWith("test_auth")
|
||||||
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
|
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
|
||||||
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(2)
|
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(3)
|
||||||
|
|
||||||
expect(result.id).toEqual("test")
|
expect(result.id).toEqual("test")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should return the order if already canceled", async () => {
|
||||||
|
result = await paypalProviderService.cancelPayment({
|
||||||
|
currency_code: "eur",
|
||||||
|
data: { id: "test-voided" },
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(PayPalMock.payments.AuthorizationsVoidRequest).not.toHaveBeenCalled()
|
||||||
|
expect(PayPalMock.payments.CapturesRefundRequest).not.toHaveBeenCalled()
|
||||||
|
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test-voided")
|
||||||
|
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(1)
|
||||||
|
|
||||||
|
expect(result.id).toEqual("test-voided")
|
||||||
|
expect(result.status).toEqual("VOIDED")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return the order if already fully refund", async () => {
|
||||||
|
result = await paypalProviderService.cancelPayment({
|
||||||
|
currency_code: "eur",
|
||||||
|
data: {
|
||||||
|
id: "test-refund",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(PayPalMock.payments.AuthorizationsVoidRequest).not.toHaveBeenCalled()
|
||||||
|
expect(PayPalMock.payments.CapturesRefundRequest).not.toHaveBeenCalled()
|
||||||
|
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test-refund")
|
||||||
|
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(1)
|
||||||
|
|
||||||
|
expect(result.id).toEqual("test-refund")
|
||||||
|
expect(result.status).toEqual("COMPLETED")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import _ from "lodash"
|
|
||||||
import { humanizeAmount, zeroDecimalCurrencies } from "medusa-core-utils"
|
import { humanizeAmount, zeroDecimalCurrencies } from "medusa-core-utils"
|
||||||
import PayPal from "@paypal/checkout-server-sdk"
|
import PayPal from "@paypal/checkout-server-sdk"
|
||||||
import { PaymentService } from "medusa-interfaces"
|
import { PaymentService } from "medusa-interfaces"
|
||||||
@@ -72,7 +71,6 @@ class PayPalProviderService extends PaymentService {
|
|||||||
return "requires_more"
|
return "requires_more"
|
||||||
case "VOIDED":
|
case "VOIDED":
|
||||||
return "canceled"
|
return "canceled"
|
||||||
// return "captured"
|
|
||||||
default:
|
default:
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
@@ -284,11 +282,18 @@ class PayPalProviderService extends PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels payment for Stripe payment intent.
|
* Cancels payment for paypal payment.
|
||||||
* @param {object} paymentData - payment method data from cart
|
* @param {Payment} payment - payment object
|
||||||
* @returns {Promise<object>} canceled payment intent
|
* @returns {Promise<object>} canceled payment intent
|
||||||
*/
|
*/
|
||||||
async cancelPayment(payment) {
|
async cancelPayment(payment) {
|
||||||
|
const order = await this.retrievePayment(payment.data)
|
||||||
|
const isAlreadyCanceled = order.status === "VOIDED"
|
||||||
|
const isCanceledAndFullyRefund = order.status === "COMPLETED" && !!order.invoice_id
|
||||||
|
if (isAlreadyCanceled || isCanceledAndFullyRefund) {
|
||||||
|
return order
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { purchase_units } = payment.data
|
const { purchase_units } = payment.data
|
||||||
if (payment.captured_at) {
|
if (payment.captured_at) {
|
||||||
@@ -303,7 +308,7 @@ class PayPalProviderService extends PaymentService {
|
|||||||
await this.paypal_.execute(request)
|
await this.paypal_.execute(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.retrievePayment(payment.data)
|
return await this.retrievePayment(payment.data)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user