Requiply
SDK TypeScript

Sprzedaż i towary na sprzedaż

Wyświetlaj towary na sprzedaż i ich stany, odczytuj i rejestruj sprzedaż oraz sprzedawaj towary razem z rezerwacją za pomocą SDK.

Te zasoby obsługują moduł Sprzedaż: towary, takie jak karty pamięci, akumulatory czy taśma gaffer, które wypożyczalnia sprzedaje z ewidencją stanów obok wynajmu.

Organizacja musi mieć plan Advanced i włączone Włącz sprzedaż w Funkcje. W przeciwnym razie każda metoda zgłasza RequiplyError ze status403 i reasonfeature_disabled (selling_disabled dla klucza publicznego).
MetodaKlucz tajnyKlucz publiczny
saleItems.list(), saleItems.get()TakTylko aktywne towary, gdy organizacja sprzedaje klientom
saleLines w pricing.quote() i bookings.create()TakTak, w granicach stanu magazynowego, gdy organizacja sprzedaje klientom
sales.list(), sales.get(), sales.create()TakNie

Towary na sprzedaż są oddzielone od pozycji do wynajęcia: inventory.list(), dostępność i categories.list() nigdy ich nie zwracają.

Z kluczem publicznym

Sklep internetowy może pokazywać towary na sprzedaż i pozwalać klientom dodawać je do zapytania o rezerwację, tak jak portal klienta robi to w kroku Produkty do zakupu. Klucz publiczny ma do nich dostęp tylko wtedy, gdy organizacja sprzedaje klientom, co wymaga spełnienia wszystkich trzech warunków:

  • funkcja Sprzedaż włączona w planie Advanced, jak wyżej;
  • włączona opcja Sprzedaż towarów w ustawieniach portalu klienta;
  • co najmniej jeden niezarchiwizowany towar na sprzedaż.

W przeciwnym razie wywołanie zgłasza 403 z reason selling_disabled, więc sklep internetowy może ukryć sekcję z towarami.

Z kluczem publicznym:

  • saleItems.list() zwraca tylko aktywne towary, niezależnie od wartości filter. barcode i purchaseCost mają zawsze wartość null.
  • saleItems.get() zwraca 404 dla zarchiwizowanego towaru, a soldUnits30d, revenue30d i soldUnitsTotal mają wartość 0.
  • saleLines nie może prosić o więcej niż stockOnHand. Pozycja ponad stan zgłasza 409 z reason out_of_stock. data.saleItemId wskazuje towar, a data.availableQuantity mówi, ile zostało (0, gdy towar jest wyprzedany).
try {
  await requiply.pricing.quote({ startDate, endDate, items, saleLines });
} catch (error) {
  if (error instanceof RequiplyError && error.reason === 'out_of_stock') {
    showNotice(`Only ${error.data?.availableQuantity} left`);
  } else if (error instanceof RequiplyError && error.reason === 'selling_disabled') {
    hideGoodsSection();
  } else {
    throw error;
  }
}

saleItems.list()

saleItems.list(
  params?: SaleItemsListParams,
  options?: RequiplyRequestOptions,
): Promise<SaleItemsListResponse>

Parametry opcjonalne: search (nazwa, SKU lub kod kreskowy), category (identyfikator kategorii), filter (domyślnie active, a także archived lub all; klucze publiczne zawsze dostają active), limit (od 1 do 100, domyślnie 25) i cursor.

const { items, nextCursor } = await requiply.saleItems.list({ search: 'battery' });

for (const item of items) {
  console.log(item.name, item.salePrice, item.currency, item.stockOnHand);
}
PoleCo zawiera
id, name, sku, barcodeTowar. sku i barcode mogą mieć wartość null. Dla klucza publicznego barcode ma zawsze wartość null.
categoryId, categoryName, imageUrlMogą mieć wartość null.
salePrice, currencyStała cena za sztukę w walucie organizacji.
stockOnHandLiczba sztuk na półce. Może być ujemna, gdy sprzedaż przekroczyła zapisany stan.
purchaseCostKoszt netto za sztukę albo null, chyba że klucz może zarządzać stanem magazynowym. Dla klucza publicznego zawsze null.
isArchivedZarchiwizowanych towarów nie można sprzedawać.

saleItems.get()

saleItems.get(
  saleItemId: string,
  options?: RequiplyRequestOptions,
): Promise<SaleItemResponse>

Zwraca saleItem z powyższymi polami oraz soldUnits30d, revenue30d i soldUnitsTotal.

const { saleItem } = await requiply.saleItems.get(itemId);
console.log(saleItem.soldUnits30d, saleItem.revenue30d);

sales.list()

sales.list(
  params?: SalesListParams,
  options?: RequiplyRequestOptions,
): Promise<SalesListResponse>

Wymienia sprzedaże od najnowszej, zarówno samodzielne, jak i w ramach rezerwacji. Filtry opcjonalne:

ParametrDziałanie
kindstandalone lub booking.
statuscompleted lub cancelled.
unpaidtrue dla samodzielnych sprzedaży, które nie są jeszcze w pełni opłacone.
clientIdSprzedaże jednego klienta.
soldFrom, soldToDaty z godziną w formacie ISO 8601.
searchNumer sprzedaży, nazwa klienta, e-mail lub telefon, nazwa towaru lub SKU.
limit, cursorRozmiar strony (od 1 do 100, domyślnie 25) i nextCursor poprzedniej strony.
const { sales, currency } = await requiply.sales.list({ kind: 'standalone', unpaid: true });

Każda sprzedaż ma id, saleOrgId (numer sprzedaży, który pracownicy widzą w aplikacji), status, soldAt, total, returnedTotal, net (suma pomniejszona o zwroty), paidAmount, balance, paymentMethod, paidAt, note, klienta, rezerwację, do której należy (reservationId, reservationOrgId), itemCount i itemsLabel. balance to kwota, której samodzielna sprzedaż nadal wymaga. Dla sprzedaży w ramach rezerwacji ma zawsze wartość 0, bo płaci się za nią w rezerwacji.

sales.get()

sales.get(
  id: string | number,
  params?: { idKind?: 'internal' | 'org' },
  options?: RequiplyRequestOptions,
): Promise<SaleResponse>

id to UUID sprzedaży albo numer sprzedaży z aplikacji z idKind: 'org'.

const { sale } = await requiply.sales.get(12, { idKind: 'org' });

Sprzedaż zawiera też lines (towar, ilość, returnedQuantity, unitPrice, lineTotal), returns i payments. W przypadku sprzedaży w ramach rezerwacji payments to płatności rezerwacji, bo rezerwacja pobiera opłatę za wynajem i towary w jednej płatności.

sales.create()

sales.create(
  input: SaleCreateInput,
  options?: RequiplyRequestOptions,
): Promise<SaleCreateResponse>

Rejestruje samodzielną sprzedaż, tak jak Nowa sprzedaż w aplikacji.

const { sale, stockWarnings, payment } = await requiply.sales.create({
  lines: [{ saleItemId: itemId, quantity: 2 }],
  client: { name: 'Alex', email: 'customer@example.com' },
  paymentMethod: 'monobank',
  note: 'Counter sale',
});

if (payment?.paymentUrl) console.log('Pay here:', payment.paymentUrl);
PoleZasady
linesWymagane. Od 1 do 100 towarów, każdy najwyżej raz, z ilością będącą liczbą całkowitą większą od zera. Każda pozycja jest sprzedawana po cenie salePrice towaru.
clientId lub clientOpcjonalne. client jest dopasowywany po adresie e-mail, potem po telefonie, a gdy żaden nie pasuje, zostaje utworzony.
paymentMethodpayOnPickup (domyślnie) albo monobank, liqpay, wayforpay lub stripe przy aktywnej integracji. liqpay wymaga klienta z adresem e-mail.
soldAtISO 8601. Domyślnie bieżący moment.
noteDo 2000 znaków.

Stan magazynowy spada od razu. Sprzedaż może zejść ze stanem poniżej zera: nadal zostaje zarejestrowana, a stockWarnings wymienia każdy taki towar z jego stockOnHand i stanem after po sprzedaży. payment to oczekująca płatność, od której zaczyna się sprzedaż, z paymentUrl dla metody online.

Odrzucona sprzedaż zgłasza RequiplyError z reason, takim jak sale_item_archived, payment_method_unavailable lub client_email_required. Pełną listę zawiera Obsługa błędów.

Towary w rezerwacji

pricing.quote() i bookings.create() przyjmują saleLines, aby sprzedać towary razem z wynajmem:

const quote = await requiply.pricing.quote({
  startDate: '2026-07-01T10:00:00',
  endDate: '2026-07-03T18:00:00',
  items: [{ groupId: cameraKitId, quantity: 1 }],
  saleLines: [{ saleItemId: memoryCardId, quantity: 2 }],
});

console.log(quote.saleSubtotal, quote.lineSaleItems[0]?.stockAfter);
  • Klucz tajny może sprzedawać poniżej zerowego stanu, tak jak pracownicy w aplikacji. Klucz publiczny nie może: zobacz Z kluczem publicznym.
  • Towary są sprzedawane po cenie katalogowej i nigdy nie są objęte rabatem ani korektą. Ich suma to saleSubtotal, już uwzględniona w total.
  • lineSaleItems pokazuje każdy towar z stockOnHand i stockAfter, więc możesz ostrzec, zanim stan spadnie poniżej zera.
  • W bookings.create() stan magazynowy spada po utworzeniu rezerwacji i wraca, jeśli rezerwacja zostanie anulowana. Suma za towary jest doliczana do totalCost rezerwacji i jej płatności.
  • bookings.get() zwraca towary jako saleItems, a ich sprzedaż jako saleId.

Aby zmienić towary w istniejącej rezerwacji, użyj w aplikacji opcji Sprzedaż towarów w rezerwacji.

Copyright © 2026