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:
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
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
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
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
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
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
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
[]
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
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
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 StringdiscountedBasketItems[].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
andloyaltyData.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 appliedField Descriptions: Enhanced descriptions for
discountedBasketItems
andconditionConsumedBasketItems
for better clarityProduct 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?