# POST Repayments

Полное, частичное и процентное погашение в Sandbox.

## POST /api/sandbox/loans/{id}/repayment-flow

> Продвигает один шаг cabinet-compatible flow погашения. Используйте его для имитации полного, частичного или процентного repayment path с тестовым платежным кошельком, KYT и возвратом залога.\
> \
> Порядок действий строгий:\
> \
> 1\. \`start\_payment\` — создать repayment operation и получить sandbox-кошельки.\
> 2\. \`confirm\_usdt\` — подтвердить тестовое зачисление платежа через \`tx\_hash\` и \`confirmations\`.\
> 3\. \`run\_kyt\` — симулировать KYT-проверку платежа.\
> 4\. \`complete\_settlement\` — списать проценты или основной долг.\
> 5\. \`complete\_collateral\_return\` — вернуть залог после полного погашения.\
> \
> Нельзя выполнить шаг раньше времени: API вернет \`409 FLOW\_CONFLICT\`. Для восстановления состояния вызовите \`GET /api/sandbox/state\`.\
> \
> Кошельки в ответе находятся в \`sandboxFlow\.repaymentOperations\[].wallets\`: \`repayment\` для платежа и \`collateralReturn\` для возврата залога после полного погашения. В Sandbox внешний chain polling не требуется: подтверждение имитируется POST-действием \`confirm\_usdt\`.\
> \
> Для POST обязательно передавайте \`Idempotency-Key\`, чтобы retry не создал вторую repayment operation или второй переход состояния.\
> \
> Пример:\
> \`\`\`bash\
> curl <https://partner.fundora.capital/api/sandbox/loans/LOAN\\_ID/repayment-flow> \\\
> &#x20; -H "Authorization: Bearer sk\_sandbox\_YOUR\_KEY" \\\
> &#x20; -H "Content-Type: application/json" \\\
> &#x20; -H "Idempotency-Key: b6dc3b48-8a3b-4c19-9c7c-365809712665" \\\
> &#x20; -d '{"action":"start\_payment","repayment\_kind":"full\_principal","full\_repayment":true}'\
> \`\`\`

````json
{"openapi":"3.0.3","info":{"title":"Fundora API","version":"0.3.0"},"tags":[{"name":"post-repayments","description":"Полное, частичное и процентное погашение в Sandbox."}],"servers":[{"url":"https://partner.fundora.capital","description":"Production-домен партнерского API"}],"security":[{"SandboxBearer":[]}],"components":{"securitySchemes":{"SandboxBearer":{"type":"http","scheme":"bearer","bearerFormat":"sk_sandbox"}},"parameters":{"LoanId":{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор Sandbox-займа из activeLoans[].id или loanHistory[].id."},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Обязательный уникальный ключ POST-операции, обычно UUID. Повтор того же POST с тем же endpoint-ом и телом вернет сохраненный результат с idempotency_replayed=true. Тот же ключ с другим телом или endpoint-ом вернет IDEMPOTENCY_KEY_CONFLICT. Отсутствующий ключ вернет IDEMPOTENCY_KEY_REQUIRED.","schema":{"type":"string","maxLength":255}}},"schemas":{"SandboxRepaymentFlowRequest":{"type":"object","properties":{"action":{"type":"string","enum":["start_payment","confirm_usdt","run_kyt","complete_settlement","complete_collateral_return"],"description":"Действие repayment flow. Порядок: start_payment -> confirm_usdt -> run_kyt -> complete_settlement -> complete_collateral_return."},"operation_id":{"type":"string","nullable":true,"description":"ID repayment operation из sandboxFlow.repaymentOperations[].id. Нужен на шагах после start_payment."},"repayment_kind":{"type":"string","enum":["interest","partial_principal","full_principal"],"description":"Тип погашения для start_payment: interest, partial_principal или full_principal."},"amount":{"type":"number","nullable":true,"description":"Сумма частичного погашения или процентного платежа. Для full_principal можно не передавать при full_repayment=true."},"full_repayment":{"type":"boolean","description":"true для полного погашения основного долга и последующего возврата залога."},"tx_hash":{"type":"string","nullable":true,"description":"Тестовый hash транзакции. Передавайте на confirm_usdt для имитации платежа."},"confirmations":{"type":"number","description":"Количество тестовых подтверждений. Для confirm_usdt обычно достаточно 1."},"kyt_report":{"type":"object","nullable":true,"additionalProperties":true,"description":"Произвольный KYT payload для run_kyt. В Sandbox сохраняется как тестовый отчет."}},"description":"Тело запроса для одного шага repayment flow. action можно не передавать: по умолчанию используется start_payment."},"SandboxLoansStateResponse":{"type":"object","properties":{"request_id":{"type":"string","description":"Идентификатор запроса для поддержки и поиска в Logs."},"idempotency_replayed":{"type":"boolean","description":"true, если POST-ответ возвращен из кеша Idempotency-Key. Для GET отсутствует."},"success":{"type":"boolean","description":"Признак успешного ответа."},"activatedScenarios":{"type":"object","description":"Какие sandbox-сценарии активированы для текущего пользователя/API-ключа.","properties":{"miner":{"type":"boolean","description":"Активирован borrower/miner сценарий."},"investor":{"type":"boolean","description":"Активирован investor сценарий."}}},"wallet":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/SandboxWalletState"}],"description":"Тестовый кошелек симулятора."},"activeLoans":{"type":"array","description":"Активные Sandbox-займы.","items":{"$ref":"#/components/schemas/SandboxLoanRecord"}},"loanHistory":{"type":"array","description":"Закрытые или исторические Sandbox-займы.","items":{"$ref":"#/components/schemas/SandboxLoanRecord"}},"loanHistoryEvents":{"type":"array","description":"События истории по займам для UI/таймлайна.","items":{"$ref":"#/components/schemas/SandboxLoanHistoryEvent"}},"loanDraft":{"$ref":"#/components/schemas/SandboxLoanDraft"},"sandboxFlow":{"$ref":"#/components/schemas/SandboxLoanFlowState"}},"required":["request_id","success"]},"SandboxWalletState":{"type":"object","properties":{"id":{"type":"string","description":"ID sandbox-кошелька симулятора."},"virtualBtcBalance":{"type":"string","description":"Доступный тестовый BTC-баланс."},"virtualUsdBalance":{"type":"string","description":"Доступный тестовый USD/USDT-баланс."},"virtualRubBalance":{"type":"string","description":"Доступный тестовый RUB-баланс."},"lockedBtcBalance":{"type":"string","description":"BTC, заблокированный в залоге."},"investedRubBalance":{"type":"string","description":"RUB, задействованный в инвестиционном сценарии."}}},"SandboxLoanRecord":{"type":"object","properties":{"id":{"type":"string","description":"ID Sandbox-займа."},"status":{"type":"string","description":"Статус займа."},"collateral_btc":{"type":"number","description":"Общий BTC-залог."},"collateral_received":{"type":"number","description":"Фактически подтвержденный BTC-залог."},"collateral_address":{"type":"string","nullable":true,"description":"Адрес залога в симуляторе."},"external_client_id":{"type":"string","nullable":true,"description":"ID клиента в системе партнера."},"client_reference":{"type":"string","nullable":true,"description":"Человекочитаемая ссылка на клиента или сделку."},"loan_amount":{"type":"number","description":"Исходная сумма займа."},"loan_currency":{"type":"string","enum":["RUB","USDT"],"description":"Валюта займа."},"debt_amount":{"type":"number","description":"Исходный основной долг."},"annual_rate":{"type":"number","description":"Годовая ставка займа в процентах."},"btc_rate":{"type":"number","description":"BTC rate, зафиксированный на момент создания."},"usd_rub_rate":{"type":"number","description":"USD/RUB rate, зафиксированный на момент создания."},"current_collateral_usd":{"type":"number","description":"Текущая стоимость залога в USD."},"current_collateral_rub":{"type":"number","description":"Текущая стоимость залога в RUB."},"current_debt":{"type":"number","description":"Текущий долг с учетом операций."},"health_factor":{"type":"number","description":"Индикатор здоровья займа: чем выше, тем безопаснее."},"accrued_interest":{"type":"number","description":"Начисленные проценты."},"max_ltv":{"type":"number","description":"Максимальный LTV для займа."},"liquidation_threshold":{"type":"number","description":"Порог ликвидации для займа."},"created_at":{"type":"string","format":"date-time","description":"Время создания займа."},"funded_at":{"type":"string","format":"date-time","description":"Время выдачи займа."},"interest_due_at":{"type":"string","nullable":true,"format":"date-time","description":"Дата ближайшего процентного платежа."},"principal_due_at":{"type":"string","nullable":true,"format":"date-time","description":"Дата платежа основного долга."}}},"SandboxLoanHistoryEvent":{"type":"object","properties":{"id":{"type":"string","description":"ID события истории."},"type":{"type":"string","enum":["opened","collateral","loan","interest_paid","closed"],"description":"Тип события."},"title":{"type":"string","description":"Название события для UI."},"amountLabel":{"type":"string","description":"Основная сумма для отображения."},"amountSubLabel":{"type":"string","nullable":true,"description":"Дополнительная сумма для отображения."},"rateLabel":{"type":"string","nullable":true,"description":"Ставка или курс для отображения."},"createdAt":{"type":"string","format":"date-time","description":"Время события."},"loanId":{"type":"string","description":"ID связанного займа."},"canRemoveCollateral":{"type":"boolean","description":"Можно ли снять часть залога после этого события."}}},"SandboxLoanDraft":{"type":"object","nullable":true,"properties":{"id":{"type":"string","description":"ID draft-заявки."},"status":{"type":"string","enum":["active","completed","discarded"],"description":"Статус draft-заявки."},"currentStep":{"type":"string","enum":["contract","kyt","collateral","cfa"],"description":"Текущий шаг draft в legacy simulator flow."},"loanId":{"type":"string","nullable":true,"description":"ID созданного займа, если draft уже завершен."},"loanParams":{"type":"object","properties":{"collateral_btc":{"type":"number","description":"BTC-залог draft-заявки."},"loan_amount":{"type":"number","description":"Сумма займа draft-заявки."},"loan_currency":{"type":"string","enum":["RUB","USDT"],"description":"Валюта займа draft-заявки."}}},"contractAddress":{"type":"string","nullable":true,"description":"Тестовый contract/collateral address."},"kytReport":{"type":"object","nullable":true,"additionalProperties":true,"description":"KYT payload, переданный в run_kyt."},"collateralPosted":{"type":"boolean","description":"Подтвержден ли залог."},"cfaIssued":{"type":"boolean","description":"Завершена ли выдача займа."},"collateralPostedAt":{"type":"string","nullable":true,"format":"date-time"},"cfaIssuedAt":{"type":"string","nullable":true,"format":"date-time"},"completedAt":{"type":"string","nullable":true,"format":"date-time"},"discardedAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SandboxLoanFlowState":{"type":"object","properties":{"loanApplications":{"type":"array","description":"Все активные и завершенные loan application flows.","items":{"$ref":"#/components/schemas/SandboxLoanApplicationFlow"}},"repaymentOperations":{"type":"array","description":"Все repayment flows по займам.","items":{"$ref":"#/components/schemas/SandboxRepaymentOperationFlow"}}}},"SandboxLoanApplicationFlow":{"type":"object","description":"Текущий loan application flow для выдачи займа.","properties":{"id":{"type":"string","description":"Идентификатор draft/application flow."},"loanId":{"type":"string","nullable":true,"description":"Идентификатор созданного займа. До complete_payout может быть null."},"externalClientId":{"type":"string","nullable":true,"description":"ID клиента в системе партнера."},"clientReference":{"type":"string","nullable":true,"description":"Человекочитаемая ссылка на клиента/сделку."},"status":{"type":"string","enum":["pending","completed"],"description":"Статус loan application flow."},"currentStepId":{"type":"string","nullable":true,"enum":["calculator","collateral_transfer","btc_confirmation","kyt","payout"],"description":"Следующий или текущий шаг, который нужно завершить."},"collateralRequiredConfirmations":{"type":"integer","description":"Сколько подтверждений нужно передать в confirm_btc."},"payoutRequiredConfirmations":{"type":"integer","description":"Сколько подтверждений ожидается для тестовой выдачи."},"wallets":{"type":"object","description":"Тестовые кошельки loan flow.","properties":{"collateralDeposit":{"$ref":"#/components/schemas/SandboxTestWallet"},"loanPayout":{"$ref":"#/components/schemas/SandboxTestWallet"},"collateralReturn":{"$ref":"#/components/schemas/SandboxTestWallet"}}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/SandboxFlowStep"}}}},"SandboxTestWallet":{"type":"object","description":"Тестовый deterministic wallet/address для Sandbox flow. Не является реальным custody-кошельком.","properties":{"purpose":{"type":"string","enum":["collateral_deposit","loan_payout","repayment","collateral_return"],"description":"Назначение тестового кошелька в flow."},"asset":{"type":"string","enum":["BTC","USDT"],"description":"Актив кошелька."},"network":{"type":"string","enum":["sandbox"],"description":"Всегда sandbox: адрес не предназначен для реального blockchain-перевода."},"chainCode":{"type":"string","enum":["SANDBOX_BTC","SANDBOX_USDT"],"description":"Код тестовой сети."},"address":{"type":"string","description":"Тестовый адрес, который партнер показывает клиенту или использует в симуляции."},"isRealWallet":{"type":"boolean","enum":[false],"description":"Всегда false: в Sandbox не создается реальный custody wallet."},"confirmationMode":{"type":"string","enum":["api_simulated"],"description":"Подтверждение выполняется через API action, а не через внешний blockchain polling."},"requiredConfirmations":{"type":"integer","description":"Сколько подтверждений нужно передать в confirm action."}},"required":["purpose","asset","network","chainCode","address","isRealWallet","confirmationMode","requiredConfirmations"]},"SandboxFlowStep":{"type":"object","properties":{"id":{"type":"string","description":"Машинный идентификатор шага flow."},"title":{"type":"string","description":"Название шага для отображения."},"status":{"type":"string","enum":["pending","processing","completed"],"description":"Текущий статус шага."}}},"SandboxRepaymentOperationFlow":{"type":"object","description":"Repayment operation flow для процентов, частичного или полного погашения.","properties":{"id":{"type":"string","description":"Идентификатор repayment operation. Передавайте его как operation_id на следующих шагах."},"loanId":{"type":"string","nullable":true,"description":"ID займа, к которому относится repayment operation."},"kind":{"type":"string","enum":["interest","partial_principal","full_principal"],"description":"Тип погашения."},"status":{"type":"string","enum":["pending","completed"],"description":"Статус repayment flow."},"currentStepId":{"type":"string","nullable":true,"enum":["payment","usdt_confirmation","kyt","interest_settlement","debt_update","collateral_return"],"description":"Следующий или текущий шаг repayment flow."},"requiredConfirmations":{"type":"integer","description":"Сколько подтверждений нужно передать в confirm_usdt."},"wallets":{"type":"object","description":"Тестовые кошельки repayment flow.","properties":{"repayment":{"$ref":"#/components/schemas/SandboxTestWallet"},"collateralReturn":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/SandboxTestWallet"}],"description":"Кошелек возврата залога. Заполняется для полного погашения."}}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/SandboxFlowStep"}},"createdAt":{"type":"string","format":"date-time","description":"Время создания repayment operation."}}},"ErrorResponse":{"type":"object","properties":{"request_id":{"type":"string","description":"Идентификатор запроса для поддержки и поиска в Logs."},"error_code":{"type":"string","description":"Формализованный код ошибки для интеграционной логики.","enum":["SANDBOX_API_KEY_REQUIRED","SANDBOX_API_KEY_INVALID","SANDBOX_API_KEY_DATABASE_REQUIRED","SANDBOX_SESSION_REQUIRED","SANDBOX_RATE_LIMIT_EXCEEDED","INVALID_REQUEST","INVALID_ACTION","INVALID_SCOPE","LOAN_NOT_FOUND","WALLET_NOT_FOUND","FLOW_CONFLICT","LIMIT_EXCEEDED","INSUFFICIENT_BALANCE","IDEMPOTENCY_KEY_REQUIRED","IDEMPOTENCY_KEY_CONFLICT","IDEMPOTENCY_KEY_IN_PROGRESS","DATABASE_UNAVAILABLE","INTERNAL_ERROR"]},"error":{"type":"string","description":"Человекочитаемое описание ошибки. Не используйте его для интеграционной логики, для этого есть error_code."}},"required":["request_id","error_code","error"]}},"responses":{"BadRequest":{"description":"Некорректный запрос: неверное тело, отсутствует Idempotency-Key для POST, неизвестное действие или невалидная сумма","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Sandbox API-ключ отсутствует или недействителен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Займ не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Conflict":{"description":"Flow нельзя продолжить из текущего состояния, не хватает баланса/лимита или конфликтует Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Превышен Sandbox API rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/api/sandbox/loans/{id}/repayment-flow":{"post":{"operationId":"runSandboxRepaymentFlow","tags":["post-repayments"],"summary":"POST /api/sandbox/loans/{id}/repayment-flow","description":"Продвигает один шаг cabinet-compatible flow погашения. Используйте его для имитации полного, частичного или процентного repayment path с тестовым платежным кошельком, KYT и возвратом залога.\n\nПорядок действий строгий:\n\n1. `start_payment` — создать repayment operation и получить sandbox-кошельки.\n2. `confirm_usdt` — подтвердить тестовое зачисление платежа через `tx_hash` и `confirmations`.\n3. `run_kyt` — симулировать KYT-проверку платежа.\n4. `complete_settlement` — списать проценты или основной долг.\n5. `complete_collateral_return` — вернуть залог после полного погашения.\n\nНельзя выполнить шаг раньше времени: API вернет `409 FLOW_CONFLICT`. Для восстановления состояния вызовите `GET /api/sandbox/state`.\n\nКошельки в ответе находятся в `sandboxFlow.repaymentOperations[].wallets`: `repayment` для платежа и `collateralReturn` для возврата залога после полного погашения. В Sandbox внешний chain polling не требуется: подтверждение имитируется POST-действием `confirm_usdt`.\n\nДля POST обязательно передавайте `Idempotency-Key`, чтобы retry не создал вторую repayment operation или второй переход состояния.\n\nПример:\n```bash\ncurl https://partner.fundora.capital/api/sandbox/loans/LOAN_ID/repayment-flow \\\n  -H \"Authorization: Bearer sk_sandbox_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Idempotency-Key: b6dc3b48-8a3b-4c19-9c7c-365809712665\" \\\n  -d '{\"action\":\"start_payment\",\"repayment_kind\":\"full_principal\",\"full_repayment\":true}'\n```","parameters":[{"$ref":"#/components/parameters/LoanId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxRepaymentFlowRequest"}}}},"responses":{"200":{"description":"Обновленное состояние Sandbox-займа","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxLoansStateResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}}}
````


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fundora.capital/api-sandbox/post-repayments.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
