Pobieranie koszyka
Wywołanie pobierania koszyka jest wykonywane, gdy użytkownik OpenApp chce dokonać zakupu i skanuje kod QR w aplikacji OpenApp. Widoczne jako krok 4 na diagramie sekwencji:
Żądanie
Gdy klient skanuje kod QR, OpenApp pobiera koszyk. Jest to żądanie HTTP GET z serwera OpenApp do endpointu skonfigurowanego w panelu merchanta, z parametrem basketId równym wartości data-basket ustawionej w integracji frontendu sklepu:
GET <basket-url>?basketId=<data-basket>
Jeśli skonfigurowano adres https://shop.example.com/api/openapp/basket i basketId to 6548654ef654d654aa, żądanie wykonane przez OpenApp będzie wyglądać następująco:
GET https://shop.example.com/api/openapp/basket?basketId=6548654ef654d654aa
Odpowiedź
W odpowiedzi sklep powinien przesłać zawartość koszyka i skonfigurowane opcje dostawy. W poniższym przykładzie użytkownik ma w koszyku 2 sztuki „Superb product" w cenie 70,00 zł każda. Ponieważ zastosował kod rabatowy -10 zł, łączna cena wynosi 130 zł. Zamówienie może zostać dostarczone do Paczkomatu InPost bezpłatnie lub kurierem za dopłatą 10 zł.
- 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#"
}
Zasady produktów (opcjonalne)
Opcje policies na poziomie produktu są opcjonalne i mogą być przesyłane tylko gdy jest to wymagane przez merchanta. Na przykład, jeśli produkt jest przeznaczony wyłącznie dla dorosłych, merchant może dołączyć zasadę wiekową:
type: AGEcriteria.minAge: 18
Jeśli dodatkowe ograniczenia produktu nie są potrzebne, policies można pominąć.
expiresAt
Ważność koszyka określana jest w polu expiresAt. OpenApp pozwala użytkownikowi złożyć zamówienie do tego momentu (krok 7 na diagramie). Po otrzymaniu zamówienia od użytkownika OpenApp autoryzuje płatność, co może trwać maksymalnie 3 minuty. Tak więc OpenApp wyśle zamówienie do merchanta najpóźniej 3 minuty po czasie określonym w expiresAt.
Jeśli przez 5 minut nie uda się nawiązać komunikacji z backendem sklepu (łącznie maksymalnie 8 minut od expiresAt), OpenApp anuluje transakcję i dokonuje zwrotu płatności użytkownikowi.
To jest przykład prostego koszyka. Pełny opis odpowiedzi koszyka zawiera zakładka Schemat powyżej.