feat(dashboard,core-flows,js-sdk,types,link-modules,payment): ability to copy payment link (#8630)
what: - enables a button to create a payment link when a payment delta is present - api to delete order payment collection - adds a pending amount to payment collections Note: Not the happiest with the decision on when to create a payment collection and when not to. The code should programatically create or delete payment collections currently to generate the right collection for the payment delta. Adding a more specific flow to create and manage a payment collection will help reduce this burden from the code path and onto CX/merchant. Another issue I found is that the payment collection status doesn't get updated when payment is complete as it still gets stuck to "authorized" state https://github.com/user-attachments/assets/037a10f9-3621-43c2-94ba-1ada4b0a041b
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export interface DeleteEntitiesStepType {
|
||||
moduleRegistrationName: string
|
||||
invokeMethod: string
|
||||
compensateMethod: string
|
||||
entityIdentifier?: string
|
||||
data: any[]
|
||||
}
|
||||
|
||||
export const deleteEntitiesStepId = "delete-entities-step"
|
||||
/**
|
||||
* This step deletes one or more entities.
|
||||
*/
|
||||
export const deleteEntitiesStep = createStep(
|
||||
deleteEntitiesStepId,
|
||||
async (input: DeleteEntitiesStepType, { container }) => {
|
||||
const {
|
||||
moduleRegistrationName,
|
||||
invokeMethod,
|
||||
compensateMethod,
|
||||
data = [],
|
||||
} = input
|
||||
|
||||
const module = container.resolve<any>(moduleRegistrationName)
|
||||
data.length ? await module[invokeMethod](data) : []
|
||||
|
||||
return new StepResponse(void 0, {
|
||||
entityIdentifiers: input.data,
|
||||
moduleRegistrationName,
|
||||
compensateMethod,
|
||||
})
|
||||
},
|
||||
async (compensateInput, { container }) => {
|
||||
const {
|
||||
entityIdentifiers = [],
|
||||
moduleRegistrationName,
|
||||
compensateMethod,
|
||||
} = compensateInput!
|
||||
|
||||
if (!entityIdentifiers?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const module = container.resolve<any>(moduleRegistrationName)
|
||||
|
||||
await module[compensateMethod](entityIdentifiers)
|
||||
}
|
||||
)
|
||||
@@ -65,13 +65,12 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
|
||||
|
||||
const paymentCollection = useRemoteQueryStep({
|
||||
entry_point: "payment_collection",
|
||||
fields: ["id"],
|
||||
fields: ["id", "status"],
|
||||
variables: {
|
||||
id: orderPaymentCollectionIds,
|
||||
status: [
|
||||
PaymentCollectionStatus.NOT_PAID,
|
||||
PaymentCollectionStatus.AWAITING,
|
||||
],
|
||||
filters: {
|
||||
id: orderPaymentCollectionIds,
|
||||
status: [PaymentCollectionStatus.NOT_PAID],
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
}).config({ name: "payment-collection-query" })
|
||||
@@ -81,10 +80,7 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
|
||||
const paymentCollectionData = transform(
|
||||
{ order, input },
|
||||
({ order, input }) => {
|
||||
const pendingPayment = MathBN.sub(
|
||||
order.summary.raw_current_order_total,
|
||||
order.summary.raw_original_order_total
|
||||
)
|
||||
const pendingPayment = order.summary.raw_pending_difference
|
||||
|
||||
if (MathBN.lte(pendingPayment, 0)) {
|
||||
throw new MedusaError(
|
||||
@@ -93,7 +89,10 @@ export const createOrderPaymentCollectionWorkflow = createWorkflow(
|
||||
)
|
||||
}
|
||||
|
||||
if (input.amount && MathBN.gt(input.amount, pendingPayment)) {
|
||||
if (
|
||||
input.amount &&
|
||||
MathBN.gt(input.amount ?? pendingPayment, pendingPayment)
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
`Cannot create a payment collection for amount greater than ${pendingPayment}`
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { PaymentCollectionDTO } from "@medusajs/types"
|
||||
import { MedusaError, Modules, PaymentCollectionStatus } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { removeRemoteLinkStep, useRemoteQueryStep } from "../../common"
|
||||
|
||||
/**
|
||||
* This step validates that the order doesn't have an active payment collection.
|
||||
*/
|
||||
export const throwUnlessStatusIsNotPaid = createStep(
|
||||
"validate-payment-collection",
|
||||
({ paymentCollection }: { paymentCollection: PaymentCollectionDTO }) => {
|
||||
if (paymentCollection.status !== PaymentCollectionStatus.NOT_PAID) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
`Can only delete payment collections where status is not_paid`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const deleteOrderPaymentCollectionsId =
|
||||
"delete-order-payment-collectionworkflow"
|
||||
/**
|
||||
* This workflow deletes one or more invites.
|
||||
*/
|
||||
export const deleteOrderPaymentCollections = createWorkflow(
|
||||
deleteOrderPaymentCollectionsId,
|
||||
(input: WorkflowData<{ id: string }>): WorkflowData<void> => {
|
||||
const paymentCollection = useRemoteQueryStep({
|
||||
entry_point: "payment_collection",
|
||||
fields: ["id", "status"],
|
||||
variables: { id: input.id },
|
||||
throw_if_key_not_found: true,
|
||||
list: false,
|
||||
}).config({ name: "payment-collection-query" })
|
||||
|
||||
throwUnlessStatusIsNotPaid({ paymentCollection })
|
||||
|
||||
removeRemoteLinkStep({
|
||||
[Modules.PAYMENT]: { payment_collection_id: input.id },
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -27,6 +27,7 @@ export * from "./create-shipment"
|
||||
export * from "./decline-order-change"
|
||||
export * from "./delete-order-change"
|
||||
export * from "./delete-order-change-actions"
|
||||
export * from "./delete-order-payment-collection"
|
||||
export * from "./exchange/begin-order-exchange"
|
||||
export * from "./exchange/cancel-begin-order-exchange"
|
||||
export * from "./exchange/cancel-exchange"
|
||||
|
||||
Reference in New Issue
Block a user