syntax = "proto3";

package exchange_core;

import "google/protobuf/struct.proto";

option csharp_namespace = "ExchangeCore";
option java_multiple_files = true;
option java_package = "com.arbiwallet.exchange.core";

service ExchangeCoreService {
  rpc CreateExchangeOrder(CreateExchangeOrderRequest) returns (CreateExchangeOrderResponse);
  rpc GetWithdrawTypes(GetWithdrawTypesRequest) returns (GetWithdrawTypesResponse);
  rpc GetReceiveBanks(GetReceiveBanksRequest) returns (GetReceiveBanksResponse);

  rpc CreateExchangeDeal(CreateExchangeDealRequest) returns (CreateExchangeDealResponse);
  rpc GetExchangeDeals(GetExchangeDealsRequest) returns (GetExchangeDealsResponse);
  rpc GetExchangeDealDetails(GetExchangeDealDetailsRequest) returns (GetExchangeDealDetailsResponse);
  rpc GetExchangeDealsDetails(GetExchangeDealsDetailsRequest) returns (GetExchangeDealsDetailsResponse);
  rpc BatchGetReferralRecreateDeals(BatchGetReferralRecreateDealsRequest) returns (BatchGetReferralRecreateDealsResponse);
  rpc UpdateExchangeDeal(UpdateExchangeDealRequest) returns (UpdateExchangeDealResponse);
  rpc CompleteExchangeDeal(CompleteExchangeDealRequest) returns (CompleteExchangeDealResponse);
  rpc CancelExchangeDeal(CancelExchangeDealRequest) returns (CancelExchangeDealResponse);
  rpc DeleteExchangeDeal(DeleteExchangeDealRequest) returns (DeleteExchangeDealResponse);
  rpc GetUserIdsWithDealsInPeriod(GetUserIdsWithDealsInPeriodRequest) returns (GetUserIdsWithDealsInPeriodResponse);
  rpc BatchGetUserDealStats(BatchGetUserDealStatsRequest) returns (BatchGetUserDealStatsResponse);
  rpc BatchGetManagerPersonDealStats(BatchGetManagerPersonDealStatsRequest) returns (BatchGetManagerPersonDealStatsResponse);
  rpc GetUserMetrics(GetUserMetricsRequest) returns (GetUserMetricsResponse);
  rpc GetFinModelExchangeAggregates(GetFinModelExchangeAggregatesRequest) returns (GetFinModelExchangeAggregatesResponse);

  rpc CreateExchangePayment(CreateExchangePaymentRequest) returns (CreateExchangePaymentResponse);
  rpc HandlePaymentWebhook(HandlePaymentWebhookRequest) returns (HandlePaymentWebhookResponse);
  rpc GetExchangePayments(GetExchangePaymentsRequest) returns (GetExchangePaymentsResponse);

  rpc ListExchangePayouts(ListExchangePayoutsRequest) returns (ListExchangePayoutsResponse);
  rpc GetExchangePayout(GetExchangePayoutRequest) returns (GetExchangePayoutResponse);
  rpc CreateExchangePayout(CreateExchangePayoutRequest) returns (CreateExchangePayoutResponse);
  rpc HandleExchangePayoutWebhook(HandleExchangePayoutWebhookRequest) returns (HandleExchangePayoutWebhookResponse);
  rpc GetExchangePayment(GetExchangePaymentRequest) returns (GetExchangePaymentResponse);
  rpc SetPaymentRealPrimeRateFixed(SetPaymentRealPrimeRateFixedRequest) returns (SetPaymentRealPrimeRateFixedResponse);
  rpc GetPaymentsSummary(ExchangeCalculationsFiltersRequest) returns (GetPaymentsSummaryResponse);
  rpc SearchExchangePayment(SearchExchangePaymentRequest) returns (SearchExchangePaymentResponse);
  rpc PrealoadExchangePaymentForSearch(PrealoadExchangePaymentForSearchRequest) returns (PrealoadExchangePaymentForSearchResponse);
  // CRM crypto refund via ARBIPAY platform API (CRYPTO_GATEWAY / agent 5).
  rpc RefundExchangePayment(RefundExchangePaymentRequest) returns (RefundExchangePaymentResponse);
  rpc EstimateExchangePaymentRefundFee(EstimateExchangePaymentRefundFeeRequest) returns (EstimateExchangePaymentRefundFeeResponse);
  rpc ConfirmExchangePayment(ConfirmExchangePaymentRequest) returns (ConfirmExchangePaymentResponse);
  // Gatepay underpayment refund intent lifecycle (Exchange-side payout).
  rpc PrepareGatepayPaymentRefund(PrepareGatepayPaymentRefundRequest) returns (PrepareGatepayPaymentRefundResponse);
  rpc AttachGatepayPaymentRefund(AttachGatepayPaymentRefundRequest) returns (AttachGatepayPaymentRefundResponse);
  rpc FinalizeGatepayPaymentRefund(FinalizeGatepayPaymentRefundRequest) returns (FinalizeGatepayPaymentRefundResponse);
  rpc ListPendingGatepayPaymentRefunds(ListPendingGatepayPaymentRefundsRequest) returns (ListPendingGatepayPaymentRefundsResponse);
  rpc MarkGatepayPaymentRefundFailed(MarkGatepayPaymentRefundFailedRequest) returns (MarkGatepayPaymentRefundFailedResponse);

  rpc GetExchangeMethods(GetExchangeMethodsRequest) returns (GetExchangeMethodsResponse);
  rpc GetExchangeStatuses(GetExchangeStatusesRequest) returns (GetExchangeStatusesResponse);

  rpc GetWallets(GetWalletsRequest) returns (GetWalletsResponse);
  rpc GetWalletsMonika(GetWalletsMonikaRequest) returns (GetWalletsMonikaResponse);

  rpc ListPaymentAgentDailyRates(ListPaymentAgentDailyRatesRequest) returns (ListPaymentAgentDailyRatesResponse);
  rpc CreatePaymentAgentDailyRate(CreatePaymentAgentDailyRateRequest) returns (CreatePaymentAgentDailyRateResponse);
  rpc PreviewPaymentAgentDailyRate(PreviewPaymentAgentDailyRateRequest) returns (PreviewPaymentAgentDailyRateResponse);
  rpc ApplyPaymentAgentDailyRate(ApplyPaymentAgentDailyRateRequest) returns (ApplyPaymentAgentDailyRateResponse);
  rpc DeletePaymentAgentDailyRate(DeletePaymentAgentDailyRateRequest) returns (DeletePaymentAgentDailyRateResponse);
}

message AuthManagerContext {
  string manager_id = 1;
  repeated string office_ids = 2;
  bool can_cross_office = 3;
  optional string request_id = 4;
  optional string client_type = 5;
  repeated string permissions = 6;
  bool is_super_admin = 7;
}

message CreateExchangeOrderRequest {
  AuthManagerContext auth_manager_context = 1;
  double input_amount = 2;
  double output_amount = 3;
  string input_currency_id = 4;
  string output_currency_id = 5;
  string withdraw_type_id = 6;
  string customer_id = 7;
  optional string receive_bank_id = 8;
}

message CreateExchangeOrderResponse {
  bool success = 1;
  optional string order_id = 2;
  optional string message = 3;
  optional string warning = 4;
  optional string error = 5;
  optional google.protobuf.Struct validationErrors = 6;
}

message WithdrawTypeItem {
  int64 id = 1;
  string name = 2;
  int32 sort = 3;
  bool is_active = 4;
}

message GetWithdrawTypesRequest {
  AuthManagerContext auth_manager_context = 1;
  optional bool is_active = 2;
}

message GetWithdrawTypesResponse {
  repeated WithdrawTypeItem withdraw_types = 1;
}

message ReceiveBankItem {
  int64 id = 1;
  string name = 2;
  optional string code = 3;
  bool is_active = 4;
}

message GetReceiveBanksRequest {
  AuthManagerContext auth_manager_context = 1;
  optional bool is_active = 2;
  optional string search = 3;
}

message GetReceiveBanksResponse {
  repeated ReceiveBankItem receive_banks = 1;
}

message CreateExchangeDealRequest {
  AuthManagerContext auth_manager_context = 1;

  optional string calculation_id = 3;
  optional string payment_id = 4;

  string method_id = 5;
  string input_wallet_id = 6;
  string output_wallet_id = 7;

  optional double input_amount = 8;
  optional double output_amount = 9;
  optional double fact_output_amount = 10;

  optional string input_currency_id = 11;
  optional string output_currency_id = 12;

  optional string user_id = 13;
  optional string manager_person_id = 14;

  optional double expenses_for_courier = 15;
  optional bool include_in_total_calculation = 16;
  optional bool one_currency_exchange = 17;
  optional double received_from_dealer = 18;
  optional string received_from_dealer_wallet_id = 19;

  optional string customer_doc_name = 20;
  optional string customer_doc_nationality = 21;
  optional string customer_doc_number = 22;

  optional string customer_source = 23;
  optional string customer_referrer = 24;

  repeated double receipts = 25;
  optional string office_id = 26;
}

message CreateExchangeDealResult {
  string exchange_id = 1;
  string user_id = 2;
  double input_amount = 3;
  string input_currency_id = 4;
  double output_amount = 5;
  string output_currency_id = 6;
  string status = 7;
}

message CreateExchangeDealResponse {
  bool ok = 1;
  optional CreateExchangeDealResult result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message GetExchangeDealsRequest {
  AuthManagerContext auth_manager_context = 1;
  ExchangeDealsFiltersRequest filter = 2;
  optional int32 page = 3;
  optional int32 page_size = 4;
}

message GetExchangeDealsManager {
  string id = 1;
  string email = 2;
}

message GetExchangeDealsReceipt {
  string id = 1;
  optional double amount = 2;
  optional string created_at = 3;
}

message GetExchangeDealsItem {
  string id = 1;
  string daily_id = 2;
  string user_id = 3;
  string user_text = 4;
  string created_at = 5;
  double input_amount = 6;
  string input_currency_id = 7;
  string input_wallet_id = 8;
  string method_id = 9;
  double output_amount = 10;
  double fact_output_amount = 11;
  string output_currency_id = 12;
  string output_wallet_id = 13;
  string exchange_status_id = 14;
  string exchange_status_name = 15;
  bool status = 16;
  bool payed = 17;
  optional string referrer_id = 18;
  optional string referrer_text = 19;
  optional string office_id = 20;
  repeated GetExchangeDealsReceipt receipts = 21;
  optional GetExchangeDealsManager manager = 22;
  optional string payment_id = 23;
  string payer_name = 24;
  string payer_data = 25;
  optional string calculation_source_id = 26;
  optional double exchange_rate_1_iter = 27;
  optional double exchange_rate_2_iter = 28;
  optional double usdt_rate = 29;
  optional double output_amount_in_usdt = 30;
  bool include_in_total_calculation = 31;
  bool one_currency_exchange = 32;
  optional double profit_percent = 33;
  optional double profit = 34;
  optional string profit_currency_id = 35;
  optional double usdt_profit = 36;
  optional double expenses_for_courier = 37;
  optional double referrer_bonus_amount = 38;
  optional double referrer_percent = 39;
  optional string manager_person_id = 40;
  optional string manager_person_name = 41;
  optional double received_from_dealer = 42;
  optional string received_from_dealer_wallet_id = 43;
  optional int32 payment_agent = 44;
}

message GetExchangeDealsResponse {
  int32 count = 1;
  optional string next = 2;
  optional string previous = 3;
  repeated GetExchangeDealsItem results = 4;
}

message GetExchangeDealDetailsRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message GetExchangeDealDetailsResult {
  string id = 1;
  string user_id = 2;

  string customer_id = 3;
  string customer_full_name = 4;
  optional string customer_chat_link = 5;
  optional string customer_url = 6;

  optional string referrer_id = 7;
  optional string referrer_full_name = 8;
  optional string referrer_url = 9;
  optional double referrer_percent = 10;

  string created_at = 11;

  double input_amount = 12;
  string input_currency_id = 13;
  optional string input_currency_short_name = 14;
  string input_wallet_id = 15;
  optional string input_wallet_name = 16;
  string method_id = 17;
  optional string method_name = 18;

  double output_amount = 19;
  string output_currency_id = 20;
  optional string output_currency_short_name = 21;
  string output_wallet_id = 22;
  optional string output_wallet_name = 23;

  bool one_currency_exchange = 24;
  optional double received_from_dealer = 25;
  optional string received_from_dealer_wallet_id = 26;
  optional string received_from_dealer_wallet_name = 27;

  optional string exchange_status_id = 28;
  optional string exchange_status_name = 29;
  bool payed = 30;

  optional double buy_price = 31;
  optional double sell_price = 32;
  optional double profit_percent = 33;
  optional double profit = 34;

  optional string profit_currency_id = 35;
  optional string profit_currency_short_name = 36;
  optional double usdt_rate = 37;
  optional double usdt_profit = 38;
  bool profit_accounting = 39;
  optional string profit_date = 40;

  optional string expenses_currency_id = 41;
  optional string expenses_currency_short_name = 42;
  optional double expenses_for_courier = 43;
  optional double expenses_for_referrer = 44;
}

message GetExchangeDealDetailsResponse {
  bool ok = 1;
  optional GetExchangeDealDetailsResult result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message GetExchangeDealsDetailsRequest {
  AuthManagerContext auth_manager_context = 1;
  repeated string ids = 2;
}

message GetExchangeDealsDetailsItem {
  string id = 1;
  bool ok = 2;
  optional GetExchangeDealDetailsResult result = 3;
  optional string error = 4;
}

message GetExchangeDealsDetailsResponse {
  bool ok = 1;
  repeated GetExchangeDealsDetailsItem results = 2;
}

message BatchGetReferralRecreateDealsRequest {
  repeated int32 user_ids = 1;
  repeated string exchange_ids = 2;
}

message ReferralRecreateDealItem {
  string exchange_id = 1;
  int32 user_id = 2;
  string created_at = 3;
  string input_currency = 4;
  string input_amount = 5;
  string output_currency = 6;
  string output_amount = 7;
  string fact_output_amount = 8;
  string profit_amount = 9;
  string profit_currency = 10;
  string courier_expenses = 11;
  string usdt_rate = 12;
  bool status = 13;
}

message BatchGetReferralRecreateDealsResponse {
  repeated ReferralRecreateDealItem items = 1;
}

message UpdateExchangeDealRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;

  optional string user_id = 3;
  optional double input_amount = 4;
  optional string input_currency_id = 5;
  optional string input_wallet_id = 6;
  optional string method_id = 7;
  optional string output_currency_id = 8;
  optional double output_amount = 9;
  optional double fact_output_amount = 10;
  optional string output_wallet_id = 11;
  optional string exchange_status_id = 12;
  optional bool payed = 13;
  optional string manager_person_id = 14;
  optional double exchange_rate_1_iter = 15;
  optional double exchange_rate_2_iter = 16;
  optional double usdt_rate = 17;
  optional bool include_in_total_calculation = 18;

  repeated double receipts = 19;
  optional string customer_doc_name = 20;
  optional string customer_doc_nationality = 21;
  optional string customer_doc_number = 22;
  optional string priority_manager_id = 23;
  optional string priority_outcome_wallet_id = 24;
}

message UpdateExchangeDealResult {
  string id = 1;
  string user_id = 2;
  double input_amount = 3;
  string input_currency_id = 4;
  double output_amount = 5;
  string output_currency_id = 6;
  double fact_output_amount = 7;
  string exchange_status_id = 8;
  bool payed = 9;
  bool include_in_total_calculation = 10;
}

message UpdateExchangeDealResponse {
  bool ok = 1;
  optional UpdateExchangeDealResult result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message CompleteExchangeDealRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message CompleteExchangeDealResponse {
  bool success = 1;
  optional string message = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message CancelExchangeDealRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message CancelExchangeDealResponse {
  bool success = 1;
  optional string message = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message DeleteExchangeDealRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message DeleteExchangeDealResponse {
  bool success = 1;
  optional string message = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message GetUserIdsWithDealsInPeriodRequest {
  optional string date_from = 1;
  optional string date_to = 2;
}

message GetUserIdsWithDealsInPeriodResponse {
  repeated int32 user_ids = 1;
}

message BatchGetUserDealStatsRequest {
  repeated int32 user_ids = 1;
}

message UserDealStats {
  int32 user_id = 1;
  int32 exchange_count_last_month = 2;
  double total_profit = 3;
}

message BatchGetUserDealStatsResponse {
  repeated UserDealStats items = 1;
}

message BatchGetManagerPersonDealStatsRequest {
  repeated int32 manager_person_ids = 1;
  optional string start_date = 2;
  optional string end_date = 3;
}

message ManagerPersonDealStats {
  int32 manager_person_id = 1;
  int32 all_exchanges = 2;
  int32 completed_exchanges = 3;
  double avg_check = 4;
  double total_amount = 5;
  double avg_profit_percent = 6;
  double profit = 7;
}

message BatchGetManagerPersonDealStatsResponse {
  repeated ManagerPersonDealStats items = 1;
}

message GetUserMetricsRequest {
  int32 user_id = 1;
  optional string date_from = 2;
  optional string date_to = 3;
}

message UserDebtByCurrency {
  string currency = 1;
  double amount = 2;
}

message UserMetricsSnapshot {
  double total_profit = 1;
  int32 deals_count = 2;
  repeated UserDebtByCurrency client_debt = 3;
  double average_markup = 4;
  double average_check = 5;
}

message GetUserMetricsResponse {
  UserMetricsSnapshot period = 1;
  UserMetricsSnapshot today = 2;
}

message ExchangeCalculationsFiltersRequest {
  optional string date_from = 1;
  optional string date_to = 2;
  optional double amount_from = 3;
  optional double amount_to = 4;
  optional string input_currency = 5;
  optional string output_currency = 6;
  optional string status = 7; // no_payment | with_payment | with_exchange | completed
  optional string search = 8;
  optional AuthManagerContext auth_manager_context = 9;
}

message ExchangeDealsFiltersRequest {
  optional string customers = 1;
  optional string managers = 2;
  optional string input_currency = 3;
  optional string output_currency = 4;
  optional string status = 5;
  optional string start_date = 6;
  optional string end_date = 7;
  optional string source = 8;
  optional string referrer = 9;
  optional bool is_partner = 10;
  optional bool one_currency = 11;
  optional bool include_in_total_calculation = 12;
  optional double amount_min = 13;
  optional double amount_max = 14;
  optional string search = 15;
  optional string sort = 16;
  optional string office = 17;
  optional int32 payment_agent = 18;
}

message CreateExchangePaymentRequest {
  AuthManagerContext auth_manager_context = 1;

  optional string calculation_id = 2;
  int32 agent_id = 3;
  optional double amount = 4;
  optional string customer_id = 5;
  optional string crypto_network = 6;
  optional string customer_source = 7;
  optional string customer_referrer = 8;
}

message CreateExchangePaymentResult {
  string payment_id = 1;
  string payment_uuid = 2;
  double amount = 3;
  int32 status = 4;
  string agent = 5;
  optional string wallet_id = 6;
  optional string crypto_network = 7;
  optional string crypto_address = 8;
  optional string arbi_link = 9;
  optional string payment_link = 10;
}

message CreateExchangePaymentResponse {
  bool ok = 1;
  optional CreateExchangePaymentResult result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message HandlePaymentWebhookRequest {
  string json_payload = 1;
  string x_api_key = 2;
}

message HandlePaymentWebhookResponse {
  bool ok = 1;
  string status = 2;
}

message GetExchangePaymentsRequest {
  optional int32 page = 1;
  optional int32 limit = 2;
  optional AuthManagerContext auth_manager_context = 3;
  optional string payment_number = 4;
  optional string customer_id = 5;
  optional string start_date = 6;
  optional string end_date = 7;
  optional string currency = 8; // all | RUB | USDT
  optional double amount_from = 9;
  optional double amount_to = 10;
  optional string status = 11;
  optional int32 payment_agent = 12;
  optional string sort = 13; // date_asc | date_desc | amount_asc | amount_desc
}

message GetExchangePaymentsItem {
  string id = 1;
  string arbipay_id = 2;
  optional string qr_link = 3;
  string arbipay_link = 4;
  int32 payment_agent = 5;
  optional double amount = 6;
  optional double amount_usdt = 7;
  int32 status = 8;
  optional string crypto_address = 9;
  string created_at = 10;
  optional string customer_name = 11;
  optional string manager_name = 12;
  optional string calculation_id = 13;
  optional string crypto_network = 14;
  /** Tx hash / provider track id for crypto payments. */
  optional string track_id = 15;
  /** Network fee in USDT (crypto), when stored. */
  optional double network_fee = 16;
  /** Base amount without network fee (crypto), when stored. */
  optional double amount_base = 17;
  optional string uuid = 18;
  optional bool real_prime_rate_is_fixed = 19;
  /** Provider/agent raw status (UNDERPAID, MANUAL_REVIEW, ...). */
  optional string payment_agent_status = 20;
  /** True when CRYPTO_GATEWAY + refund-eligible agent status. */
  optional bool can_refund = 21;
  optional bool can_confirm = 22;
  optional string track_uuid = 23;
  /** Actual USDT amount received (underpayment). */
  optional double received_amount = 24;
  /** Actual provider code from ARBIPAY (crypto / gatepay). */
  optional string provider_code = 25;
  /** Gatepay refund intent status: PENDING | CREATED | PAID | FAILED. */
  optional string refund_status = 26;
}

message GetExchangePaymentsResponse {
  repeated GetExchangePaymentsItem payments = 1;
  int32 page = 2;
  int32 limit = 3;
  int32 total = 4;
  int32 total_pages = 5;
}

message GetExchangePaymentRequest {
  string id = 1;
}

message GetExchangePaymentResponse {
  optional GetExchangePaymentsItem payment = 1;
}

message SetPaymentRealPrimeRateFixedRequest {
  optional AuthManagerContext auth_manager_context = 1;
  string payment_id = 2;
  bool is_fixed = 3;
}

message SetPaymentRealPrimeRateFixedResponse {
  bool ok = 1;
  optional string error = 2;
  optional string payment_id = 3;
  optional bool real_prime_rate_is_fixed = 4;
}

message RefundExchangePaymentRequest {
  string payment_id = 1;
  string refund_address = 2;
  optional string commission = 3;
  optional AuthManagerContext auth_manager_context = 4;
}

message RefundExchangePaymentResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
}

message ConfirmExchangePaymentRequest {
  string payment_id = 1;
  optional AuthManagerContext auth_manager_context = 2;
}

message ConfirmExchangePaymentResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
}

message EstimateExchangePaymentRefundFeeRequest {
  string payment_id = 1;
  optional string refund_address = 2;
  optional AuthManagerContext auth_manager_context = 3;
}

message EstimateExchangePaymentRefundFeeResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
  optional string total_commission_usdt = 4;
  optional string disclaimer = 5;
}

message PrepareGatepayPaymentRefundRequest {
  string payment_id = 1;
  string refund_address = 2;
  optional string commission = 3;
  optional AuthManagerContext auth_manager_context = 4;
}

message PrepareGatepayPaymentRefundResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
  optional string refund_id = 4;
  optional double received_amount = 5;
  optional double commission = 6;
  optional double payout_amount = 7;
  optional string chain = 8;
  optional string refund_address = 9;
  optional string status = 10;
  optional string gatepay_merchant_trade_no = 11;
  optional string customer = 12;
}

message AttachGatepayPaymentRefundRequest {
  string payment_id = 1;
  string gatepay_merchant_trade_no = 2;
  optional string gatepay_batch_id = 3;
  optional AuthManagerContext auth_manager_context = 4;
}

message AttachGatepayPaymentRefundResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
  optional string refund_id = 4;
  optional string status = 5;
}

message FinalizeGatepayPaymentRefundRequest {
  string payment_id = 1;
  optional string gatepay_merchant_trade_no = 2;
  optional AuthManagerContext auth_manager_context = 3;
}

message FinalizeGatepayPaymentRefundResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
  optional string refund_id = 4;
  optional string status = 5;
}

message ListPendingGatepayPaymentRefundsRequest {
  optional int32 limit = 1;
  optional AuthManagerContext auth_manager_context = 2;
}

message GatepayPaymentRefundItem {
  string refund_id = 1;
  string payment_id = 2;
  string refund_address = 3;
  string chain = 4;
  double received_amount = 5;
  double commission = 6;
  double payout_amount = 7;
  string status = 8;
  optional string gatepay_merchant_trade_no = 9;
  optional string gatepay_batch_id = 10;
  optional string arbipay_id = 11;
}

message ListPendingGatepayPaymentRefundsResponse {
  repeated GatepayPaymentRefundItem items = 1;
}

message MarkGatepayPaymentRefundFailedRequest {
  string payment_id = 1;
  optional string error = 2;
  optional AuthManagerContext auth_manager_context = 3;
}

message MarkGatepayPaymentRefundFailedResponse {
  bool ok = 1;
  optional string error = 2;
  optional string error_code = 3;
  optional string refund_id = 4;
  optional string status = 5;
}

message SearchExchangePaymentRequest {
  string search = 1;
  int32 limit = 2;
  optional AuthManagerContext auth_manager_context = 3;
}

message SearchExchangePaymentItem {
  string id = 1;
  optional double amount = 2;
  optional double usdt_amount = 3;
}

message SearchExchangePaymentResponse {
  repeated SearchExchangePaymentItem items = 1;
}

message PrealoadExchangePaymentForSearchRequest {
  string payment_id = 1;
  optional AuthManagerContext auth_manager_context = 2;
}

message PrealoadExchangePaymentForSearchResponse {
  optional SearchExchangePaymentItem item = 1;
}

message PaymentsSummaryItem {
  string currency = 1;
  double total = 2;
  double paid = 3;
  double unpaid = 4;
  int32 percent = 5;
}

message GetPaymentsSummaryResponse {
  int32 with_payment_count = 1;
  repeated PaymentsSummaryItem items = 2;
}

enum FinModelDealBucket {
  FIN_MODEL_DEAL_BUCKET_UNSPECIFIED = 0;
  FIN_MODEL_DEAL_BUCKET_ONE_CURRENCY = 1;
  FIN_MODEL_DEAL_BUCKET_BIG = 2;
  FIN_MODEL_DEAL_BUCKET_MEDIUM = 3;
  FIN_MODEL_DEAL_BUCKET_SMALL = 4;
}

message GetFinModelExchangeAggregatesRequest {
  optional AuthManagerContext auth_manager_context = 1;
  string date_from = 2;
  string date_to = 3;
  optional string office_id = 4;
}

message FinModelExchangeAggregateItem {
  int32 user_id = 1;
  FinModelDealBucket bucket = 2;
  int32 deals_count = 3;
  double amount_usdt = 4;
  double profit_usdt = 5;
}

message FinModelDebtByCurrency {
  string output_currency_id = 1;
  double amount = 2;
}

message GetFinModelExchangeAggregatesResponse {
  repeated FinModelExchangeAggregateItem items = 1;
  int32 total_exchanges_count = 2;
  int32 all_completed_exchanges_count = 3;
  double total_amount_usdt = 4;
  repeated FinModelDebtByCurrency debt = 5;
}

message ExchangeMethodItem {
  int64 id = 1;
  string name = 2;
  int32 sort = 3;
}

message GetExchangeMethodsRequest {
  AuthManagerContext auth_manager_context = 1;
}

message GetExchangeMethodsResponse {
  repeated ExchangeMethodItem methods = 1;
}

message ExchangeStatusItem {
  int64 id = 1;
  string name = 2;
  bool is_completed = 3;
}

message GetExchangeStatusesRequest {
  AuthManagerContext auth_manager_context = 1;
}

message GetExchangeStatusesResponse {
  repeated ExchangeStatusItem statuses = 1;
}

message WalletItem {
  string id = 1;
  string name = 2;
  int32 sort = 3;
  double balance = 4;
  bool status = 5;
  optional string current_manager_id = 6;
  optional string manager_changed = 7;
  bool is_general = 8;
  bool show_on_balances = 9;
  optional string crypto_address = 10;
  optional int32 crypto_network = 11;
  bool is_active = 12;
  repeated string currency_ids = 13;
}

message GetWalletsRequest {
  AuthManagerContext auth_manager_context = 1;
  optional string search = 2;
  optional bool is_active = 3;
  optional int32 page = 4;
  optional int32 page_size = 5;
}

message GetWalletsResponse {
  int32 count = 1;
  optional string next = 2;
  optional string previous = 3;
  repeated WalletItem results = 4;
}

message GetWalletsMonikaRequest {
  optional string currency_id = 1;
  optional string is_active = 2;
}

message WalletMonikaCurrency {
  int64 id = 1;
  string short_name = 2;
  string name = 3;
}

message WalletMonikaItem {
  string id = 1;
  string name = 2;
  repeated WalletMonikaCurrency currencies = 3;
  double balance = 4;
  bool status = 5;
  bool is_active = 6;
  optional string crypto_address = 7;
  optional int32 crypto_network = 8;
  bool is_general = 9;
}

message GetWalletsMonikaResponse {
  repeated WalletMonikaItem wallets = 2;
}

message PaymentAgentDailyRateItem {
  string id = 1;
  int32 payment_agent = 2;
  string rate_date = 3; // YYYY-MM-DD
  double actual_cost = 4;
  bool is_applied = 5;
  int32 affected_payments = 6;
  string created_at = 7;
  optional string created_by_manager_id = 8;
  bool recalculate_payouts = 9;
}

message ListPaymentAgentDailyRatesRequest {
  AuthManagerContext auth_manager_context = 1;
}

message ListPaymentAgentDailyRatesResponse {
  repeated PaymentAgentDailyRateItem items = 1;
}

message CreatePaymentAgentDailyRateRequest {
  AuthManagerContext auth_manager_context = 1;
  int32 payment_agent = 2;
  string rate_date = 3; // YYYY-MM-DD
  double actual_cost = 4;
  bool recalculate_payouts = 5;
}

message CreatePaymentAgentDailyRateResponse {
  bool ok = 1;
  optional string error = 2;
  optional PaymentAgentDailyRateItem item = 3;
}

message PreviewPaymentAgentDailyRateRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message PaymentAgentDailyRatePaymentPreviewItem {
  string id = 1;
  optional double current_rate = 2;
  string created_at = 3;
}

message PaymentAgentDailyRateExchangePreviewItem {
  string id = 1;
  optional string payment_id = 2;
  optional double current_rate_1_iter = 3;
  optional double current_profit = 4;
  optional string input_currency_id = 5;
  optional string output_currency_id = 6;
}

message PreviewPaymentAgentDailyRateResponse {
  bool ok = 1;
  optional string error = 2;
  optional PaymentAgentDailyRateItem item = 3;
  int32 payments_count = 4;
  int32 exchanges_count = 5;
  repeated PaymentAgentDailyRatePaymentPreviewItem payments_first = 6;
  repeated PaymentAgentDailyRatePaymentPreviewItem payments_last = 7;
  repeated PaymentAgentDailyRateExchangePreviewItem exchanges_first = 8;
  repeated PaymentAgentDailyRateExchangePreviewItem exchanges_last = 9;
}

message ApplyPaymentAgentDailyRateRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message ApplyPaymentAgentDailyRateResponse {
  bool ok = 1;
  optional string error = 2;
  optional PaymentAgentDailyRateItem item = 3;
  int32 payments_updated = 4;
  int32 exchanges_updated = 5;
  optional string task_id = 6;
  int32 transactions_updated = 7;
}

message DeletePaymentAgentDailyRateRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message DeletePaymentAgentDailyRateResponse {
  bool ok = 1;
  optional string error = 2;
  bool deleted = 3;
}

// --- Exchange Overpay payouts (CRM «Выплаты по обменам») ---

message ListExchangePayoutsRequest {
  AuthManagerContext auth_manager_context = 1;
  optional int32 page = 2;
  optional int32 page_size = 3;
  optional string manager_id = 4;
}

message ExchangePayoutManager {
  string id = 1;
  optional string email = 2;
  optional string username = 3;
}

message ExchangePayoutItem {
  string id = 1;
  optional string payout_agent_id = 2;
  optional string uuid = 3;
  int32 payment_agent = 4;
  double amount = 5;
  int32 status = 6;
  optional string payment_agent_status = 7;
  optional string pan = 8;
  optional string cardholder = 9;
  optional string manager_id = 10;
  optional ExchangePayoutManager manager = 11;
  string created_at = 12;
  string updated_at = 13;
  // CARD | SBP | WALLET | ACCOUNT
  optional string payout_kind = 14;
  optional string destination_mask = 15;
  optional string bank = 16;
}

message ListExchangePayoutsResponse {
  int32 count = 1;
  optional string next = 2;
  optional string previous = 3;
  repeated ExchangePayoutItem results = 4;
}

message GetExchangePayoutRequest {
  AuthManagerContext auth_manager_context = 1;
  string id = 2;
}

message GetExchangePayoutResponse {
  bool ok = 1;
  optional ExchangePayoutItem result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message CreateExchangePayoutRequest {
  AuthManagerContext auth_manager_context = 1;
  double amount = 2;
  string pan = 3;
  string holder = 4;
  string cvv = 5;
  int32 month = 6;
  int32 year = 7;
  string uuid = 8;
  optional int32 payment_agent = 9;
  optional string manager_id = 10;
  // CARD | SBP | WALLET | ACCOUNT (Pay1Time); Overpay implies CARD.
  optional string payout_kind = 11;
  optional string phone = 12;
  optional string bank = 13;
  optional string wallet = 14;
  optional string account = 15;
  optional string fio = 16;
}

message CreateExchangePayoutResponse {
  bool ok = 1;
  optional ExchangePayoutItem result = 2;
  optional string error = 3;
  optional google.protobuf.Struct validationErrors = 4;
}

message HandleExchangePayoutWebhookRequest {
  string json_payload = 1;
}

message HandleExchangePayoutWebhookResponse {
  bool ok = 1;
  string status = 2;
}
