feat: implement promotions api v1.0.0 create revoke get and list endpoints
This commit is contained in:
parent
1ce9a38808
commit
0c41ad5858
@ -14,7 +14,7 @@ This file intentionally separates high-priority vs extended APIs for easier team
|
|||||||
|
|
||||||
## Group B (Extended / Optional / Can Be Added Incrementally)
|
## Group B (Extended / Optional / Can Be Added Incrementally)
|
||||||
|
|
||||||
- Promotions
|
- Promotions (Promotions API v1.0.0 route set available)
|
||||||
- Ads / sponsored listings
|
- Ads / sponsored listings
|
||||||
- Payout and financial reconciliation (Reporting API route now available)
|
- Payout and financial reconciliation (Reporting API route now available)
|
||||||
- Store holiday/special schedules
|
- Store holiday/special schedules
|
||||||
|
|||||||
32
docs/developer-portal/17-promotions-api-1-0-0-audit.md
Normal file
32
docs/developer-portal/17-promotions-api-1-0-0-audit.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# 17 Promotions API 1.0.0 Audit
|
||||||
|
|
||||||
|
Source checked: "Uber Eats Marketplace Promotions API (1.0.0)" shared by you.
|
||||||
|
|
||||||
|
## Implemented Now (Dedicated Wrapper Namespace)
|
||||||
|
|
||||||
|
- Create Promotion:
|
||||||
|
- `POST /api/v1/uber/delivery-promotions/stores/{storeId}`
|
||||||
|
- upstream: `/v1/delivery/stores/{store_id}/promotion`
|
||||||
|
- Revoke Promotion:
|
||||||
|
- `POST /api/v1/uber/delivery-promotions/{promotionId}/revoke`
|
||||||
|
- upstream: `/v1/delivery/promotions/{promotion_id}/revoke`
|
||||||
|
- Get Promotion:
|
||||||
|
- `GET /api/v1/uber/delivery-promotions/{promotionId}`
|
||||||
|
- upstream: `/v1/delivery/promotions/{promotion_id}`
|
||||||
|
- Get Promotions:
|
||||||
|
- `GET /api/v1/uber/delivery-promotions/stores/{storeId}`
|
||||||
|
- upstream: `/v1/delivery/stores/{store_id}/promotions`
|
||||||
|
|
||||||
|
## Validation Added
|
||||||
|
|
||||||
|
- `user_group` enum: `ALL_CUSTOMERS | FIRST_TIME_CUSTOMERS`
|
||||||
|
- promotions list `state` enum:
|
||||||
|
- `active`, `pending`, `completed`, `revoked`, `expired`, `deleted`
|
||||||
|
- required top-level create payload fields enforced
|
||||||
|
|
||||||
|
## Pending
|
||||||
|
|
||||||
|
- Strict schema unions for each promotion type object variant:
|
||||||
|
- flat_off, free_item, bogo, percent_off, menu_item, free_delivery
|
||||||
|
- typed handling for `time_range` object query form when full exact query contract is shared
|
||||||
|
|
||||||
14
docs/developer-portal/17-promotions.md
Normal file
14
docs/developer-portal/17-promotions.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# 17 Promotions
|
||||||
|
|
||||||
|
Promotions API 1.0.0 wrapper routes:
|
||||||
|
|
||||||
|
- `POST /api/v1/uber/delivery-promotions/stores/{storeId}` (Create promotion)
|
||||||
|
- `GET /api/v1/uber/delivery-promotions/stores/{storeId}` (List promotions)
|
||||||
|
- `GET /api/v1/uber/delivery-promotions/{promotionId}` (Get single promotion)
|
||||||
|
- `POST /api/v1/uber/delivery-promotions/{promotionId}/revoke` (Revoke promotion)
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Only promotions created via API are expected to be returned by get/list endpoints.
|
||||||
|
- User group and state filters are validated.
|
||||||
|
|
||||||
@ -1026,6 +1026,96 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/uber/delivery-promotions/stores/{storeId}": {
|
||||||
|
"post": {
|
||||||
|
"summary": "Promotions API 1.0.0 - Create promotion",
|
||||||
|
"tags": [
|
||||||
|
"Uber Delivery Promotions v1"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "storeId",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Promotion created"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get": {
|
||||||
|
"summary": "Promotions API 1.0.0 - Get promotions by store",
|
||||||
|
"tags": [
|
||||||
|
"Uber Delivery Promotions v1"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "storeId",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Promotions listed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/uber/delivery-promotions/{promotionId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Promotions API 1.0.0 - Get promotion by ID",
|
||||||
|
"tags": [
|
||||||
|
"Uber Delivery Promotions v1"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "promotionId",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Promotion retrieved"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/uber/delivery-promotions/{promotionId}/revoke": {
|
||||||
|
"post": {
|
||||||
|
"summary": "Promotions API 1.0.0 - Revoke promotion",
|
||||||
|
"tags": [
|
||||||
|
"Uber Delivery Promotions v1"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "promotionId",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Promotion revoked"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/uber/reporting/fetch": {
|
"/api/v1/uber/reporting/fetch": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Fetch Uber reporting CSV with retries and header-based parsing",
|
"summary": "Fetch Uber reporting CSV with retries and header-based parsing",
|
||||||
|
|||||||
@ -927,6 +927,123 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Promotions API - Create Promotion",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "x-api-key",
|
||||||
|
"value": "{{apiKey}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"start_time\": \"2026-04-10T00:00:00-07:00\",\n \"end_time\": \"2026-04-20T00:00:00-07:00\",\n \"external_promotion_id\": \"Uber_Superbowl\",\n \"user_group\": \"ALL_CUSTOMERS\",\n \"allow_unlimited_apply\": true,\n \"currency_code\": \"USD\",\n \"budget\": {\n \"unlimited_budget\": true\n },\n \"promo_type\": \"FLATOFF\",\n \"promotion_discount\": {\n \"flat_off_discount\": {}\n }\n}"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/api/v1/uber/delivery-promotions/stores/{{storeId}}",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"v1",
|
||||||
|
"uber",
|
||||||
|
"delivery-promotions",
|
||||||
|
"stores",
|
||||||
|
"{{storeId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Promotions API - List Promotions",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "x-api-key",
|
||||||
|
"value": "{{apiKey}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/api/v1/uber/delivery-promotions/stores/{{storeId}}?state=active",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"v1",
|
||||||
|
"uber",
|
||||||
|
"delivery-promotions",
|
||||||
|
"stores",
|
||||||
|
"{{storeId}}"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "state",
|
||||||
|
"value": "active"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Promotions API - Get Promotion",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "x-api-key",
|
||||||
|
"value": "{{apiKey}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/api/v1/uber/delivery-promotions/{{promotionId}}",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"v1",
|
||||||
|
"uber",
|
||||||
|
"delivery-promotions",
|
||||||
|
"{{promotionId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Promotions API - Revoke Promotion",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "x-api-key",
|
||||||
|
"value": "{{apiKey}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/api/v1/uber/delivery-promotions/{{promotionId}}/revoke",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"v1",
|
||||||
|
"uber",
|
||||||
|
"delivery-promotions",
|
||||||
|
"{{promotionId}}",
|
||||||
|
"revoke"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Get Store By ID",
|
"name": "Get Store By ID",
|
||||||
"request": {
|
"request": {
|
||||||
@ -1491,6 +1608,10 @@
|
|||||||
{
|
{
|
||||||
"key": "orderId",
|
"key": "orderId",
|
||||||
"value": ""
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "promotionId",
|
||||||
|
"value": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,12 @@ module.exports = {
|
|||||||
deliveryByoc: {
|
deliveryByoc: {
|
||||||
ingestCourierLocation: "/v1/eats/byoc/restaurants/orders/event/location"
|
ingestCourierLocation: "/v1/eats/byoc/restaurants/orders/event/location"
|
||||||
},
|
},
|
||||||
|
deliveryPromotions: {
|
||||||
|
createByStore: "/v1/delivery/stores/{storeId}/promotion",
|
||||||
|
revokeById: "/v1/delivery/promotions/{promotionId}/revoke",
|
||||||
|
getById: "/v1/delivery/promotions/{promotionId}",
|
||||||
|
listByStore: "/v1/delivery/stores/{storeId}/promotions"
|
||||||
|
},
|
||||||
webhooks: {
|
webhooks: {
|
||||||
events: "/v1/eats/stores/{storeId}/event_feed"
|
events: "/v1/eats/stores/{storeId}/event_feed"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -635,6 +635,63 @@ async function deliveryByocIngestCourierLocation(req, res) {
|
|||||||
return res.json({ success: true, data });
|
return res.json({ success: true, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deliveryCreatePromotion(req, res) {
|
||||||
|
const budgetSchema = z
|
||||||
|
.object({
|
||||||
|
unlimited_budget: z.boolean().optional(),
|
||||||
|
amount_e5: z.coerce.number().optional()
|
||||||
|
})
|
||||||
|
.optional();
|
||||||
|
|
||||||
|
const promotionSchema = z.object({
|
||||||
|
start_time: z.string(),
|
||||||
|
end_time: z.string(),
|
||||||
|
external_promotion_id: z.string().optional(),
|
||||||
|
user_group: z.enum(["ALL_CUSTOMERS", "FIRST_TIME_CUSTOMERS"]).optional(),
|
||||||
|
allow_unlimited_apply: z.boolean().optional(),
|
||||||
|
currency_code: z.string().optional(),
|
||||||
|
budget: budgetSchema,
|
||||||
|
promo_type: z.string(),
|
||||||
|
promotion_discount: z.record(z.string(), z.any()).optional(),
|
||||||
|
promotion_customization: z.record(z.string(), z.any()).optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = promotionSchema.parse(req.body || {});
|
||||||
|
const data = await proxyService.deliveryCreatePromotion({
|
||||||
|
storeId: req.params.storeId,
|
||||||
|
payload
|
||||||
|
});
|
||||||
|
return res.json({ success: true, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryRevokePromotion(req, res) {
|
||||||
|
const data = await proxyService.deliveryRevokePromotion({
|
||||||
|
promotionId: req.params.promotionId
|
||||||
|
});
|
||||||
|
return res.json({ success: true, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryGetPromotion(req, res) {
|
||||||
|
const data = await proxyService.deliveryGetPromotion({
|
||||||
|
promotionId: req.params.promotionId
|
||||||
|
});
|
||||||
|
return res.json({ success: true, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryListPromotions(req, res) {
|
||||||
|
const schema = z.object({
|
||||||
|
state: z.enum(["active", "pending", "completed", "revoked", "expired", "deleted"]).optional(),
|
||||||
|
start_time: z.string().optional(),
|
||||||
|
end_time: z.string().optional()
|
||||||
|
});
|
||||||
|
const query = schema.parse(req.query || {});
|
||||||
|
const data = await proxyService.deliveryListPromotions({
|
||||||
|
storeId: req.params.storeId,
|
||||||
|
query
|
||||||
|
});
|
||||||
|
return res.json({ success: true, data });
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
genericProxy,
|
genericProxy,
|
||||||
upsertMenu,
|
upsertMenu,
|
||||||
@ -676,5 +733,9 @@ module.exports = {
|
|||||||
deliveryResolveFulfillmentIssues,
|
deliveryResolveFulfillmentIssues,
|
||||||
deliveryGetReplacementRecommendations,
|
deliveryGetReplacementRecommendations,
|
||||||
deliveryUpdatePartnerCount,
|
deliveryUpdatePartnerCount,
|
||||||
deliveryByocIngestCourierLocation
|
deliveryByocIngestCourierLocation,
|
||||||
|
deliveryCreatePromotion,
|
||||||
|
deliveryRevokePromotion,
|
||||||
|
deliveryGetPromotion,
|
||||||
|
deliveryListPromotions
|
||||||
};
|
};
|
||||||
|
|||||||
@ -612,6 +612,53 @@ async function deliveryByocIngestCourierLocation({ payload }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deliveryCreatePromotion({ storeId, payload }) {
|
||||||
|
const uberPath = interpolatePath(uberEndpoints.deliveryPromotions.createByStore, { storeId });
|
||||||
|
return callUberApi({
|
||||||
|
method: "POST",
|
||||||
|
uberPath,
|
||||||
|
body: payload,
|
||||||
|
wrapperRoute: "/api/v1/uber/delivery-promotions/stores/:storeId",
|
||||||
|
authMode: "app",
|
||||||
|
scopes: AUTH_SCOPES.STORE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryRevokePromotion({ promotionId }) {
|
||||||
|
const uberPath = interpolatePath(uberEndpoints.deliveryPromotions.revokeById, { promotionId });
|
||||||
|
return callUberApi({
|
||||||
|
method: "POST",
|
||||||
|
uberPath,
|
||||||
|
body: {},
|
||||||
|
wrapperRoute: "/api/v1/uber/delivery-promotions/:promotionId/revoke",
|
||||||
|
authMode: "app",
|
||||||
|
scopes: AUTH_SCOPES.STORE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryGetPromotion({ promotionId }) {
|
||||||
|
const uberPath = interpolatePath(uberEndpoints.deliveryPromotions.getById, { promotionId });
|
||||||
|
return callUberApi({
|
||||||
|
method: "GET",
|
||||||
|
uberPath,
|
||||||
|
wrapperRoute: "/api/v1/uber/delivery-promotions/:promotionId",
|
||||||
|
authMode: "app",
|
||||||
|
scopes: AUTH_SCOPES.STORE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliveryListPromotions({ storeId, query }) {
|
||||||
|
const uberPath = interpolatePath(uberEndpoints.deliveryPromotions.listByStore, { storeId });
|
||||||
|
return callUberApi({
|
||||||
|
method: "GET",
|
||||||
|
uberPath,
|
||||||
|
query,
|
||||||
|
wrapperRoute: "/api/v1/uber/delivery-promotions/stores/:storeId",
|
||||||
|
authMode: "app",
|
||||||
|
scopes: AUTH_SCOPES.STORE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
genericProxy,
|
genericProxy,
|
||||||
menuUpsert,
|
menuUpsert,
|
||||||
@ -653,5 +700,9 @@ module.exports = {
|
|||||||
deliveryResolveFulfillmentIssues,
|
deliveryResolveFulfillmentIssues,
|
||||||
deliveryGetReplacementRecommendations,
|
deliveryGetReplacementRecommendations,
|
||||||
deliveryUpdatePartnerCount,
|
deliveryUpdatePartnerCount,
|
||||||
deliveryByocIngestCourierLocation
|
deliveryByocIngestCourierLocation,
|
||||||
|
deliveryCreatePromotion,
|
||||||
|
deliveryRevokePromotion,
|
||||||
|
deliveryGetPromotion,
|
||||||
|
deliveryListPromotions
|
||||||
};
|
};
|
||||||
|
|||||||
@ -688,4 +688,87 @@ router.post(
|
|||||||
asyncHandler(controller.deliveryByocIngestCourierLocation)
|
asyncHandler(controller.deliveryByocIngestCourierLocation)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @openapi
|
||||||
|
* /api/v1/uber/delivery-promotions/stores/{storeId}:
|
||||||
|
* post:
|
||||||
|
* summary: Promotions API 1.0.0 - Create promotion
|
||||||
|
* tags:
|
||||||
|
* - Uber Delivery Promotions v1
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: storeId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Promotion created
|
||||||
|
* get:
|
||||||
|
* summary: Promotions API 1.0.0 - Get promotions by store
|
||||||
|
* tags:
|
||||||
|
* - Uber Delivery Promotions v1
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: storeId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Promotions listed
|
||||||
|
*/
|
||||||
|
router.post(
|
||||||
|
"/uber/delivery-promotions/stores/:storeId",
|
||||||
|
asyncHandler(controller.deliveryCreatePromotion)
|
||||||
|
);
|
||||||
|
router.get(
|
||||||
|
"/uber/delivery-promotions/stores/:storeId",
|
||||||
|
asyncHandler(controller.deliveryListPromotions)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @openapi
|
||||||
|
* /api/v1/uber/delivery-promotions/{promotionId}:
|
||||||
|
* get:
|
||||||
|
* summary: Promotions API 1.0.0 - Get promotion by ID
|
||||||
|
* tags:
|
||||||
|
* - Uber Delivery Promotions v1
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: promotionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Promotion retrieved
|
||||||
|
*/
|
||||||
|
router.get(
|
||||||
|
"/uber/delivery-promotions/:promotionId",
|
||||||
|
asyncHandler(controller.deliveryGetPromotion)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @openapi
|
||||||
|
* /api/v1/uber/delivery-promotions/{promotionId}/revoke:
|
||||||
|
* post:
|
||||||
|
* summary: Promotions API 1.0.0 - Revoke promotion
|
||||||
|
* tags:
|
||||||
|
* - Uber Delivery Promotions v1
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: promotionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Promotion revoked
|
||||||
|
*/
|
||||||
|
router.post(
|
||||||
|
"/uber/delivery-promotions/:promotionId/revoke",
|
||||||
|
asyncHandler(controller.deliveryRevokePromotion)
|
||||||
|
);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user