diff --git a/code_samples/discounts/src/Command/ManageDiscountsCommand.php b/code_samples/discounts/src/Command/ManageDiscountsCommand.php new file mode 100644 index 0000000000..6243da8ca6 --- /dev/null +++ b/code_samples/discounts/src/Command/ManageDiscountsCommand.php @@ -0,0 +1,96 @@ +userService = $userSerice; + $this->discountService = $discountService; + $this->discountCodeService = $discountCodeService; + $this->permissionResolver = $permissionResolver; + + parent::__construct(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->permissionResolver->setCurrentUserReference( + $this->userService->loadUserByLogin('admin') + ); + + $now = new DateTimeImmutable(); + + $discountCodeCreateStruct = new DiscountCodeCreateStruct( + 'summer10', + null, // Unlimited usage + $this->permissionResolver->getCurrentUserReference()->getUserId(), + $now + ); + $discountCode = $this->discountCodeService->createDiscountCode($discountCodeCreateStruct); + + $discountCreateStruct = new DiscountCreateStruct(); + $discountCreateStruct + ->setIdentifier('discount_identifier') + ->setType(DiscountType::CART) + ->setPriority(10) + ->setEnabled(true) + ->setUser($this->userService->loadUserByLogin('admin')) + ->setRule(new FixedAmount(10)) + ->setStartDate($now) + ->setConditions([ + new IsInRegions(['germany', 'france']), + new IsProductInArray(['product-1', 'product-2']), + new IsInCurrency('EUR'), + new IsValidDiscountCode($discountCode->getCode(), $discountCode->getUsedLimit()), + ]) + ->setTranslations([ + new DiscountTranslationStruct('eng-GB', 'Discount name', 'This is a discount description', 'Promotion Label', 'Promotion Description'), + new DiscountTranslationStruct('ger-DE', 'Discount name (German)', 'Description (German)', 'Promotion Label (German)', 'Promotion Description (German)'), + ]) + ->setEndDate(null) // Permanent discount + ->setCreatedAt($now) + ->setUpdatedAt($now) + ->setContext(new ArrayMap(['custom_context' => 'custom_value'])); + + $this->discountService->createDiscount($discountCreateStruct); + + return Command::SUCCESS; + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCode.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCode.json.example new file mode 100644 index 0000000000..3c51a54be4 --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCode.json.example @@ -0,0 +1,5 @@ +{ + "DiscountCode": { + "code": "summer10" + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCodeResponse.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCodeResponse.json.example new file mode 100644 index 0000000000..d8fee156f7 --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discount_codes/apply/POST/DiscountCodeResponse.json.example @@ -0,0 +1,12 @@ +{ + "DiscountCode": { + "_media-type": "application\/vnd.ibexa.api.DiscountCode+json", + "id": 1, + "code": "summer10", + "created_at": { + "date": "2025-06-10 14:14:06.000000", + "timezone_type": 3, + "timezone": "UTC" + } + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/Discount.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/Discount.json.example new file mode 100644 index 0000000000..4082970a0d --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/Discount.json.example @@ -0,0 +1,45 @@ +{ + "Discount": { + "_media-type": "application/vnd.ibexa.api.Discount+json", + "id": 1, + "identifier": "summersale2025", + "name": "SummerSale2025", + "type": "catalog", + "label": "Summer Sale 2025", + "labelDescription": "Summer Sale 2025", + "priority": 1, + "isEnabled": true, + "createdAt": "2025-06-10T09:43:42+00:00", + "updatedAt": "2025-06-10T09:48:23+00:00", + "startDate": "2025-07-01T09:34:19+00:00", + "endDate": "2025-07-31T12:00:00+00:00", + "DiscountExpressionAware": { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_amount": "10" + } + }, + "DiscountConditions": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "currency_code": "USD" + } + } + ], + "DiscountTranslations": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountTranslation+json", + "languageCode": {}, + "name": "SummerSale2025", + "description": null, + "label": "Summer Sale 2025", + "labelDescription": "Summer Sale 2025" + } + ] + }, + "isDiscountCodeAware": { + "_media-type": "application/vnd.ibexa.api.isDiscountCodeAware+json", + "isDiscountCodeAware": false + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/DiscountList.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/DiscountList.json.example new file mode 100644 index 0000000000..c954f3870a --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/DiscountList.json.example @@ -0,0 +1,102 @@ +{ + "DiscountList": { + "_media-type": "application/vnd.ibexa.api.DiscountList+json", + "Discount": [ + { + "_media-type": "application/vnd.ibexa.api.Discount+json", + "id": 1, + "identifier": "summersale2025", + "name": "SummerSale2025", + "type": "catalog", + "label": "Summer Sale 2025", + "labelDescription": "Summer Sale 2025", + "priority": 1, + "isEnabled": true, + "createdAt": "2025-06-10T09:43:42+00:00", + "updatedAt": "2025-06-10T09:48:23+00:00", + "startDate": "2025-07-01T09:34:19+00:00", + "endDate": "2025-07-31T12:00:00+00:00", + "DiscountExpressionAware": { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_amount": "10" + } + }, + "DiscountConditions": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "currency_code": "USD" + } + } + ], + "DiscountTranslations": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountTranslation+json", + "languageCode": {}, + "name": "SummerSale2025", + "description": null, + "label": "Summer Sale 2025", + "labelDescription": "Summer Sale 2025" + } + ] + }, + { + "_media-type": "application/vnd.ibexa.api.isDiscountCodeAware+json", + "isDiscountCodeAware": false + }, + { + "_media-type": "application/vnd.ibexa.api.Discount+json", + "id": 2, + "identifier": "my_discount", + "name": "Another discount", + "type": "cart", + "label": "another", + "labelDescription": "another label description", + "priority": 10, + "isEnabled": false, + "createdAt": "2025-06-10T11:03:37+00:00", + "updatedAt": "2025-06-10T14:14:06+00:00", + "startDate": "2025-04-01T12:12:12+00:00", + "DiscountExpressionAware": { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_percentage": "10" + } + }, + "DiscountConditions": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_code": "my_secret_code", + "usage_count": 1 + } + }, + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "categories": [ + 1, + 3 + ] + } + } + ], + "DiscountTranslations": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountTranslation+json", + "languageCode": {}, + "name": "Another discount", + "description": "another great discount", + "label": "another", + "labelDescription": "another label description" + } + ] + }, + { + "_media-type": "application/vnd.ibexa.api.isDiscountCodeAware+json", + "isDiscountCodeAware": true + } + ] + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreate.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreate.json.example new file mode 100644 index 0000000000..cd30fb46d6 --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreate.json.example @@ -0,0 +1,29 @@ +{ + "DiscountCreate": { + "identifier": "my_discount", + "type": "cart", + "priority": 10, + "isEnabled": true, + "userId": 14, + "rule": { + "type": "percentage", + "amount": 10 + }, + "startDate": "2025-04-01 12:12:12", + "translations": [ + { + "languageCode": "eng-GB", + "name": "Another discount", + "description": "another great discount", + "label": "another", + "labelDescription": "another label description" + } + ], + "conditions": [ + { + "class": "Ibexa\\Discounts\\Value\\DiscountCondition\\IsInCategory", + "parameters": [["1", "2"]] + } + ] + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreateResponse.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreateResponse.json.example new file mode 100644 index 0000000000..396c70ac57 --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/POST/DiscountCreateResponse.json.example @@ -0,0 +1,47 @@ +{ + "Discount": { + "_media-type": "application/vnd.ibexa.api.Discount+json", + "id": 2, + "identifier": "my_discount", + "name": "Another discount", + "type": "cart", + "label": "another", + "labelDescription": "another label description", + "priority": 10, + "isEnabled": true, + "createdAt": "2025-06-10T11:03:37+00:00", + "updatedAt": "2025-06-10T11:03:37+00:00", + "startDate": "2025-04-01T12:12:12+00:00", + "DiscountExpressionAware": { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_percentage": "10" + } + }, + "DiscountConditions": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "categories": [ + "1", + "2" + ] + } + } + ], + "DiscountTranslations": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountTranslation+json", + "languageCode": {}, + "name": "Another discount", + "description": "another great discount", + "label": "another", + "labelDescription": "another label description" + } + ] + }, + "isDiscountCodeAware": { + "_media-type": "application/vnd.ibexa.api.isDiscountCodeAware+json", + "isDiscountCodeAware": false + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdate.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdate.json.example new file mode 100644 index 0000000000..dc4d9911d7 --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdate.json.example @@ -0,0 +1,11 @@ +{ + "DiscountUpdate": { + "identifier": "my_discount", + "conditions": [ + { + "class": "Ibexa\\Discounts\\Value\\DiscountCondition\\IsInCategory", + "parameters": [["1", "3"]] + } + ] + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdateResponse.json.example b/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdateResponse.json.example new file mode 100644 index 0000000000..62ec96734f --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/examples/discounts/identifier/PATCH/DiscountUpdateResponse.json.example @@ -0,0 +1,47 @@ +{ + "Discount": { + "_media-type": "application/vnd.ibexa.api.Discount+json", + "id": 2, + "identifier": "my_discount", + "name": "Another discount", + "type": "cart", + "label": "another", + "labelDescription": "another label description", + "priority": 10, + "isEnabled": false, + "createdAt": "2025-06-10T11:03:37+00:00", + "updatedAt": "2025-06-10T13:05:56+00:00", + "startDate": "2025-04-01T12:12:12+00:00", + "DiscountExpressionAware": { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "discount_percentage": "10" + } + }, + "DiscountConditions": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json", + "expressionValues": { + "categories": [ + "1", + "3" + ] + } + } + ], + "DiscountTranslations": [ + { + "_media-type": "application/vnd.ibexa.api.DiscountTranslation+json", + "languageCode": {}, + "name": "Another discount", + "description": "another great discount", + "label": "another", + "labelDescription": "another label description" + } + ] + }, + "isDiscountCodeAware": { + "_media-type": "application/vnd.ibexa.api.isDiscountCodeAware+json", + "isDiscountCodeAware": false + } +} diff --git a/docs/api/rest_api/rest_api_reference/input/ibexa-discounts-codes.raml b/docs/api/rest_api/rest_api_reference/input/ibexa-discounts-codes.raml new file mode 100644 index 0000000000..2e267c390b --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/ibexa-discounts-codes.raml @@ -0,0 +1,57 @@ +displayName: Discount Codes +/{cartIdentifier}: + /apply: + post: + displayName: Apply discount to cart + description: Applies a discount associated with given discount code + headers: + Accept: + description: Specifies the expected response type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountCode+json + Content-Type: + description: Specifies the input type. + example: | + application/vnd.ibexa.api.DiscountCode+json + body: + application/vnd.ibexa.api.DiscountCode+json: + type: DiscountCodeWrapper + example: !include examples/discount_codes/apply/POST/DiscountCode.json.example + responses: + 200: + description: Discount applied successfully + body: + application/vnd.ibexa.api.DiscountCode+json: + type: DiscountCodeWrapper + example: !include examples/discount_codes/apply/POST/DiscountCodeResponse.json.example + 400: + description: Error - the request is invalid. + 404: + description: Error - the given cart identifier was not found, or the discount code does not exist. + 429: + description: Error - the request was throttled due to too many requests in a short time. + + /drop: + post: + displayName: Remove discount from cart + description: Removes the discount associated with given discount code from the cart + headers: + Accept: + description: Specifies the expected response type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountCode+json + Content-Type: + description: Specifies the input type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountCode+json + body: + application/vnd.ibexa.api.DiscountCode+json: + type: DiscountCodeWrapper + example: !include examples/discount_codes/apply/POST/DiscountCode.json.example + responses: + 204: + description: Discount code with given discount code was removed from the cart. + 400: + description: Error - the request is invalid. + 404: + description: Error - the given cart identifier was not found diff --git a/docs/api/rest_api/rest_api_reference/input/ibexa-discounts.raml b/docs/api/rest_api/rest_api_reference/input/ibexa-discounts.raml new file mode 100644 index 0000000000..76e0b9425e --- /dev/null +++ b/docs/api/rest_api/rest_api_reference/input/ibexa-discounts.raml @@ -0,0 +1,149 @@ +displayName: Discounts + +get: + displayName: List discounts + description: Returns a list of discounts. + headers: + Accept: + description: Specifies the expected response type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountList+json + responses: + 200: + description: Discount list returned successfully. + body: + application/vnd.ibexa.api.DiscountList+json: + type: DiscountListWrapper + example: !include examples/discounts/DiscountList.json.example + 400: + description: Error - the request is invalid. +post: + displayName: Create discount + description: Create a discount using the provided input. + headers: + Accept: + description: Specifies the expected response type. Only JSON is supported. + example: | + application/vnd.ibexa.api.Discount+json + Content-Type: + description: Specifies the input type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountCreate+json + body: + application/vnd.ibexa.api.DiscountCreate+json: + type: DiscountCreateWrapper + example: !include examples/discounts/POST/DiscountCreate.json.example + responses: + 200: + body: + application/vnd.ibexa.api.Discount+json: + type: DiscountWrapper + example: !include examples/discounts/POST/DiscountCreateResponse.json.example + 400: + description: Error - the request is invalid. + 401: + description: Error - the user is not authorized to execute an AI action. + +/{id}: + get: + displayName: Get discount by ID + description: Returns a discount with the specified numerical ID + headers: + Accept: + description: Only JSON is supported. + example: | + application/vnd.ibexa.api.Discount+json + responses: + 200: + body: + application/vnd.ibexa.api.Discount+json: + type: DiscountWrapper + example: !include examples/discounts/Discount.json.example + 401: + description: Error - the user is not authorized to create a discount + +/{identifier}: + get: + displayName: Get discount by identifier + description: Returns a discount with the specified identifier + headers: + Accept: + description: Only JSON is supported. + example: | + application/vnd.ibexa.api.Discount+json + responses: + 200: + body: + application/vnd.ibexa.api.Discount+json: + type: DiscountWrapper + example: !include examples/discounts/Discount.json.example + + patch: + displayName: Update discount + description: Updates a discount using the provided input. + headers: + Accept: + description: Specifies the expected response type. Only JSON is supported. + example: | + application/vnd.ibexa.api.Discount+json + Content-Type: + description: Specifies the input type. Only JSON is supported. + example: | + application/vnd.ibexa.api.DiscountUpdate+json + body: + application/vnd.ibexa.api.DiscountUpdate+json: + type: DiscountUpdateWrapper + example: !include examples/discounts/identifier/PATCH/DiscountUpdate.json.example + responses: + 200: + body: + application/vnd.ibexa.api.Discount+json: + type: DiscountWrapper + example: !include examples/discounts/identifier/PATCH/DiscountUpdateResponse.json.example + 400: + description: Error - the request is invalid. + 401: + description: Error - the user is not authorized to update the discount. + 404: + description: Error - the specified discount was not found. + + delete: + displayName: Delete discount + description: Deletes a discount + responses: + 204: + description: Discount deleted successfully. + 400: + description: Error - the request is invalid. + 401: + description: Error - the user is not authorized to update the discount. + 404: + description: Error - the specified discount was not found. + + /enable: + post: + displayName: Enable discount + description: Enables a discount with the specified identifier. + responses: + 204: + description: Discount enabled successfully. + 400: + description: Error - the request is invalid. + 401: + description: Error - the user is not authorized to update the discount. + 404: + description: Error - the specified discount was not found. + + /disable: + post: + displayName: Disable discount + description: Disables a discount with the specified identifier. + responses: + 204: + description: Discount disabled successfully. + 400: + description: Error - the request is invalid. + 401: + description: Error - the user is not authorized to update the discount. + 404: + description: Error - the specified discount was not found. diff --git a/docs/api/rest_api/rest_api_reference/input/ibexa-types.raml b/docs/api/rest_api/rest_api_reference/input/ibexa-types.raml index 8a03f70a40..516ed1627e 100644 --- a/docs/api/rest_api/rest_api_reference/input/ibexa-types.raml +++ b/docs/api/rest_api/rest_api_reference/input/ibexa-types.raml @@ -6313,3 +6313,180 @@ ActionConfiguration: updatedAt: type: datetime description: 'Timestamp indicating when the action configuration was last updated.' + +DiscountListWrapper: + type: object + description: 'Wrapper object for DiscountList.' + properties: + DiscountList: + type: object + description: 'Object containing a list of discounts.' + properties: + Discount: + type: array + items: + type: object + properties: + identifier: + type: string + description: "Discount identifier." + type: + type: string + description: "Discount type: cart or catalog." + priority: + type: integer + description: "Discount priority." + isEnabled: + type: boolean + description: "Indicates whether the discount is enabled." + userId: + type: integer + description: "User ID of discount creator." + rule: + type: object + description: "Describes how the discount is calculated: percentage or fixed." + properties: + type: + type: string + description: "Discount type." + amount: + type: integer + description: "Discount amount." + startDate: + type: datetime + description: "Defines when the discount starts." + endDate: + type: datetime + description: "Defines when the discount starts." + translations: + type: array + description: "Translations of discount data." + items: + type: object + properties: + languageCode: + type: string + name: + type: string + description: + type: string + label: + type: string + labelDescription: + type: string + conditions: + type: array + description: "List of discount conditions." + items: + type: DiscountCondition + +DiscountWrapper: + type: object + description: 'Wrapper object for Discount.' + properties: + Discount: + type: object + description: 'Object containing a list of discounts.' + +DiscountCreateWrapper: + type: object + description: 'Wrapper object for DiscountCreate.' + properties: + DiscountCreate: + type: object + description: 'Object containing a list of discounts.' + properties: + identifier: + type: string + description: "Discount identifier." + type: + type: string + description: "Discount type: cart or catalog." + priority: + type: integer + description: "Discount priority." + isEnabled: + type: boolean + description: "Indicates whether the discount is enabled." + userId: + type: integer + description: "User ID of discount creator." + rule: + type: object + description: "Describes how the discount is calculated: percentage or fixed." + properties: + type: + type: string + description: "Discount type." + amount: + type: integer + description: "Discount amount." + startDate: + type: datetime + description: "Defines when the discount starts." + endDate: + type: datetime + description: "Defines when the discount starts." + translations: + type: array + description: "Translations of discount data." + items: + type: object + properties: + languageCode: + type: string + name: + type: string + description: + type: string + label: + type: string + labelDescription: + type: string + conditions: + type: array + description: "List of discount conditions." + items: + type: DiscountCondition + +DiscountUpdateWrapper: + type: object + description: 'Wrapper object for DiscountUpdate.' + properties: + DiscountUpdate: + type: object + description: 'Object containing a list of discounts.' + properties: + identifier: + type: string + description: Identifier of the discount. Required. + conditions: + type: array + description: 'List of conditions.' + items: + type: DiscountCondition + +DiscountCodeWrapper: + type: object + description: 'Wrapper object for DiscountCode.' + properties: + DiscountCode: + type: object + description: 'Object containing data about the discount code.' + properties: + code: + type: string + description: 'Discount code' + +DiscountCondition: + type: object + description: 'Object representing a discount condition.' + properties: + class: + type: string + description: 'FCQN of a discount condition class.' + parameters: + type: array + description: 'Condition parameters.' + items: + type: object diff --git a/docs/api/rest_api/rest_api_reference/input/ibexa.raml b/docs/api/rest_api/rest_api_reference/input/ibexa.raml index 04e4912a7e..620f4a1ee5 100644 --- a/docs/api/rest_api/rest_api_reference/input/ibexa.raml +++ b/docs/api/rest_api/rest_api_reference/input/ibexa.raml @@ -81,4 +81,8 @@ baseUri: ../rest_api_usage/rest_api_usage/ /ai: !include ibexa-ai.raml +/discounts: !include ibexa-discounts.raml + +/discounts_codes: !include ibexa-discounts-codes.raml + types: !include ibexa-types.raml diff --git a/docs/api/rest_api/rest_api_reference/rest_api_reference.html b/docs/api/rest_api/rest_api_reference/rest_api_reference.html index 101663f3fa..3de731431c 100644 --- a/docs/api/rest_api/rest_api_reference/rest_api_reference.html +++ b/docs/api/rest_api/rest_api_reference/rest_api_reference.html @@ -145271,6 +145271,2978 @@
+ GET + /discounts +
+Returns a list of discounts.
+ +Accept
+Specifies the expected response type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountList+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | +
+ Discount list returned successfully. + |
+
+ 400 + | +
+ Error - the request is invalid. + |
+
Type | +Description | +
---|---|
+ + DiscountListWrapper + + | +Wrapper object for DiscountList. | +
Code: 200
+ + file_copy + +
+
+ {
+ "DiscountList": {
+ "_media-type": "application/vnd.ibexa.api.DiscountList+json",
+ "Discount": [
+ {
+ "_media-type": "application/vnd.ibexa.api.Discount+json",
+ "id": 1,
+ "identifier": "summersale2025",
+ "name": "SummerSale2025",
+ "type": "catalog",
+ "label": "Summer Sale 2025",
+ "labelDescription": "Summer Sale 2025",
+ "priority": 1,
+ "isEnabled": true,
+ "createdAt": "2025-06-10T09:43:42+00:00",
+ "updatedAt": "2025-06-10T09:48:23+00:00",
+ "startDate": "2025-07-01T09:34:19+00:00",
+ "endDate": "2025-07-31T12:00:00+00:00",
+ "DiscountExpressionAware": {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "discount_amount": "10"
+ }
+
+ + POST + /discounts +
+Create a discount using the provided input.
+ +Accept
+Specifies the expected response type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.Discount+json
+
+ |
+
Content-Type
+Specifies the input type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountCreate+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | ++ + | +
+ 400 + | +
+ Error - the request is invalid. + |
+
+ 401 + | +
+ Error - the user is not authorized to execute an AI action. + |
+
Type | +Description | +
---|---|
+ + DiscountCreateWrapper + + | +Wrapper object for DiscountCreate. | +
+ + DiscountWrapper + + | +Wrapper object for Discount. | +
+ file_copy + +
+
+ {
+ "DiscountCreate": {
+ "identifier": "my_discount",
+ "type": "cart",
+ "priority": 10,
+ "isEnabled": true,
+ "userId": 14,
+ "rule": {
+ "type": "percentage",
+ "amount": 10
+ },
+ "startDate": "2025-04-01 12:12:12",
+ "translations": [
+ {
+ "languageCode": "eng-GB",
+ "name": "Another discount",
+ "description": "another great discount",
+ "label": "another",
+ "labelDescription": "another label description"
+ }
+ ],
+ "conditions": [
+ {
+ "class": "Ibexa\\Discounts\\Value\\DiscountCondition\\IsInCategory",
+ "parameters": [["1", "2"]]
+ }
+ ]
+ }
+}
+
+
+ Code: 200
+ + file_copy + +
+
+ {
+ "Discount": {
+ "_media-type": "application/vnd.ibexa.api.Discount+json",
+ "id": 2,
+ "identifier": "my_discount",
+ "name": "Another discount",
+ "type": "cart",
+ "label": "another",
+ "labelDescription": "another label description",
+ "priority": 10,
+ "isEnabled": true,
+ "createdAt": "2025-06-10T11:03:37+00:00",
+ "updatedAt": "2025-06-10T11:03:37+00:00",
+ "startDate": "2025-04-01T12:12:12+00:00",
+ "DiscountExpressionAware": {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "discount_percentage": "10"
+ }
+ },
+ "DiscountConditions": [
+ {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "categories": [
+ "1",
+ "2"
+ ]
+
+
+ + GET + /discounts/{id} +
+Returns a discount with the specified numerical ID
+ +Accept
+Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.Discount+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | ++ + | +
Type | +Description | +
---|---|
+ + DiscountWrapper + + | +Wrapper object for Discount. | +
Code: 200
+ + file_copy + +
+
+ {
+ "Discount": {
+ "_media-type": "application/vnd.ibexa.api.Discount+json",
+ "id": 1,
+ "identifier": "summersale2025",
+ "name": "SummerSale2025",
+ "type": "catalog",
+ "label": "Summer Sale 2025",
+ "labelDescription": "Summer Sale 2025",
+ "priority": 1,
+ "isEnabled": true,
+ "createdAt": "2025-06-10T09:43:42+00:00",
+ "updatedAt": "2025-06-10T09:48:23+00:00",
+ "startDate": "2025-07-01T09:34:19+00:00",
+ "endDate": "2025-07-31T12:00:00+00:00",
+ "DiscountExpressionAware": {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "discount_amount": "10"
+ }
+ },
+ "DiscountConditions": [
+ {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "currency_code": "USD"
+ }
+
+
+ + GET + /discounts/{identifier} +
+Returns a discount with the specified identifier
+ +Accept
+Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.Discount+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | ++ + | +
Type | +Description | +
---|---|
+ + DiscountWrapper + + | +Wrapper object for Discount. | +
Code: 200
+ + file_copy + +
+
+ {
+ "Discount": {
+ "_media-type": "application/vnd.ibexa.api.Discount+json",
+ "id": 1,
+ "identifier": "summersale2025",
+ "name": "SummerSale2025",
+ "type": "catalog",
+ "label": "Summer Sale 2025",
+ "labelDescription": "Summer Sale 2025",
+ "priority": 1,
+ "isEnabled": true,
+ "createdAt": "2025-06-10T09:43:42+00:00",
+ "updatedAt": "2025-06-10T09:48:23+00:00",
+ "startDate": "2025-07-01T09:34:19+00:00",
+ "endDate": "2025-07-31T12:00:00+00:00",
+ "DiscountExpressionAware": {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "discount_amount": "10"
+ }
+ },
+ "DiscountConditions": [
+ {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "currency_code": "USD"
+ }
+
+
+ + PATCH + /discounts/{identifier} +
+Updates a discount using the provided input.
+ +Accept
+Specifies the expected response type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.Discount+json
+
+ |
+
Content-Type
+Specifies the input type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountUpdate+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | ++ + | +
+ 400 + | +
+ Error - the request is invalid. + |
+
+ 401 + | +
+ Error - the user is not authorized to update the discount. + |
+
+ 404 + | +
+ Error - the specified discount was not found. + |
+
Type | +Description | +
---|---|
+ + DiscountUpdateWrapper + + | +Wrapper object for DiscountUpdate. | +
+ + DiscountWrapper + + | +Wrapper object for Discount. | +
+ file_copy + +
+
+ {
+ "DiscountUpdate": {
+ "identifier": "my_discount",
+ "conditions": [
+ {
+ "class": "Ibexa\\Discounts\\Value\\DiscountCondition\\IsInCategory",
+ "parameters": [["1", "3"]]
+ }
+ ]
+ }
+}
+
+
+ Code: 200
+ + file_copy + +
+
+ {
+ "Discount": {
+ "_media-type": "application/vnd.ibexa.api.Discount+json",
+ "id": 2,
+ "identifier": "my_discount",
+ "name": "Another discount",
+ "type": "cart",
+ "label": "another",
+ "labelDescription": "another label description",
+ "priority": 10,
+ "isEnabled": false,
+ "createdAt": "2025-06-10T11:03:37+00:00",
+ "updatedAt": "2025-06-10T13:05:56+00:00",
+ "startDate": "2025-04-01T12:12:12+00:00",
+ "DiscountExpressionAware": {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "discount_percentage": "10"
+ }
+ },
+ "DiscountConditions": [
+ {
+ "_media-type": "application/vnd.ibexa.api.DiscountExpressionAware+json",
+ "expressionValues": {
+ "categories": [
+ "1",
+ "3"
+ ]
+
+
+ + DELETE + /discounts/{identifier} +
+Deletes a discount
+ + + +Code | +Description | +
---|---|
+ 204 + | +
+ Discount deleted successfully. + |
+
+ 400 + | +
+ Error - the request is invalid. + |
+
+ 401 + | +
+ Error - the user is not authorized to update the discount. + |
+
+ 404 + | +
+ Error - the specified discount was not found. + |
+
+ POST + /discounts/{identifier}/enable +
+Enables a discount with the specified identifier.
+ + + +Code | +Description | +
---|---|
+ 204 + | +
+ Discount enabled successfully. + |
+
+ POST + /discounts/{identifier}/disable +
+Disables a discount with the specified identifier.
+ + + +Code | +Description | +
---|---|
+ 204 + | +
+ Discount disabled successfully. + |
+
+ POST + /discounts_codes/{cartIdentifier}/apply +
+Applies a discount associated with given discount code
+ +Accept
+Specifies the expected response type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountCode+json
+
+ |
+
Content-Type
+Specifies the input type.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountCode+json
+
+ |
+
Code | +Description | +
---|---|
+ + 200 + + | +
+ Discount applied successfully + |
+
+ 400 + | +
+ Error - the request is invalid. + |
+
+ 404 + | +
+ Error - the given cart identifier was not found, or the discount code does not exist. + |
+
+ 429 + | +
+ Error - the request was throttled due to too many requests in a short time. + |
+
Type | +Description | +
---|---|
+ + DiscountCodeWrapper + + | +Wrapper object for DiscountCode. | +
+ file_copy + +
+
+ {
+ "DiscountCode": {
+ "code": "summer10"
+ }
+}
+
+
+ Code: 200
+ + file_copy + +
+
+ {
+ "DiscountCode": {
+ "_media-type": "application\/vnd.ibexa.api.DiscountCode+json",
+ "id": 1,
+ "code": "summer10",
+ "created_at": {
+ "date": "2025-06-10 14:14:06.000000",
+ "timezone_type": 3,
+ "timezone": "UTC"
+ }
+ }
+}
+
+
+ + POST + /discounts_codes/{cartIdentifier}/drop +
+Removes the discount associated with given discount code from the cart
+ +Accept
+Specifies the expected response type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountCode+json
+
+ |
+
Content-Type
+Specifies the input type. Only JSON is supported.
+Property | +Value | +
---|---|
Type | ++ + + string + + + + + | +
Examples | +
+ application/vnd.ibexa.api.DiscountCode+json
+
+ |
+
Code | +Description | +
---|---|
+ 204 + | +
+ Discount code with given discount code was removed from the cart. + |
+
+ 400 + | +
+ Error - the request is invalid. + |
+
+ 404 + | +
+ Error - the given cart identifier was not found + |
+
Type | +Description | +
---|---|
+ + DiscountCodeWrapper + + | +Wrapper object for DiscountCode. | +
+ file_copy + +
+
+ {
+ "DiscountCode": {
+ "code": "summer10"
+ }
+}
+
+
+