Basket lock
Niektóre procesy zakupowe wymagają tymczasowego zablokowania koszyka, aby zapewnić dostępność produktów i niezmienność cen pomiędzy potwierdzeniem zamówienia a autoryzacją płatności. Dla takich scenariuszy możliwa jest konfiguracja żądania blokady, które następuje tuż przed właściwym zakupem:
Żądanie
OpenApp wykona żądanie HTTP POST do endpointu skonfigurowanego w panelu merchanta dla recalculate, ze zaktualizowanym koszykiem w treści żądania:
POST <recalculate-url>?lock=true
Jeśli skonfigurowano adres https://shop.example.com/api/openapp/basket, żądanie wykonane przez OpenApp będzie wyglądać następująco:
POST https://shop.example.com/api/openapp/basket?lock=true
Treść żądania zawiera koszyk użytkownika. Na przykład:
- Żądanie
- Schemat
{
"requestId": "request-id",
"id": "basket-id",
"price": {
"currency": "PLN",
"discounts": [
{
"code": "new-discount-code-text"
}
]
},
"products": [
{
"ean": "12312",
"id": "id123",
"quantity": 3
}
],
"loggedUser": "user-id-from-webshop"
}
requestIdstringWymaganeThe ID of the request as generated by OpenApp.
maxLength: 36
idstringOpcjonalneA null value for the basket id indicates that this is a request to create a new basket for a repurchase.
maxLength: 36
priceobiektWymaganePokaż parametry podrzędneUkryj parametry podrzędne2
currencystringWymaganeThe currency
discountstablica typu RecalculateDiscountWymaganeDiscounts to apply in price calculation.
Pokaż parametry podrzędneUkryj parametry podrzędne1
codestringWymaganeThe discount code.
maxLength: 36
productstablica typu RecalculateProductWymaganePokaż parametry podrzędneUkryj parametry podrzędne3
eanstringOpcjonalneThe ean (or other barcode on the product). Specifying this allows the user to search in his order history by scanning the barcode to do a re-purchase.
maxLength: 36
idstringWymaganeThe unique ID of the product.
maxLength: 36
quantitynumberWymaganeThe requested quantity
loggedUserstringOpcjonalneSurowy schemat JSON
{
"description": "Basket recalculate request",
"additionalProperties": false,
"type": "object",
"properties": {
"requestId": {
"description": "The ID of the request as generated by OpenApp.",
"maxLength": 36,
"type": "string",
"title": "requestId"
},
"id": {
"description": "A null value for the basket id indicates that this is a request to create a new basket for a repurchase.",
"maxLength": 36,
"type": "string",
"title": "id"
},
"price": {
"$ref": "#/definitions/RecalculatePrice",
"title": "price"
},
"products": {
"type": "array",
"items": {
"$ref": "#/definitions/RecalculateProduct"
},
"title": "products"
},
"loggedUser": {
"type": "string",
"title": "loggedUser"
}
},
"required": [
"price",
"products",
"requestId"
],
"definitions": {
"RecalculatePrice": {
"title": "RecalculatePrice",
"type": "object",
"properties": {
"currency": {
"description": "The currency",
"type": "string",
"title": "currency"
},
"discounts": {
"description": "Discounts to apply in price calculation.",
"type": "array",
"items": {
"$ref": "#/definitions/RecalculateDiscount"
},
"title": "discounts"
}
},
"required": [
"currency",
"discounts"
]
},
"RecalculateDiscount": {
"title": "RecalculateDiscount",
"type": "object",
"properties": {
"code": {
"description": "The discount code.",
"maxLength": 36,
"type": "string",
"title": "code"
}
},
"required": [
"code"
]
},
"RecalculateProduct": {
"title": "RecalculateProduct",
"type": "object",
"properties": {
"ean": {
"description": "The ean (or other barcode on the product). Specifying this allows the user to search in his order history by scanning the barcode to do a re-purchase.",
"maxLength": 36,
"type": "string",
"title": "ean"
},
"id": {
"description": "The unique ID of the product.",
"maxLength": 36,
"type": "string",
"title": "id"
},
"quantity": {
"description": "The requested quantity",
"type": "number",
"title": "quantity"
}
},
"required": [
"id",
"quantity"
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
Odpowiedź
W odpowiedzi sklep przesyła zawartość koszyka oraz dostępne opcje dostawy w takim samym formacie jak przy pobieraniu koszyka. Parametr expiresAt wskazuje czas, do którego koszyk jest aktualny i zablokowany:
- Odpowiedź
- Schemat
{
"id": "basket-id",
"expiresAt": "2022-03-23T21:00:00Z",
"price": {
"currency": "PLN",
"discounts": [
{
"code": "discount-code-text",
"value": 1000
}
],
"basketValue": 13000
},
"deliveryOptions": [
{
"key": "INPOST_APM",
"cost": 0
},
{
"key": "DPD_COURIER",
"cost": 1000,
"timing": "next business day"
}
],
"products": [
{
"ean": "12312",
"id": "id123",
"name": "Superb product",
"images": [
"http://cdn.merchant.com/static/products/id123/1",
"http://cdn.merchant.com/static/products/id123/2"
],
"quantity": 2,
"unitPrice": 7000,
"linePrice": 14000,
"originalUnitPrice": 7000,
"originalLinePrice": 14000,
"policies": [
{
"type": "AGE",
"criteria": {
"minAge": 18
}
}
]
}
],
"loggedUser": "user-id-from-webshop"
}
idstringWymaganeThe unique ID of the basket.
maxLength: 36
requestIdstringOpcjonalneThe ID of the basket request as generated by OpenApp. Mandatory in case of an asynchronous connection through a queue in order to correlate the placed order with the response.
maxLength: 36
expiresAtstringWymaganeThe moment until which the basket is valid. This can be used to indicate a basket needs to be ordered before a specific time in order to guarantee availability.
format: date-time
oaOrderIdstringOpcjonalneThe OpenApp order ID (if known).
priceobiektWymaganePokaż parametry podrzędneUkryj parametry podrzędne3
currencystringWymaganebasketValueintegerWymaganeThe price of the basket. Price is expressed as the number (integer) of 1/100s of the price.
minimum: 0
discountstablica typu BasketPriceDiscountWymaganeApplied discounts
Pokaż parametry podrzędneUkryj parametry podrzędne3
codestringWymaganeThe discount code.
maxLength: 36
valueintegerWymaganeThe value of the discount. Value is expressed as the number (integer) of 1/100s of the currency.
minimum: 0
errorenumOpcjonalneThe error code of the discount
Możliwe wartości: EXPIREDINVALIDNOT_APPLICABLEUSED
deliveryOptionstablica typu BasketDeliveryOptionWymaganePokaż parametry podrzędneUkryj parametry podrzędne3
keyenumWymaganeMożliwe wartości: DHL_COURIERDHL_PICKUPDPD_COURIERDPD_PICKUPELECTRONICFEDEX_COURIERGEIS_COURIERGLS_COURIERINPOST_APMINPOST_COURIERINSTORE_PICKUPORLEN_APMPOCZTA_POLSKA_APMPOCZTEX_COURIERUPS_COURIER
costintegerWymaganeThe price of the delivery. Price is expressed as the number (integer) of 1/100s of the price.
timingstringOpcjonalneThe estimation of the delivery time, i.e. 'next business day' or 'July 18th'.
maxLength: 40
productstablica typu BasketProductWymaganePokaż parametry podrzędneUkryj parametry podrzędne11
namestringWymaganeThe product name.
imagestablica typu stringWymaganeThe URLs of the product image
originalUnitPriceintegerWymaganeThe original (before discount) price of a single product. Price is expressed as the number (integer) of 1/100s of the price.
originalLinePriceintegerWymaganeThe original (before discount) price of the products. Price is expressed as the number (integer) of 1/100s of the price.
errorenumOpcjonalneError code when the product request can not be accomodated in a recalculate request.
Możliwe wartości: OUT_OF_STOCKQUANTITY_TOO_BIG
eanstringOpcjonalneThe ean (or other barcode on the product). Specifying this allows the user to search in his order history by scanning the barcode to do a re-purchase.
maxLength: 36
idstringWymaganeThe unique ID of the product.
maxLength: 36
quantityintegerWymaganeThe number of items in the purchase.
minimum: 0
unitPriceintegerWymaganeThe price of a single product. Price is expressed as the number (integer) of 1/100s of the price.
linePriceintegerWymaganeThe price of the products. Price is expressed as the number (integer) of 1/100s of the price.
policiestablica typu ProductPolicyOpcjonalneThe list of policies applied to the product.
maxItems: 1
Pokaż parametry podrzędneUkryj parametry podrzędne2
typeenumWymaganeMożliwe wartości: AGE
criteriaobiektWymaganePokaż parametry podrzędneUkryj parametry podrzędne1
minAgeintegerWymaganeminimum: 0
invoiceAddressMandatorybooleanOpcjonalneWhether an invoice address is mandatory
loggedUserstringOpcjonalneThe unique ID of the user.
maxLength: 255
Surowy schemat JSON
{
"description": "Basket returned on retrieval or recalculation",
"additionalProperties": false,
"type": "object",
"properties": {
"id": {
"description": "The unique ID of the basket.",
"maxLength": 36,
"type": "string",
"title": "id"
},
"requestId": {
"description": "The ID of the basket request as generated by OpenApp. Mandatory in case of an asynchronous connection through a queue in order to correlate the placed order with the response.",
"maxLength": 36,
"type": "string",
"title": "requestId"
},
"expiresAt": {
"description": "The moment until which the basket is valid. This can be used to indicate a basket needs to be ordered before a specific time in order to guarantee availability.",
"format": "date-time",
"type": "string",
"title": "expiresAt"
},
"oaOrderId": {
"description": "The OpenApp order ID (if known).",
"type": "string",
"title": "oaOrderId"
},
"price": {
"$ref": "#/definitions/BasketPrice",
"title": "price"
},
"deliveryOptions": {
"type": "array",
"items": {
"$ref": "#/definitions/BasketDeliveryOption"
},
"title": "deliveryOptions"
},
"products": {
"type": "array",
"items": {
"$ref": "#/definitions/BasketProduct"
},
"title": "products"
},
"invoiceAddressMandatory": {
"description": "Whether an invoice address is mandatory",
"type": "boolean",
"title": "invoiceAddressMandatory"
},
"loggedUser": {
"description": "The unique ID of the user.",
"maxLength": 255,
"type": "string",
"title": "loggedUser"
}
},
"required": [
"deliveryOptions",
"expiresAt",
"id",
"price",
"products"
],
"definitions": {
"BasketPrice": {
"title": "BasketPrice",
"type": "object",
"properties": {
"currency": {
"type": "string",
"title": "currency"
},
"basketValue": {
"description": "The price of the basket. Price is expressed as the number (integer) of 1/100s of the price.",
"minimum": 0,
"type": "integer",
"title": "basketValue"
},
"discounts": {
"description": "Applied discounts",
"type": "array",
"items": {
"$ref": "#/definitions/BasketPriceDiscount"
},
"title": "discounts"
}
},
"required": [
"basketValue",
"currency",
"discounts"
]
},
"BasketPriceDiscount": {
"title": "BasketPriceDiscount",
"type": "object",
"properties": {
"code": {
"description": "The discount code.",
"maxLength": 36,
"type": "string",
"title": "code"
},
"value": {
"description": "The value of the discount. Value is expressed as the number (integer) of 1/100s of the currency.",
"minimum": 0,
"type": "integer",
"title": "value"
},
"error": {
"description": "The error code of the discount",
"enum": [
"EXPIRED",
"INVALID",
"NOT_APPLICABLE",
"USED"
],
"type": "string",
"title": "error"
}
},
"required": [
"code",
"value"
]
},
"BasketDeliveryOption": {
"title": "BasketDeliveryOption",
"type": "object",
"properties": {
"key": {
"$ref": "#/definitions/MerchantDeliveryOptions",
"title": "key"
},
"cost": {
"description": "The price of the delivery. Price is expressed as the number (integer) of 1/100s of the price.",
"type": "integer",
"title": "cost"
},
"timing": {
"description": "The estimation of the delivery time, i.e. 'next business day' or 'July 18th'.",
"maxLength": 40,
"type": "string",
"title": "timing"
}
},
"required": [
"cost",
"key"
]
},
"MerchantDeliveryOptions": {
"title": "MerchantDeliveryOptions",
"enum": [
"DHL_COURIER",
"DHL_PICKUP",
"DPD_COURIER",
"DPD_PICKUP",
"ELECTRONIC",
"FEDEX_COURIER",
"GEIS_COURIER",
"GLS_COURIER",
"INPOST_APM",
"INPOST_COURIER",
"INSTORE_PICKUP",
"ORLEN_APM",
"POCZTA_POLSKA_APM",
"POCZTEX_COURIER",
"UPS_COURIER"
],
"type": "string"
},
"BasketProduct": {
"title": "BasketProduct",
"type": "object",
"properties": {
"name": {
"description": "The product name.",
"type": "string",
"title": "name"
},
"images": {
"description": "The URLs of the product image",
"type": "array",
"items": {
"type": "string"
},
"title": "images"
},
"originalUnitPrice": {
"description": "The original (before discount) price of a single product. Price is expressed as the number (integer) of 1/100s of the price.",
"type": "integer",
"title": "originalUnitPrice"
},
"originalLinePrice": {
"description": "The original (before discount) price of the products. Price is expressed as the number (integer) of 1/100s of the price.",
"type": "integer",
"title": "originalLinePrice"
},
"error": {
"description": "Error code when the product request can not be accomodated in a recalculate request.",
"enum": [
"OUT_OF_STOCK",
"QUANTITY_TOO_BIG"
],
"type": "string",
"title": "error"
},
"ean": {
"description": "The ean (or other barcode on the product). Specifying this allows the user to search in his order history by scanning the barcode to do a re-purchase.",
"maxLength": 36,
"type": "string",
"title": "ean"
},
"id": {
"description": "The unique ID of the product.",
"maxLength": 36,
"type": "string",
"title": "id"
},
"quantity": {
"description": "The number of items in the purchase.",
"minimum": 0,
"type": "integer",
"title": "quantity"
},
"unitPrice": {
"description": "The price of a single product. Price is expressed as the number (integer) of 1/100s of the price.",
"type": "integer",
"title": "unitPrice"
},
"linePrice": {
"description": "The price of the products. Price is expressed as the number (integer) of 1/100s of the price.",
"type": "integer",
"title": "linePrice"
},
"policies": {
"description": "The list of policies applied to the product.",
"maxItems": 1,
"type": "array",
"items": {
"$ref": "#/definitions/ProductPolicy"
},
"title": "policies"
}
},
"required": [
"id",
"images",
"linePrice",
"name",
"originalLinePrice",
"originalUnitPrice",
"quantity",
"unitPrice"
]
},
"ProductPolicy": {
"title": "ProductPolicy",
"type": "object",
"properties": {
"type": {
"$ref": "#/definitions/ProductPolicyType",
"title": "type"
},
"criteria": {
"$ref": "#/definitions/AgeCriteria",
"title": "criteria"
}
},
"required": [
"criteria",
"type"
]
},
"ProductPolicyType": {
"title": "ProductPolicyType",
"enum": [
"AGE"
],
"type": "string"
},
"AgeCriteria": {
"title": "AgeCriteria",
"type": "object",
"properties": {
"minAge": {
"type": "integer",
"minimum": 0,
"title": "minAge"
}
},
"required": [
"minAge"
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
Może się oczywiście zdarzyć, że sklep nie będzie w stanie zrealizować żądanego koszyka, na przykład z powodu braku towaru lub zmiany ceny. Wówczas sklep odpowiada dostępną częścią koszyka oraz kodem błędu wskazującym problemy. OpenApp wyświetli te informacje użytkownikowi, aby mógł zdecydować o dalszym zakupie.
To jest przykład prostego koszyka. Pełny opis zawiera zakładka Schemat powyżej.