Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ssortia committed Nov 1, 2024
1 parent 67858e2 commit bffc597
Show file tree
Hide file tree
Showing 18 changed files with 918 additions and 1 deletion.
92 changes: 91 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
# kkmhub-client
# SDK для kkmhub

## Использование

```js
/**
kkmhubUrl - путь к kkmhub
certConfig - сертификат
*/
const kkmService = new KkmService({ kkmhubUrl, certConfig });

/**
Необходимо отнаследовать класс от Receipt и переопределить в нем методы getOperationId, getName,
getContractFields, getCashierFields, getPositions, getType, getSumType, getPayTimeString.
См. пример ExampleReceipt (src/example/ExampleReceipt.mjs).
Возвращаемые значения этих функций описаны в класе Receipt (src/Receipt.mjs).
*/
const receipt = new ExampleReceipt("project-name", offer);

/**
* Создание чека
*/
const checkId = await kkmService.createReceipt(receipt);

/**
* Получение pdf чека
*/
const buffer = await kkmService.getReceiptDocument(checkId);
```

## Константы

### ReceiptSumType - тип расчета

| Свойство | Значение | Описание |
|-----------|------------|--------------------|
| HARD_CASH | "hardcash" | Наличные |
| CARD | "card" | Карта |
| CASHLESS | "cashless" | Безналичный расчет |
| PREPAID | "prepaid" | Предоплата |
| CREDIT | "credit" | Кредит |

### ReceiptType - тип чека

| Свойство | Значение | Описание |
|-------------|--------------|-----------------|
| SALE | "sale" | Приход |
| BUY | "buy" | Расход |
| RETURN_SALE | "returnSale" | Возврат прихода |
| RETURN_BUY | "returnBuy" | Возврат расхода |

### PositionItemSign - тип позиции

| Свойство | Значение | Описание |
|----------------|-----------------|--------------------------|
| SERVICE | "service" | Услуга |
| PRODUCT | "product" | Товар |
| EXCISE_PRODUCT | "exciseProduct" | Акцизный товар |
| WORK | "work" | Работа |
| GAME_BET | "gameBet" | Ставка на игру |
| GAME_WIN | "gameWin" | Выигрыш ставки |
| LOTTERY_BET | "lotteryBet" | Лотерейная ставка |
| LOTTERY_WIN | "lotteryWin" | Выигрыш в лотерею |
| RID | "rid" | |
| PAY | "pay" | |
| AGENT_FEE | "agentFee" | Агентское вознаграждение |
| COMPOSITE | "composite" | |
| OTHER | "other" | Иное |

### PositionNdsType - тип НДС позиции

| Свойство | Значение | Описание |
|----------|----------|----------|
| NDS20 | "nds20" | НДС 20% |
| NDS18 | "nds18" | НДС 18% |
| NDS10 | "nds10" | НДС 10% |
| NDS0 | "nds0" | НДС 0% |
| NONDS | "nonds" | Без НДС |

### PositionTypeSign - тип оплаты позиции

| Свойство | Значение | Описание |
|------------|-------------|-------------------|
| FULL_PAY | "fullPay" | Полный расчет |
| ADVANCE | "advance" | Аванс |
| PREPAY100 | "prePay100" | Полная предоплата |
| PREPAY | "prePay" | Предоплата |
| PART_PAY | "partPay" | Частичная оплата |
| CREDIT | "credit" | Кредит |
| PAY_CREDIT | "payCredit" | |
77 changes: 77 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "kkmhub-client",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ilb/kkmhub-client.git"
},
"author": "ssortia",
"license": "ISC",
"bugs": {
"url": "https://github.com/ilb/kkmhub-client/issues"
},
"homepage": "https://github.com/ilb/kkmhub-client#readme",
"dependencies": {
"currency.js": "^2.0.4",
"isomorphic-fetch": "^3.0.0"
}
}
70 changes: 70 additions & 0 deletions src/KkmGate.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import fetch from "isomorphic-fetch";
import https from "https";
import CreateReceiptError from "./exceptions/CreateReceiptError.mjs";

export default class KkmGate {
constructor({ kkmhubUrl, certConfig }) {
this.kkmhubUrl = kkmhubUrl;
this.certConfig = certConfig;
this.count = 3;
this.step = 0;
}

/**
* Скачивает чек в формате pdf из kkmhub
*
* @param {number} checkId checkId from KKM service
* @returns {Buffer}
*/
async getOrder(checkId) {
const url = this.kkmhubUrl + `/api/v1/checkPDF/${checkId}`;
const options = {
agent: () => new https.Agent(this.certConfig),
headers: {
Accept: "application/pdf",
},
};
const response = await fetch(url, options);

if (response.status !== 200) {
throw new CreateReceiptError("Ошибка загрузки чека, повторите запрос позднее");
}

return response.buffer();
}

/**
* Создает чек в kkmhub
*
* @param {Object} data data from orderAdapter
* @returns
*/
async generateReceipt(data) {
if (data) {
const url = this.kkmhubUrl + "/api/v1/order";
const options = {
method: "POST",
body: JSON.stringify(data),
agent: () => new https.Agent(this.certConfig),
headers: {
Accept: "application/json",
"Content-type": "application/json",
},
};
const response = await fetch(url, options);

if (this.step > this.count) {
const err = await response.text();
throw new CreateReceiptError(`Ошибка отправки чека, повторите запрос позднее ${err}`);
}

if (!response.ok) {
await new Promise((resolve) => setTimeout(resolve, 2000));
this.step++;
return this.generateReceipt(data);
}

return response.json();
}
}
}
34 changes: 34 additions & 0 deletions src/KkmService.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import KkmGate from "./KkmGate.mjs";

export default class KkmService {
/**
* @param {string} kkmhubUrl - Путь к kkmhub
* @param {*} certConfig - сертификат
*/
constructor({ kkmhubUrl, certConfig }) {
this.kkmGate = new KkmGate({ kkmhubUrl, certConfig });
}

/**
* Создает чек в kkmhub и возвращает его идентификатор.
*
* @param {object} receipt - экземпляр класса отнаследованного от Receipt
* @returns {Promise<number>}
*/
async createReceipt(receipt) {
const receiptData = receipt.format();
const order = await this.kkmGate.generateReceipt(receiptData);

return order.checkId;
}

/**
* Возвращает чек в pdf формате (Buffer) по переданному идентификатору.
*
* @param {number} checkId - идентификатор чека
* @returns {Promise<Buffer>}
*/
async getReceiptDocument(checkId) {
return this.kkmGate.getOrder(checkId);
}
}
Loading

0 comments on commit bffc597

Please sign in to comment.