docs: fix broken links utility + uncaught broken links (#12637)

* fix broken links

* update broken links utility

* add missing payment evens

* generate llms

* fix segment link
This commit is contained in:
Shahed Nasser authored and GitHub committed 2025-05-28 17:13:27 +03:00
1 parent 9866baa852
commit 40e73c6ea2
64 files changed
+773864 -772891

No files matched your search

@@ -14,7 +14,7 @@ sdk.admin.upload.create(
// file uploaded as a binary string
{
name: "test.txt",
content: "test", // Should be the binary content of the file
content: "test", // Should be the binary string of the file
},
// file uploaded as a File object
new File(["test"], "test.txt", { type: "text/plain" })
@@ -25350,7 +25350,16 @@ paths:
'500':
$ref: '#/components/responses/500_error'
x-workflow: markPaymentCollectionAsPaid
x-events: []
x-events:
- name: payment.captured
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is captured.
deprecated: false
/admin/payments:
get:
operationId: GetPayments
@@ -26200,7 +26209,16 @@ paths:
'500':
$ref: '#/components/responses/500_error'
x-workflow: capturePaymentWorkflow
x-events: []
x-events:
- name: payment.captured
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is captured.
deprecated: false
/admin/payments/{id}/refund:
post:
operationId: PostPaymentsIdRefund
@@ -26292,7 +26310,16 @@ paths:
'500':
$ref: '#/components/responses/500_error'
x-workflow: refundPaymentWorkflow
x-events: []
x-events:
- name: payment.refunded
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is refunded.
deprecated: false
/admin/plugins:
get:
operationId: GetPlugins
@@ -49518,7 +49545,7 @@ paths:
// file uploaded as a binary string
{
name: "test.txt",
content: "test", // Should be the binary content of the file
content: "test", // Should be the binary string of the file
},
// file uploaded as a File object
new File(["test"], "test.txt", { type: "text/plain" })
@@ -81,4 +81,13 @@ post:
'500':
$ref: ../components/responses/500_error.yaml
x-workflow: markPaymentCollectionAsPaid
x-events: []
x-events:
- name: payment.captured
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is captured.
deprecated: false
@@ -76,4 +76,13 @@ post:
'500':
$ref: ../components/responses/500_error.yaml
x-workflow: capturePaymentWorkflow
x-events: []
x-events:
- name: payment.captured
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is captured.
deprecated: false
@@ -84,4 +84,13 @@ post:
'500':
$ref: ../components/responses/500_error.yaml
x-workflow: refundPaymentWorkflow
x-events: []
x-events:
- name: payment.refunded
payload: |-
```ts
{
id, // the ID of the payment
}
```
description: Emitted when a payment is refunded.
deprecated: false
@@ -12,7 +12,7 @@ In this chapter, you'll add a UI route to the admin dashboard that shows all [br
items={[
{
text: "Brands Module",
link: "/learn/customization/custom-features/modules"
link: "/learn/customization/custom-features/module"
},
]}
/>
@@ -11,7 +11,7 @@ const HomepageLinksSection = () => {
text: "Create your first application",
},
{
href: "/learn/customization",
href: "/learn/customization/custom-features/module",
text: "Build a Module",
},
{
+4
View File
@@ -32,6 +32,10 @@ const withMDX = mdx({
"user-guide": {
projectPath: path.resolve("..", "user-guide"),
},
api: {
projectPath: path.resolve("..", "api-reference"),
skipSlugValidation: true,
},
},
},
],
File diff suppressed because it is too large. Load diff
+111 -6
View File
@@ -4,8 +4,8 @@
const redirects = async () => {
return [
{
source: "/v2/:path*",
destination: "/:path*",
source: "/v2/learn/customization",
destination: "/learn/customization/custom-features",
permanent: true,
},
{
@@ -63,6 +63,11 @@ const redirects = async () => {
destination: "/learn/fundamentals/modules/commerce-modules",
permanent: true,
},
{
source: "/commerce-modules",
destination: "/learn/fundamentals/modules/commerce-modules",
permanent: true,
},
{
source: "/learn/advanced-development/architecture/infrastructure-modules",
destination: "/learn/fundamentals/modules/infrastructure-modules",
@@ -103,6 +108,11 @@ const redirects = async () => {
destination: "/learn/fundamentals/:path*",
permanent: true,
},
{
source: "/advanced-development/:path*",
destination: "/learn/fundamentals/:path*",
permanent: true,
},
{
source: "/learn/storefront-development/nextjs-starter",
destination: "/resources/nextjs-starter",
@@ -266,12 +276,12 @@ const redirects = async () => {
},
{
source: "/v1/modules/products/admin/manage-products",
destination: "/user-guides/products/edit",
destination: "/user-guide/products/edit",
permanent: true,
},
{
source: "/v1/plugins/overview",
destination: "/learn/integrations",
destination: "/resources/integrations",
permanent: true,
},
{
@@ -321,12 +331,12 @@ const redirects = async () => {
},
{
source: "/v1/modules/users/admin/manage-profile",
destination: "/user-guides/settings/profile",
destination: "/user-guide/settings/profile",
permanent: true,
},
{
source: "/v1/modules/customers/customer-groups",
destination: "/commerce-modules/customer",
destination: "/resources/commerce-modules/customer",
permanent: true,
},
{
@@ -369,6 +379,101 @@ const redirects = async () => {
destination: "/learn/fundamentals/workflows/errors",
permanent: true,
},
{
source: "/add-plugins/:path",
destination: "/v1/plugins/:path",
permanent: true,
},
{
source: "/usage/create-medusa-app",
destination: "/learn/installation",
permanent: true,
},
{
source: "/tutorial/set-up-your-development-environment",
destination: "/v1/development/backend/prepare-environmentt",
permanent: true,
},
{
source: "/api",
destination: "/v1/api",
permanent: true,
},
{
source: "/development/:path*",
destination: "/v1/development/:path*",
permanent: true,
},
{
source: "/modules/:path*",
destination: "/v1/modules/:path*",
permanent: true,
},
{
source: "/advanced/:path*",
destination: "/v1/development/overview",
permanent: true,
},
{
source: "/deployments/:path*",
destination: "/v1/deployments/:path*",
permanent: true,
},
{
source: "/guides/fulfillment-api",
destination: "/resources/commerce-modules/fulfillment",
permanent: true,
},
{
source: "/introduction",
destination: "/learn/introduction",
permanent: true,
},
{
source: "/admin/:path*",
destination: "/v1/admin/:path*",
permanent: true,
},
{
source: "/user-guide/regions/providers",
destination: "/user-guide/settings/regions",
permanent: true,
},
{
source: "/starters/gatsby-medusa-starter",
destination: "/resources/nextjs-starter",
permanent: true,
},
{
source: "/usage/configurations",
destination: "/learn/configurations/medusa-config",
permanent: true,
},
{
source: "/troubleshooting/:path",
destination: "/v1/troubleshooting/:path",
permanent: true,
},
{
source: "/quickstart/quick-start",
destination: "/learn/installation",
permanent: true,
},
{
source: "/guides/:path*",
destination: "/resources/how-to-tutorials",
permanent: true,
},
{
source: "/v2/:path*",
destination: "/:path*",
permanent: true,
},
{
source: "/js-client/:path*",
destination: "/resources/js-client/:path*",
permanent: true,
},
]
}
@@ -126,7 +126,7 @@ A table for the link is now created in the database. You can now retrieve and ma
When a customer is created, you also want to create a `Custom` record and set the `custom_name` property, then create a link between the `Customer` and `Custom` records.
To do that, you'll consume the [customersCreated](/resources/references/medusa-workflows/createCustomersWorkflow#customerscreated) hook of the [createCustomersWorkflow](/references/medusa-workflows/createCustomersWorkflow). This workflow is executed in the [Create Customer Admin API route](!api!/admin#customers_postcustomers)
To do that, you'll consume the [customersCreated](/references/medusa-workflows/createCustomersWorkflow#customerscreated) hook of the [createCustomersWorkflow](/references/medusa-workflows/createCustomersWorkflow). This workflow is executed in the [Create Customer Admin API route](!api!/admin#customers_postcustomers)
<Note title="Tip">
@@ -88,7 +88,7 @@ The Fulfillment Module has the following links to other modules:
</Table.Row>
<Table.Row>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
[StockLocation](/references/stock-location-next/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
</Table.Cell>
<Table.Cell>
[FulfillmentProvider](/references/fulfillment/models/FulfillmentProvider)
@@ -102,7 +102,7 @@ The Fulfillment Module has the following links to other modules:
</Table.Row>
<Table.Row>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
[StockLocation](/references/stock-location-next/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
</Table.Cell>
<Table.Cell>
[FulfillmentSet](/references/fulfillment/models/FulfillmentSet)
@@ -52,7 +52,6 @@ These rules are represented by the [ShippingOptionRule data model](/references/f
- `operator`: The operator used in the condition. For example:
- To allow multiple values, use the operator `in`, which validates that the provided values are in the rule’s values.
- To create a negation condition that considers `value` against the rule, use `nin`, which validates that the provided values aren’t in the rule’s values.
- Check out more operators in [this reference](/references/fulfillment/types/fulfillment.RuleOperatorType).
- `value`: One or more values.
![A diagram showcasing the relation between shipping option and shipping option rules.](https://res.cloudinary.com/dza7lstvk/image/upload/v1712331340/Medusa%20Resources/shipping-option-rule_oosopf.jpg)
@@ -41,7 +41,7 @@ Read-only links are used to query data across modules, but the relations aren't
[ProductVariant](/references/product/models/ProductVariant) in [Product Module](../../product/page.mdx)
</Table.Cell>
<Table.Cell>
[InventoryItem](/references/inventory/models/InventoryItem)
[InventoryItem](/references/inventory-next/models/InventoryItem)
</Table.Cell>
<Table.Cell>
Stored - many-to-many
@@ -52,10 +52,10 @@ Read-only links are used to query data across modules, but the relations aren't
</Table.Row>
<Table.Row>
<Table.Cell>
[InventoryLevel](/references/inventory/models/InventoryLevel)
[InventoryLevel](/references/inventory-next/models/InventoryLevel)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
[StockLocation](/references/stock-location-next/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
</Table.Cell>
<Table.Cell>
Read-only - has many
@@ -26,7 +26,7 @@ Once the merchant receives the returned items, they mark the return as received.
## Returned Items
The items to be returned are represented by the [ReturnItem data model](references/order/models/ReturnItem).
The items to be returned are represented by the [ReturnItem data model](/references/order/models/ReturnItem).
The `ReturnItem` model has two properties storing the item's quantity:
@@ -37,7 +37,7 @@ The `ReturnItem` model has two properties storing the item's quantity:
## Return Shipping Methods
A return has shipping methods used to return the items to the merchant. The shipping methods are represented by the [OrderShippingMethod data model](references/order/models/OrderShippingMethod).
A return has shipping methods used to return the items to the merchant. The shipping methods are represented by the [OrderShippingMethod data model](/references/order/models/OrderShippingMethod).
In the Medusa application, the shipping method for a return is created only from a shipping option, provided by the Fulfillment Module, that has the rule `is_return` enabled.
@@ -47,7 +47,7 @@ In the Medusa application, the shipping method for a return is created only from
The `refund_amount` property of the `Return` data model holds the amount a merchant must refund the customer.
The [OrderTransaction data model](references/order/models/OrderTransaction) represents the refunds made for the return.
The [OrderTransaction data model](/references/order/models/OrderTransaction) represents the refunds made for the return.
---
@@ -69,7 +69,7 @@ Read-only links are used to query data across modules, but the relations aren't
[ProductVariant](/references/product/models/ProductVariant)
</Table.Cell>
<Table.Cell>
[InventoryItem](/references/inventory/models/InventoryItem) in [Inventory Module](../../inventory/page.mdx)
[InventoryItem](/references/inventory-next/models/InventoryItem) in [Inventory Module](../../inventory/page.mdx)
</Table.Cell>
<Table.Cell>
Stored - many-to-many
@@ -123,7 +123,7 @@ In this case, a customer’s group must be in the `VIP` and `B2B` set of values
If you're managing promotions using [Medusa's workflows](../../../medusa-workflows-reference/page.mdx) or the API routes that use them, you can specify rules for the promotion or its [application method](../application-method/page.mdx).
For example, if you're creating a promotion using the [createPromotionsWorkflow](!resources!/references/medusa-workflows/createPromotionsWorkflow):
For example, if you're creating a promotion using the [createPromotionsWorkflow](/references/medusa-workflows/createPromotionsWorkflow):
```ts
const { result } = await createPromotionsWorkflow(container)
@@ -166,7 +166,7 @@ For most use cases, it's recommended to use [workflows](#using-workflows) instea
If you're managing promotions using the Promotion Module's service, you can specify rules for the promotion or its [application method](../application-method/page.mdx) in its methods.
For example, if you're creating a promotion with the [createPromotions](!resources!/references/promotion/createPromotions) method:
For example, if you're creating a promotion with the [createPromotions](/references/promotion/createPromotions) method:
```ts
const promotions = await promotionModuleService.createPromotions([
@@ -97,7 +97,7 @@ Read-only links are used to query data across modules, but the relations aren't
[SalesChannel](/references/sales-channel/models/SalesChannel)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
[StockLocation](/references/stock-location-next/models/StockLocation) in [Stock Location Module](../../stock-location/page.mdx)
</Table.Cell>
<Table.Cell>
Stored - many-to-many
@@ -41,7 +41,7 @@ Read-only links are used to query data across modules, but the relations aren't
[FulfillmentSet](/references/fulfillment/models/FulfillmentSet) in [Fulfillment Module](../../fulfillment/page.mdx)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation)
[StockLocation](/references/stock-location-next/models/StockLocation)
</Table.Cell>
<Table.Cell>
Stored - many-to-one
@@ -55,7 +55,7 @@ Read-only links are used to query data across modules, but the relations aren't
[FulfillmentProvider](/references/fulfillment/models/FulfillmentProvider) in [Fulfillment Module](../../fulfillment/page.mdx)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation)
[StockLocation](/references/stock-location-next/models/StockLocation)
</Table.Cell>
<Table.Cell>
Stored - many-to-many
@@ -66,10 +66,10 @@ Read-only links are used to query data across modules, but the relations aren't
</Table.Row>
<Table.Row>
<Table.Cell>
[InventoryLevel](/references/inventory/models/InventoryLevel) in [Inventory Module](../../inventory/page.mdx)
[InventoryLevel](/references/inventory-next/models/InventoryLevel) in [Inventory Module](../../inventory/page.mdx)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation)
[StockLocation](/references/stock-location-next/models/StockLocation)
</Table.Cell>
<Table.Cell>
Read-only - has many
@@ -83,7 +83,7 @@ Read-only links are used to query data across modules, but the relations aren't
[SalesChannel](/references/sales-channel/models/SalesChannel) in [Sales Channel Module](../../sales-channel/page.mdx)
</Table.Cell>
<Table.Cell>
[StockLocation](/references/stock-location/models/StockLocation)
[StockLocation](/references/stock-location-next/models/StockLocation)
</Table.Cell>
<Table.Cell>
Stored - many-to-many
@@ -59,7 +59,7 @@ Read-only links are used to query data across modules, but the relations aren't
The Store Module has a `Currency` data model that stores the supported currencies of a store. However, these currencies don't hold all the details of a currency, such as its name or symbol.
Instead, Medusa defines a read-only link between the [Currency Module](../../currency/page.mdx)'s `Currency` data model and the Store Module's `StoreCurrency` data model. This means you can retrieve the details of a store's supported currencies, but you don't manage the links in a pivot table in the database. The currencies of a store are determined by the `currency_code` of the [Currency](/references/store/models/Currency) data model in the Store Module (not in the Currency Module).
Instead, Medusa defines a read-only link between the [Currency Module](../../currency/page.mdx)'s `Currency` data model and the Store Module's `StoreCurrency` data model. This means you can retrieve the details of a store's supported currencies, but you don't manage the links in a pivot table in the database. The currencies of a store are determined by the `currency_code` of the [Currency](/references/store/models/StoreCurrency) data model in the Store Module (not in the Currency Module).
### Retrieve with Query
@@ -14,7 +14,7 @@ Refer to this [Medusa Admin User Guide](!user-guide!/settings/users) to learn ho
## Straightforward User Creation
To create a user, use the [create method of the User Module’s main service](/references/user/create):
To create a user, use the [createUsers method of the User Module’s main service](/references/user/createUsers):
```ts
const user = await userModuleService.createUsers({
@@ -213,7 +213,7 @@ You define the `Quote` data model using the `model.define` method of the DML. It
<Note>
Learn more about defining data model properties in the [Property Types documentation](/learn/fundamentals/data-models/property-types).
Learn more about defining data model properties in the [Property Types documentation](!docs!/learn/fundamentals/data-models/properties).
</Note>
@@ -3450,14 +3450,14 @@ You'll implement the quote acceptance logic in a workflow. The workflow has the
type: "workflow",
name: "confirmOrderEditRequestWorkflow",
description: "Confirm the changes made on the draft order, such as changes to item quantities and prices.",
link: "!resources!/references/medusa-workflows/confirmOrderEditRequestWorkflow",
link: "/references/medusa-workflows/confirmOrderEditRequestWorkflow",
depth: 1
},
{
type: "workflow",
name: "updateOrderWorkflow",
description: "Update the draft order to change its status and convert it into an order.",
link: "!resources!/references/medusa-workflows/updateOrderWorkflow",
link: "/references/medusa-workflows/updateOrderWorkflow",
depth: 1
}
]
+1 -1
View File
@@ -2389,7 +2389,7 @@ export const myWorkflow = createWorkflow(
)
```
Learn more in [this documentation](!book!/learn/fundamentals/workflows/add-workflow-hook).
Learn more in [this documentation](!docs!/learn/fundamentals/workflows/add-workflow-hook).
### Retry Steps
@@ -1293,7 +1293,7 @@ The workflow will have the following steps:
type: "workflow",
name: "updateCartPromotionsWorkflow",
description: "Update the cart's promotions with the new loyalty promotion.",
link: "/references/medusa-workflows/workflows/updateCartPromotionsWorkflow",
link: "/references/medusa-workflows/updateCartPromotionsWorkflow",
depth: 1,
},
{
@@ -1762,7 +1762,7 @@ The workflow will have the following steps:
type: "workflow",
name: "updateCartPromotionsWorkflow",
description: "Update the cart's promotions to remove the loyalty promotion.",
link: "/references/medusa-workflows/workflows/updateCartPromotionsWorkflow",
link: "/references/medusa-workflows/updateCartPromotionsWorkflow",
depth: 1,
},
{
@@ -106,9 +106,9 @@ For a full list of properties accepted, refer to [this guide](/references/notifi
---
## Using the sendNotifcationStep
## Using the sendNotificationsStep
If you want to send a notification as part of a workflow, You can use the [sendNotifcationStep](!resources!/references/medusa-workflows/steps/sendNotificationsStep) in your workflow.
If you want to send a notification as part of a workflow, You can use the [sendNotificationsStep](/references/medusa-workflows/steps/sendNotificationsStep) in your workflow.
For example:
@@ -150,7 +150,7 @@ export const sendEmailWorkflow = createWorkflow(
)
```
For a full list of input properties accepted, refer to the [sendNotifcationStep](!resources!/references/medusa-workflows/steps/sendNotificationsStep) reference.
For a full list of input properties accepted, refer to the [sendNotificationsStep](/references/medusa-workflows/steps/sendNotificationsStep) reference.
You can then execute this workflow in a subscriber, API route, or scheduled job.
@@ -192,7 +192,7 @@ Refer to the [Events Reference](/references/events) for a complete list of event
You can also send an email using SendGrid in any [workflow](!docs!/learn/fundamentals/workflows). This allows you to send emails within your custom flows.
You can use the [sendNotifcationStep](!resources!/references/medusa-workflows/steps/sendNotificationsStep) in your workflow to send an email using SendGrid.
You can use the [sendNotifcationStep](/references/medusa-workflows/steps/sendNotificationsStep) in your workflow to send an email using SendGrid.
For example:
@@ -138,7 +138,7 @@ The File Module has module providers that implement the underlying logic of hand
The Locking Module manages access to shared resources by multiple processes or threads. It prevents conflicts between processes and ensures data consistency. Refer to the [Locking Module documentation](./locking/page.mdx) to learn more about it.
The Locking Module uses module providers that implement the underlying logic of the locking mechanism. The following Locking Module Providers are provided by Medusa. You can also create a custom provider as explained in the [Create Locking Module Provider guide](/references/locking-provider-module).
The Locking Module uses module providers that implement the underlying logic of the locking mechanism. The following Locking Module Providers are provided by Medusa. You can also create a custom provider as explained in the [Create Locking Module Provider guide](/references/locking-module-provider).
<CardList
items={[
@@ -763,7 +763,7 @@ You create a step using `createStep` from the Workflows SDK. It accepts two para
1. The step's name, which is `get-magento-products`.
1. An async function that executes the step's logic. The function receives two parameters:
- The input data for the step, which in this case is the pagination parameters.
- An object holding the workflow's context, including the [Medusa Container](!docs!learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
- An object holding the workflow's context, including the [Medusa Container](!docs!/learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
In the step function, you resolve the Magento Module's service from the container, then use its `getProducts` method to retrieve the products from Magento.
@@ -1664,7 +1664,7 @@ To render a widget that matches the rest of the admin dashboard's design, you us
<Note>
Learn more about widgets in [this documentation](/learn/fundamentals/admin/widgets).
Refer to the [Admin Widgets](!docs!/learn/fundamentals/admin/widgets) documentation to learn more.
</Note>
@@ -1746,7 +1746,7 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
This adds a `POST` API route at `/admin/sanity/syncs`. In the route handler, you execute the `sanitySyncProductsWorkflow` without passing it a `product_ids` input. The step in the workflow will retrieve all products, instead of filtering them by ID, and sync them to Sanity.
You return the transaction ID of the workflow, which you can use to track the execution's progress since the workflow will run in the background. This is not implemented in this guide, but Medusa has a [Get Execution API route](!api!admin#workflows-executions_getworkflowsexecutionsworkflow_idtransaction_id) that you can use to get the details of a workflow's execution.
You return the transaction ID of the workflow, which you can use to track the execution's progress since the workflow will run in the background. This is not implemented in this guide, but Medusa has a [Get Execution API route](!api!/admin#workflows-executions_getworkflowsexecutionsworkflow_idtransaction_id) that you can use to get the details of a workflow's execution.
### Add Sanity UI Route
+1 -1
View File
@@ -27,7 +27,7 @@ An Analytics Module Provider tracks events and user behavior in your Medusa appl
title: "PostHog"
},
{
href: "/infrastructure-modules/analytics/segment",
href: "/integrations/guides/segment",
title: "Segment",
badge: {
variant: "blue",
+2 -2
View File
@@ -21,12 +21,12 @@ If you think this is a mistake, please [report this issue on GitHub](https://git
items={[
{
title: "Get Started Docs",
href: "/",
href: "!docs!/learn",
icon: BookOpen
},
{
title: "Commerce Modules",
href: "!resources!/commerce-modules",
href: "/commerce-modules",
icon: AcademicCapSolid
},
{
@@ -591,7 +591,7 @@ You create a step using `createStep` from the Workflows SDK. It accepts two para
1. The step's name, which is `validate-customer-create-wishlist`.
1. An async function that executes the step's logic. The function receives two parameters:
- The input data for the step, which in this case is an object having a `customer_id` property.
- An object holding the workflow's context, including the [Medusa Container](!docs!learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
- An object holding the workflow's context, including the [Medusa Container](!docs!/learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
In the step function, you use [Query](!docs!/learn/fundamentals/module-links/query) to retrieve the wishlist based on the specified customer ID. If a wishlist exists, you throw an error, stopping the workflow's execution.
@@ -1756,7 +1756,7 @@ The add-to-cart workflow for bundled products has the following steps:
type: "step",
description: "Add the items in the bundle to the cart.",
depth: 1,
link: "/references/workflows/addToCartWorkflow"
link: "/references/medusa-workflows/addToCartWorkflow"
},
{
name: "useQueryGraphStep",
@@ -2778,7 +2778,7 @@ The workflow has the following steps:
type: "workflow",
description: "Remove the items in the bundle from the cart.",
depth: 1,
link: "/references/workflows/removeFromCartWorkflow"
link: "/references/medusa-workflows/deleteLineItemsWorkflow"
},
{
name: "useQueryGraphStep",
@@ -64,7 +64,7 @@ This approach allows you to interact with the third-party service within custom
You can also automate sending notifications to customers when changes happen related to their orders, returns, exchanges, and more.
Medusa's Notification Module allows you to send notifications when an event is triggered, such as when a customer's order is updated. You can use third-party services, like [SendGrid](../../infrastructure-modules/notification/sendgrid), to send emails to customers.
Medusa's Notification Module allows you to send notifications when an event is triggered, such as when a customer's order is updated. You can use third-party services, like [SendGrid](../../infrastructure-modules/notification/sendgrid/page.mdx), to send emails to customers.
<CardList items={[
{
@@ -156,7 +156,7 @@ Medusa's commerce features are geared towards automating RMA flows and ensuring
<CardList items={[
{
href: "/commerce-modules/orders",
href: "/commerce-modules/order",
title: "Order Module",
text: "Learn about the Order Module and its features.",
icon: AcademicCapSolid,
@@ -572,7 +572,7 @@ You create a step using `createStep` from the Workflows SDK. It accepts two para
1. The step's name, which is `get-products-from-erp`.
2. An async function that executes the step's logic. The function receives two parameters:
- The input data for the step, which are the pagination fields `offset` and `limit`.
- An object holding the workflow's context, including the [Medusa Container](!docs!learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
- An object holding the workflow's context, including the [Medusa Container](!docs!/learn/fundamentals/medusa-container) that allows you to resolve Framework and commerce tools.
In this step, you resolve the Odoo Module's service from the container and use its `listProducts` method to fetch products from Odoo. You pass the pagination options from the input data to the method.
+1 -1
View File
@@ -468,7 +468,7 @@ Then, for each product variant, you use a `canCompanyPurchaseProduct` method in
So, only customers who are allowed in the ERP system to purchase a product can add it to the cart.
Learn more about workflow hooks and how to consume them in [this documentation](/docs/learn/fundamentals/workflows/workflow-hooks).
Learn more about workflow hooks and how to consume them in [this documentation](!docs!/learn/fundamentals/workflows/workflow-hooks).
---
@@ -34,7 +34,7 @@ During checkout, Medusa calculates the taxes using the tax region settings of th
<CardList items={[
{
href: "!user-guides!/settings/tax-regions",
href: "!user-guide!/settings/tax-regions",
title: "Using Medusa Admin",
text: "Learn how to manage tax regions in the Medusa Admin",
icon: UsersSolid,
+3 -3
View File
@@ -78,7 +78,7 @@ In addition, you can create a subscriber that listens to fulfillment-related eve
icon: AcademicCapSolid,
},
{
href: "/commerce-modules/order/events",
href: "/references/order/events",
title: "Order Events",
text: "Learn about the events emitted related to the Order Module",
icon: AcademicCapSolid,
@@ -109,7 +109,7 @@ In addition, you can create a subscriber that listen to payment-related events,
icon: AcademicCapSolid,
},
{
href: "/commerce-modules/payment/events",
href: "/references/payment/events",
title: "Payment Events",
text: "Learn about the events emitted related to the Payment Module",
icon: AcademicCapSolid,
@@ -175,7 +175,7 @@ Medusa also emits events related to these actions, such as `order.return_request
icon: AcademicCapSolid,
},
{
href: "/commerce-modules/order/events",
href: "/references/order/events",
title: "Order Events",
text: "Learn about the events emitted related to the Order Module",
icon: AcademicCapSolid,
@@ -937,7 +937,7 @@ To support subscriptions, you need to support capturing the payment each time th
<Note title="Tip">
If you're using a custom payment provider, you can handle that additional data in the [initiatePayment method](!resources!/references/payment/provider#initiatepayment) of your provider's service.
If you're using a custom payment provider, you can handle that additional data in the [initiatePayment method](/references/payment/provider#initiatepayment) of your provider's service.
</Note>
@@ -18,7 +18,7 @@ After the customer completes the checkout process and places an order, you can s
## Retrieve Order Details
To show the order details, you need to retrieve the order by sending a request to the [Get an Order API route](!api!store#orders_getordersid).
To show the order details, you need to retrieve the order by sending a request to the [Get an Order API route](!api!/store#orders_getordersid).
You need the order's ID to retrieve the order. You can pass it from the [complete cart step](../complete-cart/page.mdx) or store it in the `localStorage`.
@@ -84,7 +84,7 @@ sdk.store.order.retrieve(orderId)
</CodeTab>
</CodeTabs>
In the above example, you retrieve the order's details from the [Get an Order API route](!api!store#orders_getordersid). Then, in the React example, you show the order details like the order ID, order date, and customer email.
In the above example, you retrieve the order's details from the [Get an Order API route](!api!/store#orders_getordersid). Then, in the React example, you show the order details like the order ID, order date, and customer email.
The rest of this guide will expand on the React example to show more order details.
@@ -33,7 +33,7 @@ For other types of frameworks or tech stacks, the steps are similar. Refer to [S
},
{
text: "Cart context in your storefront, which is used in a code snippet later.",
link: "/resources/storefront-development/cart/context"
link: "/storefront-development/cart/context"
},
]} />
+8 -5
View File
@@ -802,7 +802,7 @@ export const generatedEditDates = {
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.completeOrderWorkflow/page.mdx": "2025-05-22T12:22:25.498Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.createFulfillmentValidateOrder/page.mdx": "2025-05-20T07:51:40.825Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.createShipmentValidateOrder/page.mdx": "2025-05-20T07:51:40.829Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.refundPaymentWorkflow/page.mdx": "2025-05-22T12:22:26.662Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.refundPaymentWorkflow/page.mdx": "2025-05-28T13:08:49.632Z",
"references/core_flows/Payment/core_flows.Payment.Workflows_Payment/page.mdx": "2025-01-07T12:54:17.428Z",
"references/core_flows/Promotion/Steps_Promotion/functions/core_flows.Promotion.Steps_Promotion.updatePromotionsStep/page.mdx": "2025-04-11T09:04:41.156Z",
"references/core_flows/Promotion/Workflows_Promotion/functions/core_flows.Promotion.Workflows_Promotion.updatePromotionsWorkflow/page.mdx": "2025-05-22T12:22:27.490Z",
@@ -1815,7 +1815,7 @@ export const generatedEditDates = {
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.deleteOrderChangeWorkflow/page.mdx": "2025-05-22T12:22:25.652Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.deleteOrderPaymentCollections/page.mdx": "2025-05-22T12:22:25.659Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.getOrderDetailWorkflow/page.mdx": "2025-05-22T12:22:25.862Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.markPaymentCollectionAsPaid/page.mdx": "2025-05-22T12:22:25.884Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.markPaymentCollectionAsPaid/page.mdx": "2025-05-28T13:07:57.643Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.receiveAndCompleteReturnOrderWorkflow/page.mdx": "2025-05-22T12:22:26.249Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.receiveCompleteReturnValidationStep/page.mdx": "2025-05-20T07:51:40.837Z",
"references/core_flows/Order/Workflows_Order/functions/core_flows.Order.Workflows_Order.throwUnlessPaymentCollectionNotPaid/page.mdx": "2025-05-20T07:51:40.845Z",
@@ -1824,7 +1824,7 @@ export const generatedEditDates = {
"references/core_flows/Payment/Steps_Payment/functions/core_flows.Payment.Steps_Payment.cancelPaymentStep/page.mdx": "2025-01-13T17:30:25.526Z",
"references/core_flows/Payment/Steps_Payment/functions/core_flows.Payment.Steps_Payment.capturePaymentStep/page.mdx": "2025-01-17T16:43:24.790Z",
"references/core_flows/Payment/Steps_Payment/functions/core_flows.Payment.Steps_Payment.refundPaymentStep/page.mdx": "2025-01-17T16:43:24.798Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.capturePaymentWorkflow/page.mdx": "2025-05-22T12:22:26.611Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.capturePaymentWorkflow/page.mdx": "2025-05-28T13:08:12.045Z",
"references/core_flows/Payment_Collection/Steps_Payment_Collection/functions/core_flows.Payment_Collection.Steps_Payment_Collection.createPaymentSessionStep/page.mdx": "2025-05-22T12:22:26.707Z",
"references/core_flows/Payment_Collection/Steps_Payment_Collection/functions/core_flows.Payment_Collection.Steps_Payment_Collection.createRefundReasonStep/page.mdx": "2025-04-11T09:04:40.525Z",
"references/core_flows/Payment_Collection/Steps_Payment_Collection/functions/core_flows.Payment_Collection.Steps_Payment_Collection.deletePaymentSessionsStep/page.mdx": "2025-05-22T12:22:26.715Z",
@@ -2116,7 +2116,7 @@ export const generatedEditDates = {
"app/commerce-modules/order/order-change/page.mdx": "2024-10-09T09:59:40.745Z",
"app/commerce-modules/payment/links-to-other-modules/page.mdx": "2025-04-17T15:53:23.515Z",
"references/core_flows/Common/Steps_Common/functions/core_flows.Common.Steps_Common.useQueryGraphStep/page.mdx": "2025-04-11T09:04:35.943Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.processPaymentWorkflow/page.mdx": "2025-05-22T12:22:26.616Z",
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.processPaymentWorkflow/page.mdx": "2025-05-28T13:08:31.922Z",
"references/helper_steps/functions/helper_steps.useQueryGraphStep/page.mdx": "2025-01-17T16:43:22.242Z",
"references/order/IOrderModuleService/methods/order.IOrderModuleService.undoLastChange/page.mdx": "2025-05-20T07:51:40.984Z",
"references/order/interfaces/order.CreateOrderLineItemAdjustmentDTO/page.mdx": "2024-12-09T13:22:01.264Z",
@@ -6198,7 +6198,7 @@ export const generatedEditDates = {
"app/commerce-modules/product/guides/variant-inventory/page.mdx": "2025-04-25T14:22:42.329Z",
"app/troubleshooting/validation-error/page.mdx": "2025-04-25T14:14:57.568Z",
"app/integrations/guides/contentful/page.mdx": "2025-05-20T07:51:40.715Z",
"references/modules/events/page.mdx": "2025-05-20T07:51:40.958Z",
"references/modules/events/page.mdx": "2025-05-28T13:06:45.041Z",
"references/module_events/module_events.Auth/page.mdx": "2025-05-20T07:51:40.956Z",
"references/module_events/module_events.Cart/page.mdx": "2025-05-20T07:51:40.956Z",
"references/module_events/module_events.Customer/page.mdx": "2025-05-20T07:51:40.956Z",
@@ -6524,5 +6524,8 @@ export const generatedEditDates = {
"references/helper_steps/variables/helper_steps.deleteEntitiesStepId/page.mdx": "2025-05-22T12:22:22.848Z",
"references/js_sdk/admin/Upload/methods/js_sdk.admin.Upload.presignedUrl/page.mdx": "2025-05-22T12:22:45.318Z",
"references/types/types/types.CreateCartCreditLinesWorkflowInput/page.mdx": "2025-05-22T12:22:32.616Z",
"references/events/Payment/variables/events.Payment.PaymentEvents/page.mdx": "2025-05-28T13:06:45.060Z",
"references/events/events.Payment/page.mdx": "2025-05-28T13:06:45.059Z",
"references/module_events/module_events.Payment/page.mdx": "2025-05-28T13:06:45.066Z",
"app/integrations/guides/segment/page.mdx": "2025-05-26T14:46:22.757Z"
}
@@ -10075,6 +10075,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/references/events/Order/variables/events.Order.OrderWorkflowEvents/page.mdx",
"pathname": "/references/events/Order/variables/events.Order.OrderWorkflowEvents"
},
{
"filePath": "/www/apps/resources/references/events/Payment/variables/events.Payment.PaymentEvents/page.mdx",
"pathname": "/references/events/Payment/variables/events.Payment.PaymentEvents"
},
{
"filePath": "/www/apps/resources/references/events/Product/variables/events.Product.ProductCategoryWorkflowEvents/page.mdx",
"pathname": "/references/events/Product/variables/events.Product.ProductCategoryWorkflowEvents"
@@ -10139,6 +10143,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/references/events/events.Order/page.mdx",
"pathname": "/references/events/events.Order"
},
{
"filePath": "/www/apps/resources/references/events/events.Payment/page.mdx",
"pathname": "/references/events/events.Payment"
},
{
"filePath": "/www/apps/resources/references/events/events.Product/page.mdx",
"pathname": "/references/events/events.Product"
@@ -13691,6 +13699,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/references/module_events/module_events.Order/page.mdx",
"pathname": "/references/module_events/module_events.Order"
},
{
"filePath": "/www/apps/resources/references/module_events/module_events.Payment/page.mdx",
"pathname": "/references/module_events/module_events.Payment"
},
{
"filePath": "/www/apps/resources/references/module_events/module_events.Product/page.mdx",
"pathname": "/references/module_events/module_events.Product"
@@ -4939,6 +4939,11 @@ export const slugChanges = [
"newSlug": "/references/order/events",
"filePath": "/www/apps/resources/references/module_events/module_events.Order/page.mdx"
},
{
"origSlug": "/references/module_events/module_events.Payment",
"newSlug": "/references/payment/events",
"filePath": "/www/apps/resources/references/module_events/module_events.Payment/page.mdx"
},
{
"origSlug": "/references/module_events/module_events.Product",
"newSlug": "/references/product/events",
+11
View File
@@ -19,6 +19,13 @@ const withMDX = mdx({
[
brokenLinkCheckerPlugin,
{
rootBasePath: {
default: "app",
overrides: {
"/references": "",
},
},
hasGeneratedSlugs: true,
crossProjects: {
docs: {
projectPath: path.resolve("..", "book"),
@@ -30,6 +37,10 @@ const withMDX = mdx({
"user-guide": {
projectPath: path.resolve("..", "user-guide"),
},
api: {
projectPath: path.resolve("..", "api-reference"),
skipSlugValidation: true,
},
},
},
],
@@ -146,3 +146,55 @@ const myWorkflow = createWorkflow(
## Output
<TypeList types={[{"name":"null \\| PaymentDTO","type":"`null` \\| [PaymentDTO](../../../../../payment/interfaces/payment.PaymentDTO/page.mdx)","optional":false,"defaultValue":"","description":"","expandable":false,"children":[{"name":"null \\| PaymentDTO","type":"`null` \\| [PaymentDTO](../../../../../payment/interfaces/payment.PaymentDTO/page.mdx)","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" openedLevel={1} sectionTitle="markPaymentCollectionAsPaid"/>
## Emitted Events
This section lists the events that are either triggered by the `emitEventStep` in the workflow, or by another workflow executed within this workflow.
You can listen to these events in a subscriber, as explained in the [Subscribers](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) documentation.
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
Event
</Table.HeaderCell>
<Table.HeaderCell>
Description
</Table.HeaderCell>
<Table.HeaderCell>
Payload
</Table.HeaderCell>
<Table.HeaderCell>
Action
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`payment.captured`
</Table.Cell>
<Table.Cell>
Emitted when a payment is captured.
</Table.Cell>
<Table.Cell>
```ts blockStyle="inline"
{
id, // the ID of the payment
}
```
</Table.Cell>
<Table.Cell>
<CopyGeneratedSnippetButton tooltipText="Copy subscriber for event" type="subscriber" options={{
event: "payment.captured",
payload: `\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``
}}/>
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
@@ -140,3 +140,55 @@ const myWorkflow = createWorkflow(
## Output
<TypeList types={[{"name":"PaymentDTO","type":"[PaymentDTO](../../../../../payment/interfaces/payment.PaymentDTO/page.mdx)","optional":false,"defaultValue":"","description":"","expandable":false,"children":[{"name":"id","type":"`string`","description":"The ID of the payment.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"amount","type":"[BigNumberValue](../../../../../payment/types/payment.BigNumberValue/page.mdx)","description":"The payment's total amount.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"numeric","type":"`number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw","type":"[BigNumberRawValue](../../../../../payment/types/payment.BigNumberRawValue/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]},{"name":"bigNumber","type":"`BigNumber`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"currency_code","type":"`string`","description":"The ISO 3 character currency code of the payment.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"provider_id","type":"`string`","description":"The ID of the associated payment provider.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"payment_collection_id","type":"`string`","description":"The ID of the associated payment collection.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw_amount","type":"[BigNumberValue](../../../../../payment/types/payment.BigNumberValue/page.mdx)","description":"The raw amount of the payment.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"numeric","type":"`number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw","type":"[BigNumberRawValue](../../../../../payment/types/payment.BigNumberRawValue/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]},{"name":"bigNumber","type":"`BigNumber`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"authorized_amount","type":"[BigNumberValue](../../../../../payment/types/payment.BigNumberValue/page.mdx)","description":"The authorized amount of the payment.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"numeric","type":"`number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw","type":"[BigNumberRawValue](../../../../../payment/types/payment.BigNumberRawValue/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]},{"name":"bigNumber","type":"`BigNumber`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"raw_authorized_amount","type":"[BigNumberValue](../../../../../payment/types/payment.BigNumberValue/page.mdx)","description":"The raw authorized amount of the payment.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"numeric","type":"`number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw","type":"[BigNumberRawValue](../../../../../payment/types/payment.BigNumberRawValue/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]},{"name":"bigNumber","type":"`BigNumber`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"data","type":"`Record<string, unknown>`","description":"The data relevant for the payment provider to process the payment.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"created_at","type":"`string` \\| `Date`","description":"When the payment was created.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"updated_at","type":"`string` \\| `Date`","description":"When the payment was updated.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"captured_at","type":"`string` \\| `Date`","description":"When the payment was captured.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"canceled_at","type":"`string` \\| `Date`","description":"When the payment was canceled.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"captured_amount","type":"[BigNumberValue](..Line truncated
## Emitted Events
This section lists the events that are either triggered by the `emitEventStep` in the workflow, or by another workflow executed within this workflow.
You can listen to these events in a subscriber, as explained in the [Subscribers](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) documentation.
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
Event
</Table.HeaderCell>
<Table.HeaderCell>
Description
</Table.HeaderCell>
<Table.HeaderCell>
Payload
</Table.HeaderCell>
<Table.HeaderCell>
Action
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`payment.captured`
</Table.Cell>
<Table.Cell>
Emitted when a payment is captured.
</Table.Cell>
<Table.Cell>
```ts blockStyle="inline"
{
id, // the ID of the payment
}
```
</Table.Cell>
<Table.Cell>
<CopyGeneratedSnippetButton tooltipText="Copy subscriber for event" type="subscriber" options={{
event: "payment.captured",
payload: `\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``
}}/>
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
@@ -206,6 +206,31 @@ order.
{
id, // The ID of the order
}
\`\`\``
}}/>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`payment.captured`
</Table.Cell>
<Table.Cell>
Emitted when a payment is captured.
</Table.Cell>
<Table.Cell>
```ts blockStyle="inline"
{
id, // the ID of the payment
}
```
</Table.Cell>
<Table.Cell>
<CopyGeneratedSnippetButton tooltipText="Copy subscriber for event" type="subscriber" options={{
event: "payment.captured",
payload: `\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``
}}/>
</Table.Cell>
@@ -136,3 +136,55 @@ const myWorkflow = createWorkflow(
## Input
<TypeList types={[{"name":"RefundPaymentWorkflowInput","type":"[RefundPaymentWorkflowInput](../../../../types/core_flows.RefundPaymentWorkflowInput/page.mdx)","optional":false,"defaultValue":"","description":"The data to refund a payment.","expandable":false,"children":[{"name":"payment_id","type":"`string`","description":"The ID of the payment to refund.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"created_by","type":"`string`","description":"The ID of the user that refunded the payment.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"amount","type":"[BigNumberInput](../../../../../types/types/types.BigNumberInput/page.mdx)","description":"The amount to refund. If not provided, the full payment amount will be refunded.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"numeric","type":"`number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"raw","type":"[BigNumberRawValue](../../../../../types/types/types.BigNumberRawValue/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"value","type":"`string` \\| `number`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]},{"name":"bigNumber","type":"`BigNumber`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" openedLevel={1} sectionTitle="refundPaymentWorkflow"/>
## Emitted Events
This section lists the events that are either triggered by the `emitEventStep` in the workflow, or by another workflow executed within this workflow.
You can listen to these events in a subscriber, as explained in the [Subscribers](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) documentation.
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
Event
</Table.HeaderCell>
<Table.HeaderCell>
Description
</Table.HeaderCell>
<Table.HeaderCell>
Payload
</Table.HeaderCell>
<Table.HeaderCell>
Action
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`payment.refunded`
</Table.Cell>
<Table.Cell>
Emitted when a payment is refunded.
</Table.Cell>
<Table.Cell>
```ts blockStyle="inline"
{
id, // the ID of the payment
}
```
</Table.Cell>
<Table.Cell>
<CopyGeneratedSnippetButton tooltipText="Copy subscriber for event" type="subscriber" options={{
event: "payment.refunded",
payload: `\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``
}}/>
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
@@ -0,0 +1,9 @@
import { TypeList } from "docs-ui"
# PaymentEvents
`Const` **PaymentEvents**: `Object`
## Properties
<TypeList types={[{"name":"CAPTURED","type":"`string`","description":"Emitted when a payment is captured.","optional":false,"defaultValue":"\"payment.captured\"","expandable":false,"children":[]},{"name":"REFUNDED","type":"`string`","description":"Emitted when a payment is refunded.","optional":false,"defaultValue":"\"payment.refunded\"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="PaymentEvents"/>
@@ -0,0 +1,7 @@
import { TypeList } from "docs-ui"
# Payment
## Variables
- [PaymentEvents](../Payment/variables/events.Payment.PaymentEvents/page.mdx)
@@ -0,0 +1,91 @@
---
slug: /references/payment/events
sidebar_label: Events Reference
---
import { TypeList } from "docs-ui"
# Payment Module Events Reference
This reference shows all the events emitted by the Medusa application related to the Payment Module. If you use the module outside the Medusa application, these events aren't emitted.
## Summary
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
Event
</Table.HeaderCell>
<Table.HeaderCell>
Description
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
[payment.captured](#paymentcaptured)
</Table.Cell>
<Table.Cell>
Emitted when a payment is captured.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
[payment.refunded](#paymentrefunded)
</Table.Cell>
<Table.Cell>
Emitted when a payment is refunded.
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
<EventHeader headerLvl="2" headerProps={{ id: "paymentcaptured", children: (<>payment.captured</>), className: "flex flex-wrap justify-center gap-docs_0.25" }} eventName="payment.captured" payload={`\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``} />
Emitted when a payment is captured.
### Payload
```ts
{
id, // the ID of the payment
}
```
### Workflows Emitting this Event
The following workflows emit this event when they're executed. These workflows are executed by Medusa's API routes. You can also view the events emitted by API routes in the [Store](https://docs.medusajs.com/api/store) and [Admin](https://docs.medusajs.com/api/admin) API references.
- [capturePaymentWorkflow](/references/medusa-workflows/capturePaymentWorkflow)
- [processPaymentWorkflow](/references/medusa-workflows/processPaymentWorkflow)
- [markPaymentCollectionAsPaid](/references/medusa-workflows/markPaymentCollectionAsPaid)
---
<EventHeader headerLvl="2" headerProps={{ id: "paymentrefunded", children: (<>payment.refunded</>), className: "flex flex-wrap justify-center gap-docs_0.25" }} eventName="payment.refunded" payload={`\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``} />
Emitted when a payment is refunded.
### Payload
```ts
{
id, // the ID of the payment
}
```
### Workflows Emitting this Event
The following workflows emit this event when they're executed. These workflows are executed by Medusa's API routes. You can also view the events emitted by API routes in the [Store](https://docs.medusajs.com/api/store) and [Admin](https://docs.medusajs.com/api/admin) API references.
- [refundPaymentWorkflow](/references/medusa-workflows/refundPaymentWorkflow)
@@ -2306,3 +2306,88 @@ Emitted when a fulfillment is marked as delivered.
The following workflows emit this event when they're executed. These workflows are executed by Medusa's API routes. You can also view the events emitted by API routes in the [Store](https://docs.medusajs.com/api/store) and [Admin](https://docs.medusajs.com/api/admin) API references.
- [markOrderFulfillmentAsDeliveredWorkflow](/references/medusa-workflows/markOrderFulfillmentAsDeliveredWorkflow)
---
## Payment Events Events
### Summary
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
Event
</Table.HeaderCell>
<Table.HeaderCell>
Description
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
[payment.captured](#paymentcaptured)
</Table.Cell>
<Table.Cell>
Emitted when a payment is captured.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
[payment.refunded](#paymentrefunded)
</Table.Cell>
<Table.Cell>
Emitted when a payment is refunded.
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
<EventHeader headerLvl="3" headerProps={{ id: "paymentcaptured", children: (<>payment.captured</>), className: "flex flex-wrap justify-center gap-docs_0.25" }} eventName="payment.captured" payload={`\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``} />
Emitted when a payment is captured.
#### Payload
```ts
{
id, // the ID of the payment
}
```
#### Workflows Emitting this Event
The following workflows emit this event when they're executed. These workflows are executed by Medusa's API routes. You can also view the events emitted by API routes in the [Store](https://docs.medusajs.com/api/store) and [Admin](https://docs.medusajs.com/api/admin) API references.
- [capturePaymentWorkflow](/references/medusa-workflows/capturePaymentWorkflow)
- [processPaymentWorkflow](/references/medusa-workflows/processPaymentWorkflow)
- [markPaymentCollectionAsPaid](/references/medusa-workflows/markPaymentCollectionAsPaid)
---
<EventHeader headerLvl="3" headerProps={{ id: "paymentrefunded", children: (<>payment.refunded</>), className: "flex flex-wrap justify-center gap-docs_0.25" }} eventName="payment.refunded" payload={`\`\`\`ts
{
id, // the ID of the payment
}
\`\`\``} />
Emitted when a payment is refunded.
#### Payload
```ts
{
id, // the ID of the payment
}
```
#### Workflows Emitting this Event
The following workflows emit this event when they're executed. These workflows are executed by Medusa's API routes. You can also view the events emitted by API routes in the [Store](https://docs.medusajs.com/api/store) and [Admin](https://docs.medusajs.com/api/admin) API references.
- [refundPaymentWorkflow](/references/medusa-workflows/refundPaymentWorkflow)
+4
View File
@@ -33,6 +33,10 @@ const withMDX = mdx({
projectPath: path.resolve("..", "resources"),
hasGeneratedSlugs: true,
},
api: {
projectPath: path.resolve("..", "api-reference"),
skipSlugValidation: true,
},
},
},
],
@@ -18,28 +18,99 @@ import { MD_LINK_REGEX } from "./constants.js"
function getErrorMessage({
link,
file,
additionalMessage = "",
}: {
link: string
file: VFile
additionalMessage?: string
}): string {
return `Broken link found! ${link} linked in ${file.history[0]}`
return `Broken link found! ${link} linked in ${file.history[0]}${
additionalMessage ? `: ${additionalMessage}` : ""
}`
}
function checkLocalLinkExists({
link,
file,
currentPageFilePath,
rootBasePath = { default: "app" },
slugChanges = [],
}: {
link: string
file: VFile
currentPageFilePath: string
rootBasePath?: BrokenLinkCheckerOptions["rootBasePath"]
slugChanges?: SlugChange[]
}) {
let fileToCheck = link
let basePath = currentPageFilePath
if (!fileToCheck.endsWith("page.mdx")) {
// if the link doesn't end with page.mdx, add it
// find route base path
let routeBasePath = rootBasePath.overrides
? Object.entries(rootBasePath.overrides).find(([key]) =>
fileToCheck.startsWith(key)
)?.[1]
: rootBasePath.default
if (routeBasePath === undefined) {
routeBasePath = rootBasePath.default
}
fileToCheck = `${routeBasePath}${fileToCheck}/page.mdx`.replace(
/\/{2,}/g,
"/"
)
basePath = file.cwd
}
// remove leading slash if present
fileToCheck = fileToCheck.replace(/^\//, "")
// get absolute path of the URL
const linkedFilePath = path
.resolve(currentPageFilePath, link)
.replace(/#.*$/, "")
const linkedFilePath = path.resolve(basePath, fileToCheck).replace(/#.*$/, "")
// console.log(link, currentPageFilePath, basePath, fileToCheck, linkedFilePath)
// check if the file exists
if (!existsSync(linkedFilePath)) {
if (existsSync(linkedFilePath)) {
return
}
// maybe check in slugs
if (!slugChanges.length) {
throw new Error(
getErrorMessage({
link,
file,
})
)
}
checkSlugExists({
slugChanges,
pathToCheck: link,
link,
file,
baseProjectPath: file.cwd,
})
}
function checkSlugExists({
slugChanges,
pathToCheck,
link,
file,
baseProjectPath,
}: {
slugChanges: SlugChange[]
pathToCheck: string
baseProjectPath: string
link: string
file: VFile
}) {
const slugChange = slugChanges.find(
(change) => change.newSlug === pathToCheck
)
if (
!slugChange ||
!mdxPageExists(path.join(baseProjectPath, slugChange.origSlug))
) {
throw new Error(
getErrorMessage({
link,
@@ -156,18 +227,20 @@ function checkLink({
// try to remove hash
const hashIndex = link.lastIndexOf("#")
const likeWithoutHash = hashIndex !== -1 ? link.substring(0, hashIndex) : link
if (likeWithoutHash.match(/page\.mdx?$/)) {
if (likeWithoutHash.match(/page\.mdx?$/) || likeWithoutHash.startsWith("/")) {
checkLocalLinkExists({
link: likeWithoutHash,
file,
currentPageFilePath,
slugChanges: options.generatedSlugs,
rootBasePath: options.rootBasePath,
})
return
}
const parsedLink = parseCrossProjectLink(likeWithoutHash)
if (!parsedLink || !Object.hasOwn(options.crossProjects, parsedLink.area)) {
if (!parsedLink) {
if (MD_LINK_REGEX.test(link)) {
// try fixing MDX links
let linkMatches
@@ -192,10 +265,33 @@ function checkLink({
}
}
return
} else if (!Object.hasOwn(options.crossProjects, parsedLink.area)) {
throw new Error(
getErrorMessage({
link,
file,
additionalMessage: `Unknown project area: ${parsedLink.area}`,
})
)
}
const projectOptions = options.crossProjects[parsedLink.area]
if (parsedLink.path.length && !parsedLink.path.startsWith("/")) {
throw new Error(
getErrorMessage({
link,
file,
additionalMessage: `Cross project paths must start with a slash.`,
})
)
}
if (projectOptions.skipSlugValidation) {
// if slug validation is skipped, just check if the file exists
return
}
const isReferenceLink =
parsedLink.path.startsWith("/references") &&
parsedLink.path !== "/references-overview"
@@ -210,41 +306,40 @@ function checkLink({
return
}
// file doesn't exist, check if slugs are enabled and generated
if (!projectOptions.generatedSlugs) {
throw new Error(
getErrorMessage({
link,
file,
})
)
}
checkSlugExists({
slugChanges: projectOptions.generatedSlugs,
pathToCheck: parsedLink.path,
link,
file,
baseProjectPath: projectOptions.projectPath,
})
}
function loadSlugs(projectPath: string): SlugChange[] {
// file doesn't exist, check if slugs are enabled and generated
const generatedSlugsPath = path.join(
projectOptions.projectPath,
projectPath,
"generated",
"slug-changes.mjs"
)
if (!projectOptions.hasGeneratedSlugs || !existsSync(generatedSlugsPath)) {
throw new Error(
getErrorMessage({
link,
file,
})
)
if (!existsSync(generatedSlugsPath)) {
throw new Error(`Cross project ${projectPath} has no generated slugs file.`)
}
// get slugs from file
const generatedSlugContent = readFileSync(generatedSlugsPath, "utf-8")
const slugChanges: SlugChange[] = JSON.parse(
return JSON.parse(
generatedSlugContent.substring(generatedSlugContent.indexOf("["))
)
const slugChange = slugChanges.find(
(change) => change.newSlug === parsedLink.path
)
if (
!slugChange ||
!mdxPageExists(path.join(projectOptions.projectPath, slugChange.origSlug))
) {
throw new Error(
getErrorMessage({
link,
file,
})
)
}
) as SlugChange[]
}
const allowedComponentNames = [
@@ -261,6 +356,22 @@ export function brokenLinkCheckerPlugin(
return async (tree, file) => {
const { visit } = await import("unist-util-visit")
// load slug changes for the current project
if (options.hasGeneratedSlugs) {
options.generatedSlugs = loadSlugs(file.cwd)
}
// load slug changes for cross projects
if (options.crossProjects) {
for (const project of Object.values(options.crossProjects)) {
if (!project.hasGeneratedSlugs) {
continue
}
project.generatedSlugs = loadSlugs(project.projectPath)
}
}
const currentPageFilePath = file.history[0].replace(
`/${path.basename(file.history[0])}`,
""
+11
View File
@@ -1,4 +1,5 @@
import { Node } from "unist-builder"
import { SlugChange } from "./build-scripts.js"
export interface UnistNode extends Node {
type: string
@@ -128,11 +129,21 @@ export declare type CrossProjectLinksOptions = {
}
export declare type BrokenLinkCheckerOptions = {
rootBasePath?: {
default: string
overrides?: {
[k: string]: string
}
}
hasGeneratedSlugs?: boolean
generatedSlugs?: SlugChange[]
crossProjects: {
[k: string]: {
projectPath: string
contentPath?: string
hasGeneratedSlugs?: boolean
generatedSlugs?: SlugChange[]
skipSlugValidation?: boolean
}
}
}
+24
View File
@@ -676,5 +676,29 @@
"markOrderFulfillmentAsDeliveredWorkflow"
],
"deprecated": false
},
{
"name": "payment.captured",
"parentName": "PaymentEvents",
"propertyName": "CAPTURED",
"payload": "```ts\n{\n id, // the ID of the payment\n}\n```",
"description": "Emitted when a payment is captured.",
"workflows": [
"capturePaymentWorkflow",
"processPaymentWorkflow",
"markPaymentCollectionAsPaid"
],
"deprecated": false
},
{
"name": "payment.refunded",
"parentName": "PaymentEvents",
"propertyName": "REFUNDED",
"payload": "```ts\n{\n id, // the ID of the payment\n}\n```",
"description": "Emitted when a payment is refunded.",
"workflows": [
"refundPaymentWorkflow"
],
"deprecated": false
}
]
@@ -92,7 +92,16 @@
* "500":
* $ref: "#/components/responses/500_error"
* x-workflow: markPaymentCollectionAsPaid
* x-events: []
* x-events:
* - name: payment.captured
* payload: |-
* ```ts
* {
* id, // the ID of the payment
* }
* ```
* description: Emitted when a payment is captured.
* deprecated: false
*
*/
@@ -83,7 +83,16 @@
* "500":
* $ref: "#/components/responses/500_error"
* x-workflow: capturePaymentWorkflow
* x-events: []
* x-events:
* - name: payment.captured
* payload: |-
* ```ts
* {
* id, // the ID of the payment
* }
* ```
* description: Emitted when a payment is captured.
* deprecated: false
*
*/
@@ -91,7 +91,16 @@
* "500":
* $ref: "#/components/responses/500_error"
* x-workflow: refundPaymentWorkflow
* x-events: []
* x-events:
* - name: payment.refunded
* payload: |-
* ```ts
* {
* id, // the ID of the payment
* }
* ```
* description: Emitted when a payment is refunded.
* deprecated: false
*
*/
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -314,12 +314,6 @@ class WorkflowsPlugin {
(tag) => tag.tagName.getText() === "ignore"
)
})
if (stepId === "beforePaymentAuthorization") {
console.log(
shouldIgnore,
ts.getJSDocCommentsAndTags(initializer.parent)
)
}
if (!shouldIgnore) {
const hookArgumetSymbol = this.getHookArgumentSymbol({
argument: initializer.arguments[1],