fix(medusa-payment-paypal): Should not throw when canceling already canceled payment (#1470)

This commit is contained in:
Adrien de Peretti
2022-05-19 18:28:51 +02:00
committed by GitHub
parent f17e44d88a
commit 58387936c9
3 changed files with 74 additions and 13 deletions

View File

@@ -27,7 +27,11 @@ export const PayPalMock = {
payments: {
AuthorizationsGetRequest: jest.fn().mockImplementation(() => {}),
AuthorizationsVoidRequest: jest.fn().mockImplementation(() => {}),
AuthorizationsVoidRequest: jest.fn().mockImplementation(() => {
return {
status: "VOIDED"
}
}),
AuthorizationsCaptureRequest: jest.fn().mockImplementation(() => {
return {
result: {
@@ -41,6 +45,8 @@ export const PayPalMock = {
result: {
id: "test",
},
status: "COMPLETED",
invoice_id: 'invoice_id',
body: null,
requestBody: function (d) {
this.body = d
@@ -74,11 +80,29 @@ export const PayPalMock = {
},
}
}),
OrdersGetRequest: jest.fn().mockImplementation(() => {
return {
result: {
id: "test",
},
OrdersGetRequest: jest.fn().mockImplementation((id) => {
switch (id) {
case "test-refund":
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",
},
}
}
}),
},

View File

@@ -310,7 +310,7 @@ describe("PaypalProviderService", () => {
"test_cap"
)
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(2)
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(3)
expect(result.id).toEqual("test")
})
@@ -338,9 +338,41 @@ describe("PaypalProviderService", () => {
PayPalMock.payments.AuthorizationsVoidRequest
).toHaveBeenCalledWith("test_auth")
expect(PayPalMock.orders.OrdersGetRequest).toHaveBeenCalledWith("test")
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(2)
expect(PayPalClientMock.execute).toHaveBeenCalledTimes(3)
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")
})
})
})

View File

@@ -1,4 +1,3 @@
import _ from "lodash"
import { humanizeAmount, zeroDecimalCurrencies } from "medusa-core-utils"
import PayPal from "@paypal/checkout-server-sdk"
import { PaymentService } from "medusa-interfaces"
@@ -72,7 +71,6 @@ class PayPalProviderService extends PaymentService {
return "requires_more"
case "VOIDED":
return "canceled"
// return "captured"
default:
return status
}
@@ -284,11 +282,18 @@ class PayPalProviderService extends PaymentService {
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* Cancels payment for paypal payment.
* @param {Payment} payment - payment object
* @returns {Promise<object>} canceled payment intent
*/
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 {
const { purchase_units } = payment.data
if (payment.captured_at) {
@@ -303,7 +308,7 @@ class PayPalProviderService extends PaymentService {
await this.paypal_.execute(request)
}
return this.retrievePayment(payment.data)
return await this.retrievePayment(payment.data)
} catch (error) {
throw error
}