@mercurjs/docs 2.3.8-canary.2 → 2.3.8-canary.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/learn/architecture.mdx +166 -263
- package/content/platform/attribute/concepts/attribute-types.mdx +73 -46
- package/content/platform/attribute/concepts/global-vs-inline.mdx +54 -32
- package/content/platform/attribute/concepts/variant-axes.mdx +54 -32
- package/content/platform/attribute/guides/attach-attributes-to-a-product.mdx +96 -53
- package/content/platform/attribute/guides/create-a-variant-axis.mdx +106 -57
- package/content/platform/attribute/guides/create-an-attribute.mdx +105 -56
- package/content/platform/attribute/overview.mdx +37 -33
- package/content/platform/attribute/reference/data-models.mdx +53 -38
- package/content/platform/attribute/reference/events.mdx +47 -24
- package/content/platform/attribute/reference/links.mdx +98 -27
- package/content/platform/attribute/reference/service.mdx +71 -32
- package/content/platform/attribute/reference/workflows.mdx +158 -28
- package/content/platform/catalog/concepts/master-products.mdx +39 -37
- package/content/platform/catalog/concepts/product-seller-allowlist.mdx +56 -35
- package/content/platform/catalog/concepts/status-lifecycle.mdx +55 -49
- package/content/platform/catalog/concepts/variants-categories-collections.mdx +55 -35
- package/content/platform/catalog/guides/allowlist-stores.mdx +100 -37
- package/content/platform/catalog/guides/create-a-master-product.mdx +124 -48
- package/content/platform/catalog/guides/publish-or-reject-a-product.mdx +120 -55
- package/content/platform/catalog/overview.mdx +39 -35
- package/content/platform/catalog/reference/data-models.mdx +154 -43
- package/content/platform/catalog/reference/events.mdx +41 -25
- package/content/platform/catalog/reference/links.mdx +196 -28
- package/content/platform/catalog/reference/service.mdx +57 -35
- package/content/platform/catalog/reference/workflows.mdx +124 -30
- package/content/platform/commission/concepts/order-commission-lines.mdx +54 -52
- package/content/platform/commission/concepts/rule-matching.mdx +53 -63
- package/content/platform/commission/concepts/rules-and-rates.mdx +61 -59
- package/content/platform/commission/guides/batch-update-rules.mdx +69 -41
- package/content/platform/commission/guides/create-a-rate.mdx +101 -53
- package/content/platform/commission/guides/refresh-order-commission-lines.mdx +104 -35
- package/content/platform/commission/overview.mdx +43 -35
- package/content/platform/commission/reference/data-models.mdx +59 -45
- package/content/platform/commission/reference/events.mdx +28 -34
- package/content/platform/commission/reference/links.mdx +42 -33
- package/content/platform/commission/reference/service.mdx +103 -28
- package/content/platform/commission/reference/workflows.mdx +101 -27
- package/content/platform/offer/concepts/pricing-and-inventory.mdx +63 -49
- package/content/platform/offer/concepts/shipping.mdx +28 -29
- package/content/platform/offer/concepts/what-is-an-offer.mdx +48 -45
- package/content/platform/offer/guides/bulk-create-offers.mdx +97 -61
- package/content/platform/offer/guides/create-an-offer.mdx +112 -60
- package/content/platform/offer/guides/manage-offer-inventory.mdx +78 -38
- package/content/platform/offer/overview.mdx +39 -32
- package/content/platform/offer/reference/data-models.mdx +77 -47
- package/content/platform/offer/reference/events.mdx +44 -18
- package/content/platform/offer/reference/links.mdx +92 -40
- package/content/platform/offer/reference/service.mdx +66 -31
- package/content/platform/offer/reference/workflows.mdx +146 -37
- package/content/platform/order-group/concepts/computed-totals.mdx +40 -37
- package/content/platform/order-group/concepts/order-splitting.mdx +41 -39
- package/content/platform/order-group/concepts/the-order-group.mdx +39 -32
- package/content/platform/order-group/guides/list-order-groups.mdx +96 -56
- package/content/platform/order-group/guides/retrieve-an-order-group.mdx +93 -42
- package/content/platform/order-group/guides/split-a-cart.mdx +115 -40
- package/content/platform/order-group/overview.mdx +42 -32
- package/content/platform/order-group/reference/data-models.mdx +48 -31
- package/content/platform/order-group/reference/events.mdx +29 -17
- package/content/platform/order-group/reference/links.mdx +90 -29
- package/content/platform/order-group/reference/service.mdx +55 -31
- package/content/platform/order-group/reference/workflows.mdx +83 -24
- package/content/platform/payout/concepts/account-lifecycle.mdx +64 -67
- package/content/platform/payout/concepts/accounts-and-onboarding.mdx +50 -40
- package/content/platform/payout/concepts/payout-pipeline.mdx +70 -73
- package/content/platform/payout/guides/create-a-payout-account.mdx +65 -41
- package/content/platform/payout/guides/process-a-provider-webhook.mdx +84 -38
- package/content/platform/payout/guides/start-provider-onboarding.mdx +90 -46
- package/content/platform/payout/overview.mdx +43 -34
- package/content/platform/payout/reference/data-models.mdx +63 -36
- package/content/platform/payout/reference/events.mdx +56 -30
- package/content/platform/payout/reference/links.mdx +52 -22
- package/content/platform/payout/reference/service.mdx +72 -33
- package/content/platform/payout/reference/workflows.mdx +80 -19
- package/content/platform/product-edit/concepts/change-actions.mdx +52 -45
- package/content/platform/product-edit/concepts/change-pipeline.mdx +60 -52
- package/content/platform/product-edit/concepts/status-and-auto-confirm.mdx +43 -46
- package/content/platform/product-edit/guides/confirm-or-decline-a-change.mdx +104 -56
- package/content/platform/product-edit/guides/edit-a-product.mdx +126 -46
- package/content/platform/product-edit/guides/request-a-revision.mdx +99 -39
- package/content/platform/product-edit/overview.mdx +41 -34
- package/content/platform/product-edit/reference/data-models.mdx +73 -47
- package/content/platform/product-edit/reference/events.mdx +39 -29
- package/content/platform/product-edit/reference/links.mdx +32 -24
- package/content/platform/product-edit/reference/service.mdx +45 -26
- package/content/platform/product-edit/reference/workflows.mdx +173 -31
- package/content/platform/review/concepts/product-vs-seller-reviews.mdx +42 -41
- package/content/platform/review/concepts/ratings-and-moderation.mdx +45 -44
- package/content/platform/review/concepts/the-review-model.mdx +52 -45
- package/content/platform/review/guides/compute-aggregate-ratings.mdx +62 -37
- package/content/platform/review/guides/create-a-review.mdx +109 -39
- package/content/platform/review/guides/moderate-a-review.mdx +83 -37
- package/content/platform/review/guides/respond-to-a-review.mdx +85 -40
- package/content/platform/review/overview.mdx +43 -33
- package/content/platform/review/reference/data-models.mdx +41 -27
- package/content/platform/review/reference/events.mdx +55 -37
- package/content/platform/review/reference/links.mdx +80 -22
- package/content/platform/review/reference/service.mdx +61 -33
- package/content/platform/review/reference/workflows.mdx +80 -24
- package/content/platform/store/concepts/lifecycle.mdx +68 -44
- package/content/platform/store/concepts/store-entity.mdx +45 -27
- package/content/platform/store/concepts/team.mdx +56 -35
- package/content/platform/store/guides/create-a-store.mdx +102 -35
- package/content/platform/store/guides/manage-the-team.mdx +122 -32
- package/content/platform/store/guides/moderate-a-store.mdx +107 -38
- package/content/platform/store/overview.mdx +41 -34
- package/content/platform/store/reference/data-models.mdx +132 -57
- package/content/platform/store/reference/events.mdx +42 -17
- package/content/platform/store/reference/links.mdx +67 -49
- package/content/platform/store/reference/service.mdx +105 -33
- package/content/platform/store/reference/workflows.mdx +304 -24
- package/content/references/panel-extensions/layouts.mdx +169 -0
- package/llms.txt +112 -111
- package/package.json +1 -1
|
@@ -1,58 +1,86 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Batch-update commission rules"
|
|
3
3
|
sidebarTitle: "Batch-update rules"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Add, change, and remove a commission rate's rules in one workflow run with batchCommissionRulesWorkflow."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
from your own server code, adding, changing, and removing them in one atomic
|
|
9
|
-
operation.
|
|
7
|
+
Change the rules that scope a commission rate in one run, for example to move a seller onto a negotiated rate or to retarget a rate at a new category.
|
|
10
8
|
|
|
11
|
-
##
|
|
9
|
+
## Before you begin
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
rate's rules in parallel. Pass the target `commission_rate_id` and any of the
|
|
15
|
-
`create`, `update`, and `delete` arrays.
|
|
11
|
+
You need the following:
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import { batchCommissionRulesWorkflow } from "@mercurjs/core/workflows"
|
|
13
|
+
- The id of the rate to change, such as `comrate_01JD8Q1234567`
|
|
14
|
+
- The ids of the rules to update or delete, from the rate’s `rules` relation
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
commission_rate_id: "comrate_123",
|
|
25
|
-
create: [
|
|
26
|
-
{ reference: "seller", reference_id: "sel_123" },
|
|
27
|
-
{ reference: "product_category", reference_id: "pcat_shoes" },
|
|
28
|
-
],
|
|
29
|
-
update: [{ id: "comrule_456", reference_id: "pcat_boots" }],
|
|
30
|
-
delete: ["comrule_789"],
|
|
31
|
-
},
|
|
32
|
-
})
|
|
16
|
+
<Steps>
|
|
17
|
+
<Step title="Look up the rate's rules">
|
|
18
|
+
List the rate’s current rules through the module service.
|
|
33
19
|
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
```
|
|
20
|
+
```ts
|
|
21
|
+
import { MercurModules } from "@mercurjs/types"
|
|
37
22
|
|
|
38
|
-
|
|
23
|
+
const commission = container.resolve(MercurModules.COMMISSION)
|
|
24
|
+
|
|
25
|
+
const rules = await commission.listCommissionRules({
|
|
26
|
+
commission_rate_id: "comrate_01JD8Q1234567",
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Each rule has an `id`, a `reference`, and a `reference_id`. You need the `id` to update or delete a rule.
|
|
31
|
+
|
|
32
|
+
</Step>
|
|
33
|
+
<Step title="Run the batch">
|
|
34
|
+
Call `batchCommissionRulesWorkflow` from an API route. This route adds a seller rule, retargets a category rule, and removes a product rule.
|
|
35
|
+
|
|
36
|
+
```ts title="src/api/admin/commission-scopes/route.ts"
|
|
37
|
+
import type {
|
|
38
|
+
MedusaRequest,
|
|
39
|
+
MedusaResponse,
|
|
40
|
+
} from "@medusajs/framework/http"
|
|
41
|
+
import { batchCommissionRulesWorkflow } from "@mercurjs/core/workflows"
|
|
42
|
+
|
|
43
|
+
export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
44
|
+
const { result } = await batchCommissionRulesWorkflow(req.scope).run({
|
|
45
|
+
input: {
|
|
46
|
+
commission_rate_id: "comrate_01JD8Q1234567",
|
|
47
|
+
create: [{ reference: "seller", reference_id: "sel_01JD8Q1234567" }],
|
|
48
|
+
update: [
|
|
49
|
+
{ id: "comrule_01JD8Q1234567", reference_id: "pcat_01JD8Q1234568" },
|
|
50
|
+
],
|
|
51
|
+
delete: ["comrule_01JD8Q1234569"],
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
res.json(result)
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The result is `{ created, updated, deleted }`: the created and updated rules, and the deleted ids.
|
|
60
|
+
|
|
61
|
+
</Step>
|
|
62
|
+
</Steps>
|
|
63
|
+
|
|
64
|
+
## How the three operations run
|
|
65
|
+
|
|
66
|
+
The workflow runs `createCommissionRulesStep`, `updateCommissionRulesStep`, and `deleteCommissionRulesStep` in parallel. Each array is optional, and an empty or missing one is a no-op. If any step fails, the others roll back: created rules are deleted, updated rules get their old values, and deleted rules are created again.
|
|
39
67
|
|
|
40
68
|
<Note>
|
|
41
|
-
|
|
42
|
-
`product_type`, `product_collection`, `product_category`, or `seller`. The
|
|
43
|
-
`reference_id` is the id of the specific record in that dimension.
|
|
69
|
+
A rolled-back delete creates new rule records with the same `reference` and `reference_id`. The rules keep their meaning, but their ids change.
|
|
44
70
|
</Note>
|
|
45
71
|
|
|
46
|
-
## How
|
|
72
|
+
## How the new rules change matching
|
|
73
|
+
|
|
74
|
+
Adding rules narrows a rate. Rules on the same dimension are alternatives, and rules on different dimensions must all match. Adding the `seller` rule above to a rate that already had a `product_category` rule raises its specificity from 1 to 2, so it now beats single-dimension rates on that seller’s lines in that category.
|
|
75
|
+
|
|
76
|
+
Use only the five supported references: `product`, `product_type`, `product_collection`, `product_category`, and `seller`. The module stores any string, and a rule with an unknown reference makes the rate match nothing.
|
|
77
|
+
|
|
78
|
+
## Recompute existing orders
|
|
79
|
+
|
|
80
|
+
Rule changes affect orders placed or refreshed after the change. To apply new rules to existing orders, run `refreshOrderCommissionLinesWorkflow` for them.
|
|
47
81
|
|
|
48
|
-
|
|
49
|
-
across dimensions AND together. The two `create` rules above make the rate match
|
|
50
|
-
only lines that are both from seller `sel_123` **and** in category `pcat_shoes`,
|
|
51
|
-
raising the rate's specificity to `2`.
|
|
82
|
+
## Next steps
|
|
52
83
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
[Rule matching](/platform/commission/concepts/rule-matching) for how
|
|
57
|
-
most-specific-wins and tie-breaks resolve.
|
|
58
|
-
</Tip>
|
|
84
|
+
- [Refresh order commission lines after a rule change](/platform/commission/guides/refresh-order-commission-lines)
|
|
85
|
+
- [See how specificity and tie-breaks pick a rate](/platform/commission/concepts/rule-matching)
|
|
86
|
+
- [Input and output of batchCommissionRulesWorkflow](/platform/commission/reference/workflows)
|
|
@@ -1,72 +1,120 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Create a commission rate"
|
|
3
3
|
sidebarTitle: "Create a rate"
|
|
4
|
-
description: "Create
|
|
4
|
+
description: "Create percentage and fixed commission rates from a seed script or API route with createCommissionRatesWorkflow."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
code. This is useful in a seed script, a custom API route, or an onboarding flow.
|
|
7
|
+
Create commission rates from your own server code, for example to seed a new marketplace or to set a seller’s rate during onboarding.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
`CommissionRate` records. Run it from any place that has access to the Medusa
|
|
12
|
-
container.
|
|
9
|
+
## Before you begin
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
You need the following:
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import { createCommissionRatesWorkflow } from "@mercurjs/core/workflows"
|
|
19
|
-
import { CommissionRateType } from "@mercurjs/types"
|
|
13
|
+
- A Mercur project with `@mercurjs/core` registered through `withMercur()`
|
|
14
|
+
- The id of any seller, product, or category you want to scope a rate to
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
<Steps>
|
|
17
|
+
<Step title="Create a percentage rate">
|
|
18
|
+
Run `createCommissionRatesWorkflow` with an array of rates. This seed script creates a 12% rate for apparel.
|
|
19
|
+
|
|
20
|
+
```ts title="src/scripts/seed-commission.ts"
|
|
21
|
+
import type { ExecArgs } from "@medusajs/framework/types"
|
|
22
|
+
import { CommissionRateType } from "@mercurjs/types"
|
|
23
|
+
import { createCommissionRatesWorkflow } from "@mercurjs/core/workflows"
|
|
24
|
+
|
|
25
|
+
export default async function seedCommission({ container }: ExecArgs) {
|
|
26
|
+
const { result } = await createCommissionRatesWorkflow(container).run({
|
|
27
|
+
input: [
|
|
28
|
+
{
|
|
29
|
+
name: "Apparel",
|
|
30
|
+
code: "apparel",
|
|
31
|
+
type: CommissionRateType.PERCENTAGE,
|
|
32
|
+
value: 12,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
console.log(result.map((rate) => rate.id))
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The workflow returns the created rates in input order. If you leave out `code`, the module generates one from `name` with a random suffix, so set it when other code needs to find the rate by code.
|
|
42
|
+
|
|
43
|
+
</Step>
|
|
44
|
+
<Step title="Run the script">
|
|
45
|
+
Run the script with the Medusa CLI from your API app.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx medusa exec ./src/scripts/seed-commission.ts
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
A rate without rules matches every line, so it competes with the global rate until you scope it.
|
|
52
|
+
|
|
53
|
+
</Step>
|
|
54
|
+
<Step title="Scope the rate">
|
|
55
|
+
Attach rules with `batchCommissionRulesWorkflow`, passing the id of the rate you created.
|
|
56
|
+
|
|
57
|
+
```ts title="src/scripts/seed-commission.ts"
|
|
58
|
+
import { batchCommissionRulesWorkflow } from "@mercurjs/core/workflows"
|
|
59
|
+
|
|
60
|
+
await batchCommissionRulesWorkflow(container).run({
|
|
61
|
+
input: {
|
|
62
|
+
commission_rate_id: result[0].id,
|
|
63
|
+
create: [
|
|
64
|
+
{ reference: "product_type", reference_id: "ptyp_01JD8Q1234567" },
|
|
65
|
+
],
|
|
28
66
|
},
|
|
29
|
-
|
|
30
|
-
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The rate now matches only lines whose product has that type. See [Batch-update commission rules](/platform/commission/guides/batch-update-rules) for updates and deletes.
|
|
71
|
+
|
|
72
|
+
</Step>
|
|
73
|
+
</Steps>
|
|
31
74
|
|
|
32
|
-
|
|
75
|
+
## Create a fixed rate with per-currency amounts
|
|
76
|
+
|
|
77
|
+
A fixed rate takes an amount per currency in `values`, and `value` is the fallback. `CreateCommissionRateDTO` doesn’t declare `values` or `rules`, but the module creates both as nested records.
|
|
78
|
+
|
|
79
|
+
```ts title="src/scripts/seed-commission.ts"
|
|
80
|
+
const flatFee = {
|
|
81
|
+
name: "Flat fee",
|
|
82
|
+
type: CommissionRateType.FIXED,
|
|
83
|
+
value: 3,
|
|
84
|
+
values: [
|
|
85
|
+
{ currency_code: "usd", amount: 2.5 },
|
|
86
|
+
{ currency_code: "eur", amount: 2 },
|
|
87
|
+
],
|
|
88
|
+
rules: [{ reference: "seller", reference_id: "sel_01JD8Q1234567" }],
|
|
33
89
|
}
|
|
90
|
+
|
|
91
|
+
await createCommissionRatesWorkflow(container).run({ input: [flatFee] })
|
|
34
92
|
```
|
|
35
93
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
values: [
|
|
54
|
-
{ currency_code: "usd", amount: 5 },
|
|
55
|
-
{ currency_code: "eur", amount: 4 },
|
|
56
|
-
],
|
|
57
|
-
},
|
|
58
|
-
],
|
|
94
|
+
Declaring the rate as a variable keeps TypeScript from rejecting the extra `values` and `rules` keys. The result is a flat fee per line item for one seller: 2.5 in USD, 2 in EUR, and 3 in any other currency.
|
|
95
|
+
|
|
96
|
+
## Change the global commission
|
|
97
|
+
|
|
98
|
+
The global rate is the one with `is_default: true`. Look it up, then update it with `updateCommissionRatesWorkflow`.
|
|
99
|
+
|
|
100
|
+
```ts title="src/scripts/seed-commission.ts"
|
|
101
|
+
import { MercurModules } from "@mercurjs/types"
|
|
102
|
+
import { updateCommissionRatesWorkflow } from "@mercurjs/core/workflows"
|
|
103
|
+
|
|
104
|
+
const commission = container.resolve(MercurModules.COMMISSION)
|
|
105
|
+
const [globalRate] = await commission.listCommissionRates({
|
|
106
|
+
is_default: true,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
await updateCommissionRatesWorkflow(container).run({
|
|
110
|
+
input: [{ id: globalRate.id, value: 10, include_shipping: true }],
|
|
59
111
|
})
|
|
60
112
|
```
|
|
61
113
|
|
|
62
|
-
|
|
114
|
+
This raises the baseline to 10% and turns on shipping commission. Only the global rate’s `include_shipping` produces shipping lines.
|
|
63
115
|
|
|
64
|
-
|
|
65
|
-
attach rules with
|
|
66
|
-
[`batchCommissionRulesWorkflow`](/platform/commission/guides/batch-update-rules).
|
|
116
|
+
## Next steps
|
|
67
117
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`updateCommissionRatesWorkflow`.
|
|
72
|
-
</Tip>
|
|
118
|
+
- [Scope rates with batchCommissionRulesWorkflow](/platform/commission/guides/batch-update-rules)
|
|
119
|
+
- [Recompute existing orders after changing rates](/platform/commission/guides/refresh-order-commission-lines)
|
|
120
|
+
- [See how the winning rate is picked](/platform/commission/concepts/rule-matching)
|
|
@@ -1,55 +1,124 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Refresh order commission lines"
|
|
3
3
|
sidebarTitle: "Refresh order lines"
|
|
4
|
-
description: "Recompute
|
|
4
|
+
description: "Recompute commission lines for existing orders, and pass extra data to the commission provider with workflow hooks."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
from your own server code. Mercur already refreshes lines automatically at
|
|
9
|
-
checkout and on order changes. Reach for this workflow when you change an order
|
|
10
|
-
outside those paths, or when backfilling.
|
|
7
|
+
Recompute the commission lines of existing orders, for example after you change rates or when you change an order outside Mercur’s own workflows. Mercur already refreshes lines at checkout and on order edits, returns, claims, and exchanges.
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
<Steps>
|
|
10
|
+
<Step title="Run the workflow">
|
|
11
|
+
Pass the ids of the orders to `refreshOrderCommissionLinesWorkflow`. This route refreshes one order.
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
```ts title="src/api/admin/orders/[id]/recompute-commission/route.ts"
|
|
14
|
+
import type {
|
|
15
|
+
MedusaRequest,
|
|
16
|
+
MedusaResponse,
|
|
17
|
+
} from "@medusajs/framework/http"
|
|
18
|
+
import { refreshOrderCommissionLinesWorkflow } from "@mercurjs/core/workflows"
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
21
|
+
const { result } = await refreshOrderCommissionLinesWorkflow(
|
|
22
|
+
req.scope
|
|
23
|
+
).run({
|
|
24
|
+
input: { order_ids: [req.params.id] },
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
res.json({ commission_lines: result })
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The workflow returns the lines it wrote for all the orders. It throws if any id doesn’t belong to an order.
|
|
32
|
+
|
|
33
|
+
</Step>
|
|
34
|
+
<Step title="Check the result">
|
|
35
|
+
Read the lines back through `query.graph`, filtering by the order’s item ids.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const { data: lines } = await query.graph({
|
|
39
|
+
entity: "commission_line",
|
|
40
|
+
fields: ["item_id", "shipping_method_id", "code", "rate", "amount"],
|
|
41
|
+
filters: { item_id: ["ordli_01JD8Q1234567"] },
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Item lines carry `item_id`. Shipping lines carry `shipping_method_id` and the description `Shipping Commission`.
|
|
46
|
+
|
|
47
|
+
</Step>
|
|
48
|
+
</Steps>
|
|
49
|
+
|
|
50
|
+
## Backfill existing orders
|
|
51
|
+
|
|
52
|
+
The workflow takes any number of order ids and resolves them in one batch, so the rates load once per run. For a backfill, page through orders and refresh each page.
|
|
53
|
+
|
|
54
|
+
```ts title="src/scripts/backfill-commission.ts"
|
|
55
|
+
import type { ExecArgs } from "@medusajs/framework/types"
|
|
56
|
+
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
|
20
57
|
import { refreshOrderCommissionLinesWorkflow } from "@mercurjs/core/workflows"
|
|
21
58
|
|
|
22
|
-
export async function
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
59
|
+
export default async function backfill({ container }: ExecArgs) {
|
|
60
|
+
const query = container.resolve(ContainerRegistrationKeys.QUERY)
|
|
61
|
+
const take = 100
|
|
62
|
+
|
|
63
|
+
for (let skip = 0; ; skip += take) {
|
|
64
|
+
const { data } = await query.graph({
|
|
65
|
+
entity: "order",
|
|
66
|
+
fields: ["id"],
|
|
67
|
+
pagination: { skip, take },
|
|
68
|
+
})
|
|
69
|
+
if (!data.length) break
|
|
26
70
|
|
|
27
|
-
|
|
71
|
+
await refreshOrderCommissionLinesWorkflow(container).run({
|
|
72
|
+
input: { order_ids: data.map((order) => order.id) },
|
|
73
|
+
})
|
|
74
|
+
}
|
|
28
75
|
}
|
|
29
76
|
```
|
|
30
77
|
|
|
31
|
-
|
|
32
|
-
The workflow takes an array of `order_ids`, so you can refresh many orders in
|
|
33
|
-
one run. This is useful for backfilling after you change your commission
|
|
34
|
-
configuration.
|
|
35
|
-
</Note>
|
|
78
|
+
Each page is one workflow run. A refresh replaces lines by item and shipping method, so you can re-run the script safely.
|
|
36
79
|
|
|
37
|
-
##
|
|
80
|
+
## Pass extra data with setCommissionContext
|
|
38
81
|
|
|
39
|
-
The
|
|
40
|
-
method, so re-running it never duplicates lines. You can call it as often as you
|
|
41
|
-
need without cleaning up first.
|
|
82
|
+
The `setCommissionContext` hook receives the calculation contexts before they reach the provider. Return a `StepResponse` with new contexts to fill `additional_context` for a custom provider, or return nothing to keep them.
|
|
42
83
|
|
|
43
|
-
|
|
84
|
+
```ts title="src/workflows/hooks/commission-context.ts"
|
|
85
|
+
import { StepResponse } from "@medusajs/framework/workflows-sdk"
|
|
86
|
+
import { refreshOrderCommissionLinesWorkflow } from "@mercurjs/core/workflows"
|
|
87
|
+
|
|
88
|
+
refreshOrderCommissionLinesWorkflow.hooks.setCommissionContext(
|
|
89
|
+
({ contexts }) =>
|
|
90
|
+
new StepResponse(
|
|
91
|
+
contexts.map((context) => ({
|
|
92
|
+
...context,
|
|
93
|
+
additional_context: { tier: "gold" },
|
|
94
|
+
}))
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Each context already has `order_id`, `seller_id`, `currency_code`, `items`, and `shipping_methods`. Items carry the product’s `tags` and `attribute_value_ids`, which the `system` provider ignores but your own provider can use.
|
|
100
|
+
|
|
101
|
+
## React with commissionLinesUpserted
|
|
102
|
+
|
|
103
|
+
The `commissionLinesUpserted` hook runs after the lines are written, as part of the same workflow run. If your handler throws, the run fails, and at checkout that fails the cart completion too.
|
|
104
|
+
|
|
105
|
+
```ts title="src/workflows/hooks/commission-written.ts"
|
|
106
|
+
import { refreshOrderCommissionLinesWorkflow } from "@mercurjs/core/workflows"
|
|
107
|
+
|
|
108
|
+
refreshOrderCommissionLinesWorkflow.hooks.commissionLinesUpserted(
|
|
109
|
+
async ({ order_ids, commission_lines }, { container }) => {
|
|
110
|
+
const logger = container.resolve("logger")
|
|
111
|
+
logger.info(
|
|
112
|
+
`${commission_lines.length} lines for ${order_ids.join(", ")}`
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
```
|
|
44
117
|
|
|
45
|
-
|
|
118
|
+
Use this hook to sync commission to an external ledger. Use the [order events](/platform/commission/reference/events) instead when your side effect shouldn’t be able to block the refresh.
|
|
46
119
|
|
|
47
|
-
|
|
48
|
-
- **On order changes:** a subscriber re-runs it when an order edit is
|
|
49
|
-
confirmed, or a return, claim, or exchange is created.
|
|
120
|
+
## Next steps
|
|
50
121
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
[Events reference](/platform/commission/reference/events).
|
|
55
|
-
</Tip>
|
|
122
|
+
- [What a commission line records](/platform/commission/concepts/order-commission-lines)
|
|
123
|
+
- [Write a custom commission provider](/platform/commission/reference/service)
|
|
124
|
+
- [Hooks of every commission workflow](/platform/commission/reference/workflows)
|
|
@@ -1,86 +1,94 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
2
|
+
title: "Commissions"
|
|
3
3
|
sidebarTitle: "Overview"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Set the share of each sale the marketplace keeps, scope it to sellers and parts of the catalog, and record it per order line."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Use Mercur to
|
|
8
|
-
marketplace keeps and each seller earns.
|
|
7
|
+
Use Mercur to decide what share of each sale the marketplace keeps and what each seller earns.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
exact amount deducted before the seller is paid out, computed in arbitrary
|
|
15
|
-
precision so the numbers reconcile.
|
|
9
|
+
Commission is the marketplace’s cut of a seller order. You define rates as a percentage or a fixed amount and scope them with rules to sellers, products, types, collections, or categories. When an order is placed, Mercur picks the most specific matching rate for every line item and writes a commission line with the amount. The payout for that order is the order total minus the sum of its commission lines.
|
|
10
|
+
|
|
11
|
+
<img className="block dark:hidden" src="/images/figures/commission-overview-light.svg" alt="Commission rates behind the commission lines of order #100: the Linen shirt line matches the 12% acme-apparel rate for € 5.64, while the Desk lamp line and the shipping method fall back to the 10% default rate." />
|
|
12
|
+
<img className="hidden dark:block" src="/images/figures/commission-overview-dark.svg" alt="Commission rates behind the commission lines of order #100: the Linen shirt line matches the 12% acme-apparel rate for € 5.64, while the Desk lamp line and the shipping method fall back to the 10% default rate." />
|
|
16
13
|
|
|
17
14
|
<Note>
|
|
18
|
-
|
|
19
|
-
the number, either a percentage or a fixed amount. Rules scope that rate to a
|
|
20
|
-
slice of the catalog. Every marketplace has one **Global Commission**. This is
|
|
21
|
-
the `is_default` rate that applies when nothing more specific matches.
|
|
15
|
+
The Commission module owns four data models: `CommissionRate` (`comrate`), `CommissionRule` (`comrule`), `CommissionRateValue` (`comval`), and `CommissionLine` (`comline`). Resolve its service with `MercurModules.COMMISSION` from `@mercurjs/types`.
|
|
22
16
|
</Note>
|
|
23
17
|
|
|
24
18
|
## Key features
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
20
|
+
The Commission module covers configuration, resolution, and the per-order record:
|
|
21
|
+
|
|
22
|
+
- **Percentage or fixed rates**: a percent of the line subtotal, or a flat amount per line
|
|
23
|
+
- **Per-currency amounts**: a fixed rate holds one amount per currency and falls back to its `value`
|
|
24
|
+
- **Five scoping dimensions**: rules match on `product`, `product_type`, `product_collection`, `product_category`, and `seller`
|
|
25
|
+
- **Most specific wins**: the matching rate scoped on the most dimensions wins, and ties go to the oldest rate
|
|
26
|
+
- **Global commission**: a seeded `is_default` rate that can’t be deleted and is the only rate that commissions shipping
|
|
27
|
+
- **Lines that follow the order**: lines are written at checkout and recomputed on order edits, returns, claims, and exchanges
|
|
28
|
+
- **Exact arithmetic**: amounts are computed with Medusa’s `MathBN` and stored as big numbers
|
|
29
|
+
- **Pluggable calculation**: swap the built-in `system` provider for your own `ICommissionProvider`
|
|
30
|
+
|
|
31
|
+
## How it works
|
|
32
|
+
|
|
33
|
+
Commission runs as part of checkout and again whenever the order changes:
|
|
34
|
+
|
|
35
|
+
1. `completeCartWithSplitOrdersWorkflow` splits the cart into one order per seller.
|
|
36
|
+
2. It runs `refreshOrderCommissionLinesWorkflow` for the new orders as a nested step.
|
|
37
|
+
3. The workflow builds one calculation context per order and passes them to the active provider in one batch.
|
|
38
|
+
4. The `system` provider loads the enabled rates once and picks the winning rate for each item.
|
|
39
|
+
5. The module replaces the order’s commission lines with the new set.
|
|
40
|
+
6. When a payout is created, Mercur subtracts the sum of the order’s commission lines from the order total.
|
|
33
41
|
|
|
34
42
|
## Get started
|
|
35
43
|
|
|
36
|
-
Learn how
|
|
44
|
+
Learn how rates, rules, and commission lines fit together.
|
|
37
45
|
|
|
38
46
|
<CardGroup cols={2}>
|
|
39
47
|
<Card title="Rules & rates" icon="percent" href="/platform/commission/concepts/rules-and-rates">
|
|
40
|
-
|
|
48
|
+
Percentage and fixed rates, per-currency amounts, and the global commission.
|
|
41
49
|
</Card>
|
|
42
50
|
<Card title="Rule matching" icon="sliders" href="/platform/commission/concepts/rule-matching">
|
|
43
|
-
|
|
51
|
+
How Mercur picks one rate for each line, and how shipping is handled.
|
|
44
52
|
</Card>
|
|
45
53
|
<Card title="Order commission lines" icon="receipt" href="/platform/commission/concepts/order-commission-lines">
|
|
46
|
-
|
|
54
|
+
What a commission line records and when it’s recomputed.
|
|
47
55
|
</Card>
|
|
48
56
|
</CardGroup>
|
|
49
57
|
|
|
50
58
|
## Examples
|
|
51
59
|
|
|
52
|
-
Build against
|
|
60
|
+
Build against commission in your own server code.
|
|
53
61
|
|
|
54
62
|
<CardGroup cols={2}>
|
|
55
63
|
<Card title="Create a rate" icon="plus" href="/platform/commission/guides/create-a-rate">
|
|
56
|
-
|
|
64
|
+
Create percentage and fixed rates with `createCommissionRatesWorkflow`.
|
|
57
65
|
</Card>
|
|
58
66
|
<Card title="Batch-update rules" icon="list-check" href="/platform/commission/guides/batch-update-rules">
|
|
59
|
-
|
|
67
|
+
Add, change, and remove a rate’s rules in one workflow run.
|
|
60
68
|
</Card>
|
|
61
69
|
<Card title="Refresh order lines" icon="arrows-rotate" href="/platform/commission/guides/refresh-order-commission-lines">
|
|
62
|
-
Recompute commission for
|
|
70
|
+
Recompute commission for orders and extend the calculation context.
|
|
63
71
|
</Card>
|
|
64
72
|
</CardGroup>
|
|
65
73
|
|
|
66
74
|
## Resources
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
The data models, links, workflows, service methods, and events behind commission.
|
|
69
77
|
|
|
70
78
|
<CardGroup cols={2}>
|
|
71
79
|
<Card title="Data models" icon="table" href="/platform/commission/reference/data-models">
|
|
72
|
-
|
|
80
|
+
Every field of the four commission models.
|
|
73
81
|
</Card>
|
|
74
82
|
<Card title="Links" icon="link" href="/platform/commission/reference/links">
|
|
75
|
-
How
|
|
83
|
+
How commission records point at the catalog, sellers, and orders.
|
|
76
84
|
</Card>
|
|
77
85
|
<Card title="Workflows" icon="diagram-project" href="/platform/commission/reference/workflows">
|
|
78
|
-
Rate, rule, and order-line workflows.
|
|
86
|
+
Rate, rule, and order-line workflows with their inputs and hooks.
|
|
79
87
|
</Card>
|
|
80
88
|
<Card title="Service" icon="gear" href="/platform/commission/reference/service">
|
|
81
|
-
|
|
89
|
+
Generated and custom service methods, and commission providers.
|
|
82
90
|
</Card>
|
|
83
91
|
<Card title="Events" icon="bell" href="/platform/commission/reference/events">
|
|
84
|
-
|
|
92
|
+
The order events that trigger a recompute.
|
|
85
93
|
</Card>
|
|
86
94
|
</CardGroup>
|