Basket Offer Flows

This document provides a detailed explanation of the basket offer flows, including the purpose of the flow, the services involved, and the description of each field in the requests and responses.

Purpose of the Flow

The Basket Offer Flow is designed to integrate with third-party systems to retrieve and apply discount offers to a customer's shopping basket. This flow ensures that the basket's current state, including its items and any existing discounts, is sent to the third-party system. The third-party system evaluates the basket and returns applicable offers, which are then applied to the basket before proceeding to the payment stage. This flow is particularly useful for:

  • Dynamic Discount Calculation: Allowing third-party systems to calculate discounts based on the basket's contents.

  • Custom Promotions: Supporting external promotion engines to provide tailored offers.

  • Scalability: Standardizing the integration with multiple third-party systems using a consistent API pattern.

This part of the document contains the list of services that can be integrated in flows above. 2 configuration parameters will be shared during integration:

Field
Description

username

Username for basic authentication

password

Password for basic authentication

basket-offers (POST)

This service is used to retrieve discount offers for a customer's basket from a third-party system. It sends the current state of the basket and user information to the third-party system and receives applicable offers in response.

URL:

^^/offers

Request Headers

Header
Description
Requirement

x-akinon-request-id

Unique ID for problem solving & tracing.

Mandatory

x-akinon-api-version

Akinon Customer API version.

Mandatory

Authorization

Basic [BASE64_encoded(username:password)]

Mandatory

Request Body Structure

Field
Type
Description

basket

Object

Container for basket information

basket.id

Number

Unique identifier for the basket

basket.version

Number

Version of the basket to ensure consistency

basket.basketItems

Array

List of items in the basket

basket.basketItems[].id

Number

Unique identifier for the basket item

basket.basketItems[].unitPrice

String

Price per unit of the item

basket.basketItems[].quantity

Number

Quantity of the item in the basket

basket.basketItems[].unitType

String

Type of unit (e.g., QUANTITY, KILOGRAM)

basket.basketItems[].taxRate

String

Tax rate applied to the item

basket.basketItems[].totalAmount

String

Total price of the item (unitPrice * quantity)

basket.basketItems[].discountAmount

String

Total discount applied to the item

basket.basketItems[].globallyConsumedQuantity

String

Quantity consumed globally for discounts (decimal value as string)

basket.basketItems[].currencyType

String

Currency code (ISO 4217)

basket.basketItems[].appliedDiscounts

Array

List of discounts applied to this item

basket.basketItems[].appliedDiscounts[].discount

Object

Discount details

basket.basketItems[].appliedDiscounts[].discount.type

String

Type of discount (LOYALTY_POINT, SAMPLE_PRODUCT, DEFERRED, POINT, SHIPPING, BASKET)

basket.basketItems[].appliedDiscounts[].discount.description

String

Description of the discount

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems

Array

Items to which the discount will be applied and distributed based on quantity

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems[].pk

Number

Primary key of the basket item

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems[].quantity

String

Quantity of the item affected by the discount (decimal value as string)

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems

Array

Items consumed to meet discount conditions; no additional items are consumed once offer conditions are satisfied

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems[].pk

Number

Primary key of the basket item

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems[].quantity

String

Quantity consumed for the discount (decimal value as string)

basket.basketItems[].appliedDiscounts[].discount.extraArgs

Object

Additional arguments for the discount

basket.basketItems[].product

Object

Product information

basket.basketItems[].product.id

Number

Unique identifier for the product

basket.basketItems[].product.sku

String

Stock Keeping Unit of the product

basket.basketItems[].product.name

String

Name of the product

basket.basketItems[].product.attributes

Object

Additional attributes of the product

user

Object

User information

user.emailAllowed

Boolean

Whether the user allows email communication

user.smsAllowed

Boolean

Whether the user allows SMS communication

user.callAllowed

Boolean

Whether the user allows phone calls

user.phone

String/Null

User's phone number

user.email

Array

List of user's email addresses

Request Body Example

{
    "basket": {
        "id": 32,
        "version": 1758310922044282,
        "basketItems": [
            {
                "id": 59,
                "unitPrice": "500.00",
                "quantity": 1,
                "unitType": "QUANTITY",
                "taxRate": "20.00",
                "totalAmount": "500.00",
                "discountAmount": "0.00",
                "globallyConsumedQuantity": "0.0",
                "currencyType": "TRY",
                "appliedDiscounts": [
                    {
                        "discount": {
                            "type": "BASKET",
                            "description": "Internal Offer",
                            "discountedBasketItems": [
                                {
                                    "pk": 59,
                                    "quantity": "1"
                                },
                                {
                                    "pk": 58,
                                    "quantity": "7"
                                }
                            ],
                            "conditionConsumedBasketItems": [
                                {
                                    "pk": 58,
                                    "quantity": "0.2"
                                }
                            ],
                            "extraArgs": {
                                "discount": "0.00"
                            },
                        }
                    }
                ],
                "product": {
                    "id": 100009,
                    "sku": "SKU8",
                    "name": "Test Product 8",
                    "attributes": {}
                }
            },
            {
                "id": 58,
                "unitPrice": "500.00",
                "quantity": 7,
                "unitType": "QUANTITY",
                "taxRate": "20.00",
                "totalAmount": "3500.00",
                "discountAmount": "12.32",
                "globallyConsumedQuantity": "0.0",
                "currencyType": "TRY",
                "appliedDiscounts": [
                    {
                        "discount": {
                            "type": "BASKET",
                            "description": "Internal Offer",
                            "discountedBasketItems": [
                                {
                                    "pk": 59,
                                    "quantity": "1"
                                },
                                {
                                    "pk": 58,
                                    "quantity": "7"
                                }
                            ],
                            "conditionConsumedBasketItems": [
                                {
                                    "pk": 58,
                                    "quantity": "0.2"
                                }
                            ],
                            "extraArgs": {
                                "discount": "12.32"
                            },
                        }
                    }
                ],
                "product": {
                    "id": 100010,
                    "sku": "SKU9",
                    "name": "Test Product 9",
                    "attributes": {}
                }
            }
        ]
    },
    "user": {
        "emailAllowed": true,
        "smsAllowed": true,
        "callAllowed": false,
        "phone": null,
        "email": []
    }
}

Discount Types Extra Args

The following discount types and their associated extra arguments are supported:

Loyalty Point Extra Args

Field
Type
Description

loyaltyData

Object

Loyalty point information

loyaltyData.amount

String

Amount of loyalty points used (decimal value as string)

loyaltyData.benefitCoefficient

String

Coefficient for calculating benefits

loyaltyData.validFrom

String

Start date of the loyalty points

loyaltyData.validUntil

String

Expiration date of the loyalty points

{
  "extraArgs": {
    "loyaltyData": {
      "amount": "50.00",
      "benefitCoefficient": "1.5",
      "validFrom": "2025-01-01",
      "validUntil": "2025-12-31"
    }
  }
}

Sample Product Extra Args

Field
Type
Description

sampleProducts

Array

List of sample products

sampleProducts[].id

Number

Unique identifier for the sample product

allowedQuantity

Number

Maximum quantity allowed for the sample product

{
  "extraArgs": {
    "sampleProducts": [
      {
        "id": 12345
      },
      {
        "id": 67890
      }
    ],
    "allowedQuantity": 2
  }
}

Deferred Extra Args

Field
Type
Description

data

Object

Deferred discount data

data.coupon

String

Coupon code for the deferred discount

{
  "extraArgs": {
    "data": {
      "coupon": "SAVE2025"
    }
  }
}

Point Extra Args

No additional arguments required.

{
  "extraArgs": {}
}

Shipping Extra Args

No additional arguments required.

{
  "extraArgs": {}
}

Basket Extra Args

Field
Type
Description

discount

String

Total discount applied to the basket (decimal value as string)

{
  "extraArgs": {
    "discount": "25.50"
  }
}

Request Body (typescript interface)

interface BasketOffersRequest {
  basket: Basket;
  user: User;
}

interface Basket {
  id: number;
  version: number;
  basketItems: BasketItem[];
}

interface BasketItem {
  id: number;
  unitPrice: string;
  quantity: number;
  unitType: string;
  taxRate: string;
  totalAmount: string;
  discountAmount: string;
  globallyConsumedQuantity: string;
  currencyType: string;
  appliedDiscounts: AppliedDiscount[];
  product: Product;
}

interface AppliedDiscount {
  discount: Discount;
}

interface BaseDiscount {
  type: 'LOYALTY_POINT' | 'SAMPLE_PRODUCT' | 'DEFERRED' | 'POINT' | 'SHIPPING' | 'BASKET';
  description: string;
  discountedBasketItems: DiscountedBasketItem[];
  conditionConsumedBasketItems: ConditionConsumedBasketItem[];
}

type Discount =
  | (BaseDiscount & { type: 'LOYALTY_POINT'; extraArgs: LoyaltyPointArgs })
  | (BaseDiscount & { type: 'SAMPLE_PRODUCT'; extraArgs: SampleProductArgs })
  | (BaseDiscount & { type: 'DEFERRED'; extraArgs: DeferredArgs })
  | (BaseDiscount & { type: 'POINT'; extraArgs?: undefined })
  | (BaseDiscount & { type: 'SHIPPING'; extraArgs?: undefined })
  | (BaseDiscount & { type: 'BASKET'; extraArgs: BasketArgs });

interface LoyaltyPointArgs {
  loyaltyData: {
    amount: string;
    benefitCoefficient: string;
    validFrom: string; 
    validUntil: string;
  };
}

interface SampleProductArgs {
  sampleProducts: {
    id: number;
  }[];
  allowedQuantity: number;
}

interface DeferredArgs {
  data: {
    coupon: string;
  };
}

interface BasketArgs {
  discount: string;
}

interface DiscountedBasketItem {
  pk: number;
  quantity: string;
}

interface ConditionConsumedBasketItem {
  pk: number;
  quantity: string;
}

interface Product {
  id: number;
  sku: string;
  name: string;
  attributes: Record<string, any>;
}

interface User {
  emailAllowed: boolean;
  smsAllowed: boolean;
  callAllowed: boolean;
  phone: string | null;
  email: string[];
}

Response Body Structure

Field
Type
Description

[]

Array

List of available offers

[].notifyAfterOrderCreation

Boolean

Indicates if the offer requires notification after order creation

[].discount

Object

Discount details

[].discount.id

String

Unique identifier for the discount

[].discount.type

String

Type of discount (LOYALTY_POINT, SAMPLE_PRODUCT, DEFERRED, POINT, SHIPPING, BASKET)

[].discount.description

String

Description of the discount

[].discount.discountedBasketItems

Array

Items to which the discount will be applied and distributed based on quantity

[].discount.discountedBasketItems[].pk

Number

Primary key of the basket item

[].discount.discountedBasketItems[].quantity

Number

Quantity of the item affected by the discount

[].discount.conditionConsumedBasketItems

Array

Items consumed for the discount condition

[].discount.conditionConsumedBasketItems[].pk

Number

Primary key of the basket item consumed for the discount

[].discount.conditionConsumedBasketItems[].quantity

Number

Quantity consumed for the discount

[].discount.extraArgs

Object

Additional arguments for the discount

[].priority

Number

Priority of the discount

[].label

String

Label for the discount

[].isMergeable

Boolean

Indicates if the discount can be combined with other discounts

[].successMessage

String

Message displayed when the discount is successfully applied

[].upsellMessage

String

Message encouraging the user to take further actions

Response Body Example

[
    {
        "successMessage": "Congratulations! You saved 25.50 TRY with our Spring Sale promotion.",
        "upsellMessage": "Add 2 more items to your cart and get free shipping!",
        "label": "Spring Sale - 15% Off",
        "priority": 1,
        "discount": {
            "description": "Spring Sale 2025 - 15% Off on Fashion Items",
            "discountedBasketItems": [
                {
                    "pk": 58,
                    "quantity": "1"
                }
            ],
            "extraArgs": {
                "discount": "25.50"
            },
            "conditionConsumedBasketItems": [
                {
                    "pk": 58,
                    "quantity": "1"
                }
            ],
            "type": "BASKET",
            "id": "v2-spring-discount-2025"
        },
        "notifyAfterOrderCreation": false,
        "isMergeable": true
    },
    {
        "successMessage": "Thank you for being a loyal customer! You saved 10 TRY with your member discount.",
        "upsellMessage": "Add 2 more items to your cart and get free shipping!",
        "label": "Loyalty Reward - 10 TRY Off",
        "priority": 2,
        "discount": {
            "description": "Loyalty Member Special Discount",
            "discountedBasketItems": [
                {
                    "pk": 59,
                    "quantity": "1"
                }
            ],
            "extraArgs": {
                "discount": "10.00"
            },
            "conditionConsumedBasketItems": [
                {
                    "pk": 59,
                    "quantity": "1"
                }
            ],
            "type": "BASKET",
            "id": "v2-loyalty-reward-2025"
        },
        "notifyAfterOrderCreation": true,
        "isMergeable": true
    }
]

Response Body (typescript interface)

type BasketOffersResponse = BasketOffer[];

interface BasketOffer {
  notifyAfterOrderCreation: boolean;
  discount: ResponseDiscount;
  priority: number;
  label: string;
  isMergeable: boolean;
  successMessage: string;
  upsellMessage: string;
}

interface ResponseDiscount {
  id: string;
  type: 'LOYALTY_POINT' | 'SAMPLE_PRODUCT' | 'DEFERRED' | 'POINT' | 'SHIPPING' | 'BASKET';
  description: string;
  discountedBasketItems: ResponseDiscountedBasketItem[];
  conditionConsumedBasketItems: ResponseConditionConsumedBasketItem[];
  extraArgs?: Record<string, any>;
}

interface ResponseDiscountedBasketItem {
  pk: number;
  quantity: string;
}

interface ResponseConditionConsumedBasketItem {
  pk: number;
  quantity: string;
}

basket-offers-used (POST)

This service is used to notify the system about the discounts that were applied to the basket. It ensures that the third-party system is informed about the usage of the offers.

URL:

^^/use-offers

Request Headers

Header
Description
Requirement

x-akinon-request-id

Unique ID for problem solving & tracing.

Mandatory

x-akinon-api-version

Akinon Customer API version.

Mandatory

Authorization

Basic [BASE64_encoded(username:password)]

Mandatory

Request Body Structure

Field
Type
Description

basket

Object

Final state of the basket

basket.id

Number

Unique identifier for the basket

basket.version

Number

Version of the basket to ensure consistency

basket.basketItems

Array

List of items in the basket

basket.basketItems[].id

Number

Unique identifier for the basket item

basket.basketItems[].unitPrice

String

Price per unit of the item

basket.basketItems[].quantity

Number

Quantity of the item in the basket

basket.basketItems[].unitType

String

Type of unit (e.g., QUANTITY, KILOGRAM)

basket.basketItems[].taxRate

String

Tax rate applied to the item

basket.basketItems[].totalAmount

String

Total price of the item (unitPrice * quantity)

basket.basketItems[].discountAmount

String

Total discount applied to the item

basket.basketItems[].globallyConsumedQuantity

String

Quantity consumed globally for discounts (decimal value as string)

basket.basketItems[].currencyType

String

Currency code (ISO 4217)

basket.basketItems[].appliedDiscounts

Array

List of discounts applied to this item

basket.basketItems[].appliedDiscounts[].discount

Object

Discount details

basket.basketItems[].appliedDiscounts[].discount.type

String

Type of discount (LOYALTY_POINT, SAMPLE_PRODUCT, DEFERRED, POINT, SHIPPING, BASKET)

basket.basketItems[].appliedDiscounts[].discount.description

String

Description of the discount

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems

Array

Items to which the discount will be applied and distributed based on quantity

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems[].pk

Number

Primary key of the basket item

basket.basketItems[].appliedDiscounts[].discount.discountedBasketItems[].quantity

String

Quantity of the item affected by the discount

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems

Array

Items consumed to meet discount conditions; no additional items are consumed once offer conditions are satisfied

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems[].pk

Number

Primary key of the basket item

basket.basketItems[].appliedDiscounts[].discount.conditionConsumedBasketItems[].quantity

String

Quantity consumed for the discount (decimal value as string)

basket.basketItems[].appliedDiscounts[].discount.extraArgs

Object

Additional arguments for the discount

basket.basketItems[].product

Object

Product information

basket.basketItems[].product.id

Number

Unique identifier for the product

basket.basketItems[].product.sku

String

Stock Keeping Unit of the product

basket.basketItems[].product.name

String

Name of the product

basket.basketItems[].product.attributes

Object

Additional attributes of the product

basket.basketItems[].product.attributes.categoryId

String

Category id of the product

basket.basketItems[].product.attributes.variantId

String

Variant id of the product

usedDiscounts

Array

List of used discount identifiers

usedDiscounts[]

String

Unique identifier for a used discount

Request Body Example

{
    "basket": {
        "id": 32,
        "version": 1758199055052632,
        "basketItems": [
            {
                "id": 49,
                "unitPrice": "500.00",
                "quantity": 1,
                "unitType": "Quantity",
                "taxRate": "20.00",
                "totalAmount": "500.00",
                "discountAmount": "0.00",
                "globallyConsumedQuantity": "0.0",
                "currencyType": "try",
                "appliedDiscounts": [
                    {
                        "discount": {
                            "type": "basket",
                            "description": "Internal Offer",
                            "discountedBasketItems": [
                                {
                                    "pk": 49,
                                    "quantity": "1"
                                },
                                {
                                    "pk": 47,
                                    "quantity": "1"
                                }
                            ],
                            "conditionConsumedBasketItems": [
                                {
                                    "pk": 47,
                                    "quantity": "1"
                                }
                            ],
                            "extraArgs": {
                                "discount": "12.32"
                            }
                        }
                    }
                ],
                "product": {
                    "id": 100009,
                    "sku": "SKU8",
                    "name": "Test Product 8",
                    "attributes": {
                        "categoryId": "electronics",
                        "variantId": "red-xl"
                    }
                }
            }
        ]
    },
    "usedDiscounts": [
        "v2-spring-discount-2025",
        "v2-loyalty-reward-2025"
    ]
}

Request Body (typescript interface)

interface BasketOffersUsedRequest {
  basket: Basket; 
  usedDiscounts: string[];
}

interface Basket {
  id: number;
  version: number;
  basketItems: BasketItem[];
}

interface BasketItem {
  id: number;
  unitPrice: string;
  quantity: number;
  unitType: string;
  taxRate: string;
  totalAmount: string;
  discountAmount: string;
  globallyConsumedQuantity: string;
  currencyType: string;
  appliedDiscounts: AppliedDiscount[];
  product: Product;
}

interface AppliedDiscount {
  discount: Discount;
}

interface Discount {
  type: 'LOYALTY_POINT' | 'SAMPLE_PRODUCT' | 'DEFERRED' | 'POINT' | 'SHIPPING' | 'BASKET';
  description: string;
  discountedBasketItems: DiscountedBasketItem[];
  conditionConsumedBasketItems: ConditionConsumedBasketItem[];
}

interface DiscountedBasketItem {
  pk: number;
  quantity: string;
}

interface ConditionConsumedBasketItem {
  pk: number;
  quantity: string;
}

interface Product {
  id: number;
  sku: string;
  name: string;
  attributes: Record<string, any>;
}

Response Body (raw 200)

(no body)

Response Body For Errors (ALL)

If any errors are encountered in the services, these errors should be reported in the format below, and the list of error codes should be shared with Akinon.

  • Response Body (raw 4xx/5xx json)

{
    "errors": [
       {
           "code": "",
           "field": "",
           "message": ""
       }
   ]
}
  • Response Body (raw 4xx/5xx typescript interface)

interface ErrorResponse {
  errors: ErrorItem[];
}

interface ErrorItem {
  code: string;
  field: string;
  message: string;
}

Changelog

Version 2.0.0 - September 18, 2025

Changed

  • Request/Response Structure: Removed inline comments from JSON examples and moved field descriptions to structured tables

  • Data Types: Updated field types to reflect actual implementation:

    • unitPrice, totalAmount, discountAmount, taxRate changed from Number to String

    • discountedBasketItems[].quantity in request changed from Number to String (decimal values serialized as strings)

    • conditionConsumedBasketItems[].quantity in request changed to String format (decimal values serialized as strings)

    • extraArgs.discount and loyaltyData.amount changed from Number to String (decimal values serialized as strings)

    • globallyConsumedQuantity changed from Number to String (decimal values serialized as strings)

  • Field Removal: Removed consumedQuantity field from request bodies as this value is reset when each offer is applied

  • Field Descriptions: Enhanced descriptions for discountedBasketItems and conditionConsumedBasketItems for better clarity

  • Product Attributes: Changed from Array to Object structure

  • User Fields: Updated nullable fields to properly reflect optional nature

  • Response Format: Updated examples to match actual API responses

Added

  • Field Documentation: Comprehensive tables describing all request and response fields

  • Real Examples: Updated request and response examples with actual data from implementation

  • Type Consistency: Improved type definitions to match actual API behavior

Improved

  • Documentation Structure: Better organization with separate tables for field descriptions

  • Examples: More realistic and comprehensive JSON examples

  • Type Safety: Enhanced TypeScript interfaces to match actual implementation

Last updated

Was this helpful?