@aepstore-dev/contracts 1.63.0 → 1.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/gen/activity.js +1 -1
- package/gen/activity.ts +1 -1
- package/gen/auth.js +1 -1
- package/gen/auth.ts +1 -1
- package/gen/mail.js +1 -1
- package/gen/mail.ts +1 -1
- package/gen/payments.js +1 -1
- package/gen/payments.ts +1 -1
- package/gen/products.js +1 -1
- package/gen/products.ts +1 -1
- package/gen/support.d.ts +30 -0
- package/gen/support.js +3 -1
- package/gen/support.ts +44 -1
- package/gen/taxonomy.js +1 -1
- package/gen/taxonomy.ts +1 -1
- package/gen/upload.js +1 -1
- package/gen/upload.ts +1 -1
- package/gen/users.js +1 -1
- package/gen/users.ts +1 -1
- package/package.json +35 -35
- package/proto/activity.proto +200 -200
- package/proto/auth.proto +198 -198
- package/proto/mail.proto +54 -54
- package/proto/payments.proto +516 -516
- package/proto/products.proto +405 -405
- package/proto/support.proto +170 -144
- package/proto/taxonomy.proto +105 -105
- package/proto/upload.proto +171 -171
- package/proto/users.proto +690 -690
package/proto/payments.proto
CHANGED
|
@@ -1,516 +1,516 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
|
|
3
|
-
package payments.v1;
|
|
4
|
-
|
|
5
|
-
// Commerce + double-entry wallet/ledger (D9 / D9.2). See payments-service/docs/FINANCE.md.
|
|
6
|
-
// Money = Decimal-as-string (D7). Statuses/enums as strings (avoid proto enum
|
|
7
|
-
// value-name clashes within one package).
|
|
8
|
-
service PaymentsService {
|
|
9
|
-
// ----- buyer -----
|
|
10
|
-
rpc Topup(TopupRequest) returns (CheckoutResponse);
|
|
11
|
-
rpc CreateCheckout(CreateCheckoutRequest) returns (CheckoutResponse);
|
|
12
|
-
rpc GetMyPurchases(GetMyPurchasesRequest) returns (PurchasesListResponse);
|
|
13
|
-
rpc GetPurchase(GetPurchaseRequest) returns (Purchase);
|
|
14
|
-
rpc RefundPurchase(RefundPurchaseRequest) returns (Purchase);
|
|
15
|
-
|
|
16
|
-
// ----- wallet -----
|
|
17
|
-
rpc GetWallet(GetWalletRequest) returns (WalletResponse);
|
|
18
|
-
rpc ListTransactions(ListTransactionsRequest) returns (TransactionsListResponse);
|
|
19
|
-
rpc GetTransactionMonths(GetTransactionMonthsRequest) returns (GetTransactionMonthsResponse);
|
|
20
|
-
|
|
21
|
-
// ----- withdrawals -----
|
|
22
|
-
rpc RequestWithdrawal(RequestWithdrawalRequest) returns (Withdrawal);
|
|
23
|
-
rpc ListWithdrawals(ListWithdrawalsRequest) returns (WithdrawalsListResponse);
|
|
24
|
-
rpc ProcessWithdrawal(ProcessWithdrawalRequest) returns (Withdrawal);
|
|
25
|
-
|
|
26
|
-
// ----- provider webhook (gateway forwards a verified event) -----
|
|
27
|
-
rpc HandlePaymentEvent(PaymentEventRequest) returns (Ok);
|
|
28
|
-
// Generalized per-provider callback (POST /payments/webhook/:provider).
|
|
29
|
-
// Carries the EXACT raw JSON body: signed providers (Heleket) hash the
|
|
30
|
-
// byte-exact payload, so re-serializing a parsed body would break the sign.
|
|
31
|
-
rpc HandleProviderCallback(ProviderCallbackRequest) returns (Ok);
|
|
32
|
-
|
|
33
|
-
// ----- premium -----
|
|
34
|
-
rpc GetPremiumPlans(GetPremiumPlansRequest) returns (PremiumPlansResponse);
|
|
35
|
-
rpc PurchasePremium(PurchasePremiumRequest) returns (PurchasePremiumResponse);
|
|
36
|
-
rpc SetPremiumPaymentMethod(SetPremiumPaymentMethodRequest) returns (PremiumPaymentMethodResponse);
|
|
37
|
-
// 7-day refund window from completedAt. Reverses ledger, calls YooKassa for
|
|
38
|
-
// card purchases, rolls back the subscription's expiresAt by the period.
|
|
39
|
-
rpc RefundPremium(RefundPremiumRequest) returns (RefundPremiumResponse);
|
|
40
|
-
rpc GetMyPremiumPayments(GetMyPremiumPaymentsRequest) returns (PremiumPaymentsListResponse);
|
|
41
|
-
rpc GetPremiumPayment(GetPremiumPaymentRequest) returns (PremiumPaymentRow);
|
|
42
|
-
// Internal — InternalServiceGuard. tasks-service cron triggers due renewals;
|
|
43
|
-
// payments-service iterates ACTIVE subscriptions with autoRenew+savedCard.
|
|
44
|
-
rpc RunPremiumRenewals(RunPremiumRenewalsRequest) returns (RunPremiumRenewalsResponse);
|
|
45
|
-
|
|
46
|
-
// ----- saved cards -----
|
|
47
|
-
rpc ListSavedCards(ListSavedCardsRequest) returns (ListSavedCardsResponse);
|
|
48
|
-
rpc DeleteSavedCard(DeleteSavedCardRequest) returns (Ok);
|
|
49
|
-
rpc SetDefaultSavedCard(SetDefaultSavedCardRequest) returns (SavedCard);
|
|
50
|
-
rpc UpdateSavedCard(UpdateSavedCardRequest) returns (SavedCard);
|
|
51
|
-
// Standalone "bind card" flow: creates a 1₽ YooKassa charge with
|
|
52
|
-
// save_payment_method=true; after the webhook the SavedCard row is
|
|
53
|
-
// persisted and the 1₽ credits USER_SPENDING so the user keeps it.
|
|
54
|
-
rpc BindCard(BindCardRequest) returns (CheckoutResponse);
|
|
55
|
-
// Poll an intent after returnUrl redirect: TOPUP/PREMIUM completion, bind-card
|
|
56
|
-
// completion. Ownership-checked by user_id.
|
|
57
|
-
rpc GetPaymentIntent(GetPaymentIntentRequest) returns (PaymentIntentStatus);
|
|
58
|
-
|
|
59
|
-
// ----- FX / available methods (public, cached) -----
|
|
60
|
-
// Daily CBR rates (RUB base). Frontend uses this for the "≈" display hint;
|
|
61
|
-
// the authoritative charge amount is always computed server-side at checkout.
|
|
62
|
-
rpc GetRates(GetRatesRequest) returns (GetRatesResponse);
|
|
63
|
-
// Payment methods derived from live provider capabilities — the client
|
|
64
|
-
// renders only what is actually available (e.g. CRYPTO appears once the
|
|
65
|
-
// Heleket merchant is configured).
|
|
66
|
-
rpc GetPaymentMethods(GetPaymentMethodsRequest) returns (GetPaymentMethodsResponse);
|
|
67
|
-
|
|
68
|
-
// ----- payout details -----
|
|
69
|
-
rpc UpdatePayoutDetails(UpdatePayoutDetailsRequest) returns (UpdatePayoutDetailsResponse);
|
|
70
|
-
rpc GetPayoutDetails(GetPayoutDetailsRequest) returns (UpdatePayoutDetailsResponse);
|
|
71
|
-
|
|
72
|
-
// ----- admin -----
|
|
73
|
-
rpc GetAdminOverview(AdminOverviewRequest) returns (AdminOverviewResponse);
|
|
74
|
-
rpc AdminListTransactions(AdminListTransactionsRequest) returns (AdminTransactionsListResponse);
|
|
75
|
-
rpc GetUserFinance(GetUserFinanceRequest) returns (UserFinanceResponse);
|
|
76
|
-
rpc CreateAdjustment(CreateAdjustmentRequest) returns (Ok);
|
|
77
|
-
rpc GetSalesAnalytics(SalesAnalyticsRequest) returns (SalesAnalyticsResponse);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
message Ok { bool ok = 1; }
|
|
81
|
-
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
// Purchase / checkout / topup
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
85
|
-
message Purchase {
|
|
86
|
-
string id = 1;
|
|
87
|
-
string product_id = 2;
|
|
88
|
-
string product_name = 3;
|
|
89
|
-
string user_id = 4;
|
|
90
|
-
string price = 5; // settled RUB amount
|
|
91
|
-
string status = 6; // PENDING | COMPLETED | FAILED | REFUNDED
|
|
92
|
-
string payment_id = 7;
|
|
93
|
-
string payment_method = 8; // BALANCE | YOOKASSA | CRYPTO
|
|
94
|
-
string commission_percent = 9;
|
|
95
|
-
string seller_amount = 10;
|
|
96
|
-
string created_at = 11;
|
|
97
|
-
string completed_at = 12;
|
|
98
|
-
// FX snapshot at checkout (empty for legacy RUB purchases).
|
|
99
|
-
string listing_currency = 13; // RUB | USD | EUR
|
|
100
|
-
string listing_price = 14; // Decimal as string, in listing_currency
|
|
101
|
-
string fx_rate = 15; // listing→RUB rate used (Decimal as string)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
message TopupRequest {
|
|
105
|
-
string user_id = 1;
|
|
106
|
-
string amount = 2; // >= 10.00
|
|
107
|
-
string return_url = 3;
|
|
108
|
-
string payment_method = 4; // YOOKASSA | SAVED_CARD | CRYPTO (default YOOKASSA)
|
|
109
|
-
string saved_card_id = 5; // required when payment_method=SAVED_CARD
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
message CreateCheckoutRequest {
|
|
113
|
-
string user_id = 1;
|
|
114
|
-
string product_id = 2;
|
|
115
|
-
string payment_method = 3; // BALANCE | YOOKASSA | SAVED_CARD | CRYPTO (default YOOKASSA)
|
|
116
|
-
string return_url = 4;
|
|
117
|
-
// When payment_method=SAVED_CARD — required. ID of a SavedCard row owned
|
|
118
|
-
// by user_id. Ignored otherwise.
|
|
119
|
-
string saved_card_id = 5;
|
|
120
|
-
// When payment_method=YOOKASSA — optional. If true, save the card token
|
|
121
|
-
// after success; the bound card becomes available in /account/cards.
|
|
122
|
-
bool save_payment_method = 6;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
message BindCardRequest {
|
|
126
|
-
string user_id = 1;
|
|
127
|
-
string return_url = 2;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
message GetPaymentIntentRequest {
|
|
131
|
-
string intent_id = 1;
|
|
132
|
-
string user_id = 2; // ownership check
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
message PaymentIntentStatus {
|
|
136
|
-
string id = 1;
|
|
137
|
-
string user_id = 2;
|
|
138
|
-
string purpose = 3; // TOPUP | PREMIUM
|
|
139
|
-
string status = 4; // PENDING | COMPLETED | FAILED | CANCELED
|
|
140
|
-
string amount = 5;
|
|
141
|
-
string currency = 6;
|
|
142
|
-
string purchase_id = 7; // set when purpose=PREMIUM (else empty)
|
|
143
|
-
string created_at = 8;
|
|
144
|
-
string updated_at = 9;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
message CheckoutResponse {
|
|
148
|
-
string purchase_id = 1;
|
|
149
|
-
string payment_id = 2;
|
|
150
|
-
string confirmation_url = 3; // empty when paid from balance (instant)
|
|
151
|
-
string status = 4; // PENDING (redirect) | COMPLETED (balance)
|
|
152
|
-
string intent_id = 5; // poll via GetPaymentIntent for TOPUP / bind-card flows
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
message GetMyPurchasesRequest { string user_id = 1; int32 page = 2; int32 limit = 3; }
|
|
156
|
-
message PurchasesListResponse { repeated Purchase items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
157
|
-
message GetPurchaseRequest { string id = 1; string user_id = 2; }
|
|
158
|
-
message RefundPurchaseRequest { string purchase_id = 1; string actor_user_id = 2; bool is_admin = 3; string reason = 4; }
|
|
159
|
-
|
|
160
|
-
// ---------------------------------------------------------------------------
|
|
161
|
-
// Wallet & statement
|
|
162
|
-
// ---------------------------------------------------------------------------
|
|
163
|
-
message GetWalletRequest { string user_id = 1; }
|
|
164
|
-
message WalletResponse {
|
|
165
|
-
string spending = 1;
|
|
166
|
-
string pending = 2;
|
|
167
|
-
string payout = 3;
|
|
168
|
-
string spendable = 4; // spending + payout
|
|
169
|
-
string withdrawable = 5; // payout
|
|
170
|
-
string currency = 6;
|
|
171
|
-
int32 lifetime_sales = 7;
|
|
172
|
-
string current_commission_percent = 8;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
message ListTransactionsRequest {
|
|
176
|
-
string user_id = 1;
|
|
177
|
-
// Legacy low-level filter (one of LedgerTxType). Kept for backward
|
|
178
|
-
// compatibility — admin tooling still uses it directly.
|
|
179
|
-
string type = 2;
|
|
180
|
-
int32 page = 3;
|
|
181
|
-
int32 limit = 4;
|
|
182
|
-
// ↓ added for the wallet statement page (Round 3)
|
|
183
|
-
// UI-semantic filter mapped onto displayKind:
|
|
184
|
-
// ALL | SALES | INCOME | OUTCOME | REFUND | WITHDRAWAL | PREMIUM
|
|
185
|
-
// SALES = the seller's earnings on this account (USER_PENDING credits from
|
|
186
|
-
// PURCHASE transactions); these stay separate from INCOME (TOPUP).
|
|
187
|
-
string flow = 5;
|
|
188
|
-
// Period selection. `month` is the convenience form (YYYY-MM) used by the
|
|
189
|
-
// month dropdown; from/to override it for an arbitrary range.
|
|
190
|
-
string month = 6;
|
|
191
|
-
string from = 7;
|
|
192
|
-
string to = 8;
|
|
193
|
-
// Filter wallet to purchases/refunds of a specific Product category. Has
|
|
194
|
-
// no effect on TOPUP/WITHDRAWAL/PREMIUM/ADJUSTMENT entries (they have no
|
|
195
|
-
// product).
|
|
196
|
-
string product_category_id = 9;
|
|
197
|
-
// sort_by ∈ { date | amount | type }. Default: date.
|
|
198
|
-
string sort_by = 10;
|
|
199
|
-
// order ∈ { asc | desc }. Default: desc.
|
|
200
|
-
string order = 11;
|
|
201
|
-
}
|
|
202
|
-
message StatementEntry {
|
|
203
|
-
string id = 1;
|
|
204
|
-
string tx_id = 2;
|
|
205
|
-
string type = 3; // raw tx type (TOPUP|PURCHASE|...)
|
|
206
|
-
string account_kind = 4;
|
|
207
|
-
string direction = 5; // DEBIT | CREDIT
|
|
208
|
-
string amount = 6;
|
|
209
|
-
string description = 7;
|
|
210
|
-
string created_at = 8;
|
|
211
|
-
// ↓ added for the wallet statement page (Round 3)
|
|
212
|
-
// UI-friendly classification computed server-side:
|
|
213
|
-
// TOPUP | PURCHASE | SALE | REFUND | PREMIUM | WITHDRAWAL | ADJUSTMENT
|
|
214
|
-
// SALE is the seller's view of someone else's PURCHASE (CREDIT to their
|
|
215
|
-
// USER_PENDING) — distinct from PURCHASE which is the buyer's DEBIT.
|
|
216
|
-
// PREMIUM is split out of PURCHASE/REFUND so the UI can show
|
|
217
|
-
// "Продление Premium" / refund-of-premium in their own filter bucket.
|
|
218
|
-
// SALE_CLEAR transactions are excluded from the wallet view — the maturity
|
|
219
|
-
// event is surfaced via sale_status on the original SALE row instead.
|
|
220
|
-
string display_kind = 9;
|
|
221
|
-
string balance_after = 10; // affected-account running balance, Decimal-as-string
|
|
222
|
-
string product_id = 11; // empty for non-product entries
|
|
223
|
-
string product_name = 12;
|
|
224
|
-
string product_category = 13; // "Assets" | "Project File" | "Templates"
|
|
225
|
-
string product_preview = 14; // optional thumbnail URL for richer rows
|
|
226
|
-
// Sale lifecycle. Populated only when display_kind=SALE.
|
|
227
|
-
// PENDING — held in USER_PENDING, not yet withdrawable.
|
|
228
|
-
// MATURED — SALE_CLEAR has fired; money is in USER_PAYOUT.
|
|
229
|
-
string sale_status = 15;
|
|
230
|
-
// ISO 8601 when the sale becomes withdrawable (sale_completed_at +
|
|
231
|
-
// GRACE_DAYS). Empty for non-sale rows.
|
|
232
|
-
string matures_at = 16;
|
|
233
|
-
}
|
|
234
|
-
message TransactionsListResponse { repeated StatementEntry items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
235
|
-
|
|
236
|
-
message GetTransactionMonthsRequest { string user_id = 1; }
|
|
237
|
-
message GetTransactionMonthsResponse {
|
|
238
|
-
// Newest first. "YYYY-MM" strings; the dropdown renders them
|
|
239
|
-
// localized client-side.
|
|
240
|
-
repeated string months = 1;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// ---------------------------------------------------------------------------
|
|
244
|
-
// Withdrawals
|
|
245
|
-
// ---------------------------------------------------------------------------
|
|
246
|
-
message Withdrawal {
|
|
247
|
-
string id = 1;
|
|
248
|
-
string seller_id = 2;
|
|
249
|
-
string amount = 3;
|
|
250
|
-
string status = 4; // PENDING | PROCESSING | COMPLETED | REJECTED
|
|
251
|
-
string method = 5;
|
|
252
|
-
string details = 6;
|
|
253
|
-
string comment = 7;
|
|
254
|
-
string processed_by = 8;
|
|
255
|
-
string processed_at = 9;
|
|
256
|
-
string created_at = 10;
|
|
257
|
-
}
|
|
258
|
-
message RequestWithdrawalRequest { string seller_id = 1; string amount = 2; string method = 3; string details = 4; }
|
|
259
|
-
message ListWithdrawalsRequest { string seller_id = 1; string status = 2; int32 page = 3; int32 limit = 4; }
|
|
260
|
-
message WithdrawalsListResponse { repeated Withdrawal items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
261
|
-
message ProcessWithdrawalRequest { string withdrawal_id = 1; string admin_id = 2; string action = 3; string comment = 4; }
|
|
262
|
-
|
|
263
|
-
// ---------------------------------------------------------------------------
|
|
264
|
-
// Webhook
|
|
265
|
-
// ---------------------------------------------------------------------------
|
|
266
|
-
message PaymentEventRequest { string event = 1; string payment_id = 2; }
|
|
267
|
-
|
|
268
|
-
message ProviderCallbackRequest {
|
|
269
|
-
string provider = 1; // yookassa | heleket | …
|
|
270
|
-
string raw_body = 2; // exact raw JSON body as received (signature input)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
// FX rates / payment methods
|
|
275
|
-
// ---------------------------------------------------------------------------
|
|
276
|
-
message GetRatesRequest {}
|
|
277
|
-
|
|
278
|
-
message FxRate {
|
|
279
|
-
string currency = 1; // USD | EUR
|
|
280
|
-
string rate = 2; // RUB per 1 unit, Decimal as string
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
message GetRatesResponse {
|
|
284
|
-
string base = 1; // always RUB
|
|
285
|
-
string as_of = 2; // YYYY-MM-DD the rates are for
|
|
286
|
-
repeated FxRate rates = 3;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
message GetPaymentMethodsRequest {}
|
|
290
|
-
|
|
291
|
-
message PaymentMethodInfo {
|
|
292
|
-
string method = 1; // YOOKASSA | SAVED_CARD | CRYPTO | BALANCE
|
|
293
|
-
string provider = 2; // yookassa | heleket | '' (BALANCE)
|
|
294
|
-
repeated string currencies = 3;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
message GetPaymentMethodsResponse {
|
|
298
|
-
repeated PaymentMethodInfo methods = 1;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// ---------------------------------------------------------------------------
|
|
302
|
-
// Admin
|
|
303
|
-
// ---------------------------------------------------------------------------
|
|
304
|
-
message AdminOverviewRequest { string from = 1; string to = 2; }
|
|
305
|
-
message AdminOverviewResponse {
|
|
306
|
-
string revenue = 1; // platform commission earned (period)
|
|
307
|
-
string gmv = 2; // gross merchandise value (period)
|
|
308
|
-
string liabilities = 3; // Σ all users' (pending+payout+spending) — what we owe
|
|
309
|
-
string psp_clearing = 4; // money in transit at PSP
|
|
310
|
-
string payouts_payable = 5; // reserved for approved withdrawals
|
|
311
|
-
string refunds_total = 6;
|
|
312
|
-
string topups_total = 7;
|
|
313
|
-
string withdrawals_total = 8;
|
|
314
|
-
int32 sales_count = 9;
|
|
315
|
-
string currency = 10;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
message AdminListTransactionsRequest {
|
|
319
|
-
string type = 1;
|
|
320
|
-
string user_id = 2;
|
|
321
|
-
string account_kind = 3;
|
|
322
|
-
string from = 4;
|
|
323
|
-
string to = 5;
|
|
324
|
-
int32 page = 6;
|
|
325
|
-
int32 limit = 7;
|
|
326
|
-
}
|
|
327
|
-
message AdminEntry { string account_id = 1; string account_kind = 2; string owner_id = 3; string direction = 4; string amount = 5; }
|
|
328
|
-
message AdminLedgerTx {
|
|
329
|
-
string id = 1;
|
|
330
|
-
string type = 2;
|
|
331
|
-
string status = 3;
|
|
332
|
-
string ref_type = 4;
|
|
333
|
-
string ref_id = 5;
|
|
334
|
-
string description = 6;
|
|
335
|
-
string created_by = 7;
|
|
336
|
-
string created_at = 8;
|
|
337
|
-
repeated AdminEntry entries = 9;
|
|
338
|
-
}
|
|
339
|
-
message AdminTransactionsListResponse { repeated AdminLedgerTx items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
340
|
-
|
|
341
|
-
message GetUserFinanceRequest { string user_id = 1; }
|
|
342
|
-
message AccountBalance { string kind = 1; string balance = 2; string currency = 3; }
|
|
343
|
-
message UserFinanceResponse {
|
|
344
|
-
WalletResponse wallet = 1;
|
|
345
|
-
repeated AccountBalance accounts = 2;
|
|
346
|
-
repeated StatementEntry recent = 3;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
message CreateAdjustmentRequest {
|
|
350
|
-
string admin_id = 1;
|
|
351
|
-
string user_id = 2;
|
|
352
|
-
string account_kind = 3; // USER_SPENDING | USER_PAYOUT | USER_PENDING
|
|
353
|
-
string direction = 4; // CREDIT (give) | DEBIT (take)
|
|
354
|
-
string amount = 5;
|
|
355
|
-
string reason = 6;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
message SalesAnalyticsRequest { string from = 1; string to = 2; string granularity = 3; } // day|week|month
|
|
359
|
-
message SalesPoint { string date = 1; int32 sales_count = 2; string gmv = 3; string revenue = 4; }
|
|
360
|
-
message SellerStat { string seller_id = 1; string username = 2; int32 sales = 3; string gmv = 4; }
|
|
361
|
-
message SalesAnalyticsResponse {
|
|
362
|
-
repeated SalesPoint points = 1;
|
|
363
|
-
repeated SellerStat top_sellers = 2;
|
|
364
|
-
string refund_rate = 3; // % refunded purchases
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// ---------------------------------------------------------------------------
|
|
368
|
-
// Premium
|
|
369
|
-
// ---------------------------------------------------------------------------
|
|
370
|
-
message GetPremiumPlansRequest {}
|
|
371
|
-
|
|
372
|
-
// One plan per (period). Prices are computed server-side from BASE_PRICE × months
|
|
373
|
-
// × (1 − discount); kept here as canonical strings so the gateway has no math.
|
|
374
|
-
message PremiumPlan {
|
|
375
|
-
string period = 1; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
376
|
-
int32 months = 2;
|
|
377
|
-
string price = 3; // total to charge, Decimal-as-string
|
|
378
|
-
string monthly_price = 4; // for UI "≈ X ₽/month"
|
|
379
|
-
string discount_percent = 5;
|
|
380
|
-
string currency = 6;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
message PremiumPlansResponse {
|
|
384
|
-
repeated PremiumPlan plans = 1;
|
|
385
|
-
string base_monthly_price = 2;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
message PurchasePremiumRequest {
|
|
389
|
-
string user_id = 1;
|
|
390
|
-
string period = 2; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
391
|
-
string payment_method = 3; // BALANCE | YOOKASSA | SAVED_CARD (empty = smart default)
|
|
392
|
-
string return_url = 4; // YooKassa only
|
|
393
|
-
// Save the YooKassa payment_method for future auto-renewals. Ignored for
|
|
394
|
-
// BALANCE. Kept for backwards compatibility; auto_renew=true implies save.
|
|
395
|
-
bool save_payment_method = 5;
|
|
396
|
-
bool auto_renew = 6; // default false; requires off-session-capable method
|
|
397
|
-
string saved_card_id = 7; // optional for SAVED_CARD; empty = default card
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
message PurchasePremiumResponse {
|
|
401
|
-
string payment_id = 1; // PremiumPayment.id
|
|
402
|
-
string confirmation_url = 2; // empty for BALANCE (instant) or YooKassa-issued
|
|
403
|
-
string status = 3; // PENDING (redirect) | COMPLETED (balance)
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
message RunPremiumRenewalsRequest {
|
|
407
|
-
int32 max_batch = 1; // safety cap; default 100
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
message RunPremiumRenewalsResponse {
|
|
411
|
-
int32 attempted = 1;
|
|
412
|
-
int32 succeeded = 2;
|
|
413
|
-
int32 failed = 3;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
message SetPremiumPaymentMethodRequest {
|
|
417
|
-
string user_id = 1;
|
|
418
|
-
string method = 2; // BALANCE | YOOKASSA | SAVED_CARD
|
|
419
|
-
string saved_card_id = 3; // optional for SAVED_CARD; empty = default card
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
message PremiumPaymentMethodResponse {
|
|
423
|
-
string method = 1; // BALANCE | YOOKASSA | SAVED_CARD
|
|
424
|
-
string saved_card_id = 2; // empty unless SAVED_CARD
|
|
425
|
-
bool auto_renew = 3;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
message PremiumPaymentRow {
|
|
429
|
-
string id = 1;
|
|
430
|
-
string user_id = 2;
|
|
431
|
-
string amount = 3;
|
|
432
|
-
string period = 4; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
433
|
-
string method = 5; // BALANCE | YOOKASSA
|
|
434
|
-
string status = 6; // PENDING | COMPLETED | FAILED | REFUNDED
|
|
435
|
-
bool is_renewal = 7;
|
|
436
|
-
string created_at = 8;
|
|
437
|
-
string completed_at = 9;
|
|
438
|
-
string refunded_at = 10;
|
|
439
|
-
string refunded_amount = 11;
|
|
440
|
-
// Convenience: true if this payment is currently inside the 7-day refund
|
|
441
|
-
// window AND status == COMPLETED AND not already refunded.
|
|
442
|
-
bool refundable = 12;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
message RefundPremiumRequest {
|
|
446
|
-
string user_id = 1;
|
|
447
|
-
string payment_id = 2;
|
|
448
|
-
string reason = 3; // optional
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
message RefundPremiumResponse {
|
|
452
|
-
PremiumPaymentRow payment = 1;
|
|
453
|
-
string new_expires_at = 2; // ISO 8601 after rollback
|
|
454
|
-
bool subscription_revoked = 3; // true when rollback put expiresAt <= now
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
message GetMyPremiumPaymentsRequest {
|
|
458
|
-
string user_id = 1;
|
|
459
|
-
int32 page = 2;
|
|
460
|
-
int32 limit = 3;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
message GetPremiumPaymentRequest {
|
|
464
|
-
string user_id = 1;
|
|
465
|
-
string payment_id = 2;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
message PremiumPaymentsListResponse {
|
|
469
|
-
repeated PremiumPaymentRow items = 1;
|
|
470
|
-
int32 total = 2;
|
|
471
|
-
int32 page = 3;
|
|
472
|
-
int32 limit = 4;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// ---------------------------------------------------------------------------
|
|
476
|
-
// Saved cards (YooKassa payment_method tokens; we never see PAN)
|
|
477
|
-
// ---------------------------------------------------------------------------
|
|
478
|
-
message SavedCard {
|
|
479
|
-
string id = 1;
|
|
480
|
-
string brand = 2; // "MIR" | "VISA" | "MASTERCARD" | ""
|
|
481
|
-
string last4 = 3; // "0000" etc, display-only
|
|
482
|
-
int32 exp_month = 4;
|
|
483
|
-
int32 exp_year = 5;
|
|
484
|
-
bool is_default = 6;
|
|
485
|
-
string nickname = 7; // user-set label
|
|
486
|
-
string created_at = 8;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
message ListSavedCardsRequest { string user_id = 1; }
|
|
490
|
-
message ListSavedCardsResponse { repeated SavedCard items = 1; }
|
|
491
|
-
|
|
492
|
-
message DeleteSavedCardRequest { string user_id = 1; string id = 2; }
|
|
493
|
-
|
|
494
|
-
message SetDefaultSavedCardRequest { string user_id = 1; string id = 2; }
|
|
495
|
-
|
|
496
|
-
message UpdateSavedCardRequest {
|
|
497
|
-
string user_id = 1;
|
|
498
|
-
string id = 2;
|
|
499
|
-
string nickname = 3; // empty = clear
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// ---------------------------------------------------------------------------
|
|
503
|
-
// Payout details (persistent default; per-withdrawal override still allowed)
|
|
504
|
-
// ---------------------------------------------------------------------------
|
|
505
|
-
message UpdatePayoutDetailsRequest {
|
|
506
|
-
string user_id = 1;
|
|
507
|
-
string method = 2; // "card" | "sbp" | "bank" | "" (clear)
|
|
508
|
-
string details = 3; // JSON string — payments-service treats opaquely
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
message UpdatePayoutDetailsResponse {
|
|
512
|
-
string method = 1;
|
|
513
|
-
string details = 2;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
message GetPayoutDetailsRequest { string user_id = 1; }
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package payments.v1;
|
|
4
|
+
|
|
5
|
+
// Commerce + double-entry wallet/ledger (D9 / D9.2). See payments-service/docs/FINANCE.md.
|
|
6
|
+
// Money = Decimal-as-string (D7). Statuses/enums as strings (avoid proto enum
|
|
7
|
+
// value-name clashes within one package).
|
|
8
|
+
service PaymentsService {
|
|
9
|
+
// ----- buyer -----
|
|
10
|
+
rpc Topup(TopupRequest) returns (CheckoutResponse);
|
|
11
|
+
rpc CreateCheckout(CreateCheckoutRequest) returns (CheckoutResponse);
|
|
12
|
+
rpc GetMyPurchases(GetMyPurchasesRequest) returns (PurchasesListResponse);
|
|
13
|
+
rpc GetPurchase(GetPurchaseRequest) returns (Purchase);
|
|
14
|
+
rpc RefundPurchase(RefundPurchaseRequest) returns (Purchase);
|
|
15
|
+
|
|
16
|
+
// ----- wallet -----
|
|
17
|
+
rpc GetWallet(GetWalletRequest) returns (WalletResponse);
|
|
18
|
+
rpc ListTransactions(ListTransactionsRequest) returns (TransactionsListResponse);
|
|
19
|
+
rpc GetTransactionMonths(GetTransactionMonthsRequest) returns (GetTransactionMonthsResponse);
|
|
20
|
+
|
|
21
|
+
// ----- withdrawals -----
|
|
22
|
+
rpc RequestWithdrawal(RequestWithdrawalRequest) returns (Withdrawal);
|
|
23
|
+
rpc ListWithdrawals(ListWithdrawalsRequest) returns (WithdrawalsListResponse);
|
|
24
|
+
rpc ProcessWithdrawal(ProcessWithdrawalRequest) returns (Withdrawal);
|
|
25
|
+
|
|
26
|
+
// ----- provider webhook (gateway forwards a verified event) -----
|
|
27
|
+
rpc HandlePaymentEvent(PaymentEventRequest) returns (Ok);
|
|
28
|
+
// Generalized per-provider callback (POST /payments/webhook/:provider).
|
|
29
|
+
// Carries the EXACT raw JSON body: signed providers (Heleket) hash the
|
|
30
|
+
// byte-exact payload, so re-serializing a parsed body would break the sign.
|
|
31
|
+
rpc HandleProviderCallback(ProviderCallbackRequest) returns (Ok);
|
|
32
|
+
|
|
33
|
+
// ----- premium -----
|
|
34
|
+
rpc GetPremiumPlans(GetPremiumPlansRequest) returns (PremiumPlansResponse);
|
|
35
|
+
rpc PurchasePremium(PurchasePremiumRequest) returns (PurchasePremiumResponse);
|
|
36
|
+
rpc SetPremiumPaymentMethod(SetPremiumPaymentMethodRequest) returns (PremiumPaymentMethodResponse);
|
|
37
|
+
// 7-day refund window from completedAt. Reverses ledger, calls YooKassa for
|
|
38
|
+
// card purchases, rolls back the subscription's expiresAt by the period.
|
|
39
|
+
rpc RefundPremium(RefundPremiumRequest) returns (RefundPremiumResponse);
|
|
40
|
+
rpc GetMyPremiumPayments(GetMyPremiumPaymentsRequest) returns (PremiumPaymentsListResponse);
|
|
41
|
+
rpc GetPremiumPayment(GetPremiumPaymentRequest) returns (PremiumPaymentRow);
|
|
42
|
+
// Internal — InternalServiceGuard. tasks-service cron triggers due renewals;
|
|
43
|
+
// payments-service iterates ACTIVE subscriptions with autoRenew+savedCard.
|
|
44
|
+
rpc RunPremiumRenewals(RunPremiumRenewalsRequest) returns (RunPremiumRenewalsResponse);
|
|
45
|
+
|
|
46
|
+
// ----- saved cards -----
|
|
47
|
+
rpc ListSavedCards(ListSavedCardsRequest) returns (ListSavedCardsResponse);
|
|
48
|
+
rpc DeleteSavedCard(DeleteSavedCardRequest) returns (Ok);
|
|
49
|
+
rpc SetDefaultSavedCard(SetDefaultSavedCardRequest) returns (SavedCard);
|
|
50
|
+
rpc UpdateSavedCard(UpdateSavedCardRequest) returns (SavedCard);
|
|
51
|
+
// Standalone "bind card" flow: creates a 1₽ YooKassa charge with
|
|
52
|
+
// save_payment_method=true; after the webhook the SavedCard row is
|
|
53
|
+
// persisted and the 1₽ credits USER_SPENDING so the user keeps it.
|
|
54
|
+
rpc BindCard(BindCardRequest) returns (CheckoutResponse);
|
|
55
|
+
// Poll an intent after returnUrl redirect: TOPUP/PREMIUM completion, bind-card
|
|
56
|
+
// completion. Ownership-checked by user_id.
|
|
57
|
+
rpc GetPaymentIntent(GetPaymentIntentRequest) returns (PaymentIntentStatus);
|
|
58
|
+
|
|
59
|
+
// ----- FX / available methods (public, cached) -----
|
|
60
|
+
// Daily CBR rates (RUB base). Frontend uses this for the "≈" display hint;
|
|
61
|
+
// the authoritative charge amount is always computed server-side at checkout.
|
|
62
|
+
rpc GetRates(GetRatesRequest) returns (GetRatesResponse);
|
|
63
|
+
// Payment methods derived from live provider capabilities — the client
|
|
64
|
+
// renders only what is actually available (e.g. CRYPTO appears once the
|
|
65
|
+
// Heleket merchant is configured).
|
|
66
|
+
rpc GetPaymentMethods(GetPaymentMethodsRequest) returns (GetPaymentMethodsResponse);
|
|
67
|
+
|
|
68
|
+
// ----- payout details -----
|
|
69
|
+
rpc UpdatePayoutDetails(UpdatePayoutDetailsRequest) returns (UpdatePayoutDetailsResponse);
|
|
70
|
+
rpc GetPayoutDetails(GetPayoutDetailsRequest) returns (UpdatePayoutDetailsResponse);
|
|
71
|
+
|
|
72
|
+
// ----- admin -----
|
|
73
|
+
rpc GetAdminOverview(AdminOverviewRequest) returns (AdminOverviewResponse);
|
|
74
|
+
rpc AdminListTransactions(AdminListTransactionsRequest) returns (AdminTransactionsListResponse);
|
|
75
|
+
rpc GetUserFinance(GetUserFinanceRequest) returns (UserFinanceResponse);
|
|
76
|
+
rpc CreateAdjustment(CreateAdjustmentRequest) returns (Ok);
|
|
77
|
+
rpc GetSalesAnalytics(SalesAnalyticsRequest) returns (SalesAnalyticsResponse);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
message Ok { bool ok = 1; }
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Purchase / checkout / topup
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
message Purchase {
|
|
86
|
+
string id = 1;
|
|
87
|
+
string product_id = 2;
|
|
88
|
+
string product_name = 3;
|
|
89
|
+
string user_id = 4;
|
|
90
|
+
string price = 5; // settled RUB amount
|
|
91
|
+
string status = 6; // PENDING | COMPLETED | FAILED | REFUNDED
|
|
92
|
+
string payment_id = 7;
|
|
93
|
+
string payment_method = 8; // BALANCE | YOOKASSA | CRYPTO
|
|
94
|
+
string commission_percent = 9;
|
|
95
|
+
string seller_amount = 10;
|
|
96
|
+
string created_at = 11;
|
|
97
|
+
string completed_at = 12;
|
|
98
|
+
// FX snapshot at checkout (empty for legacy RUB purchases).
|
|
99
|
+
string listing_currency = 13; // RUB | USD | EUR
|
|
100
|
+
string listing_price = 14; // Decimal as string, in listing_currency
|
|
101
|
+
string fx_rate = 15; // listing→RUB rate used (Decimal as string)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
message TopupRequest {
|
|
105
|
+
string user_id = 1;
|
|
106
|
+
string amount = 2; // >= 10.00
|
|
107
|
+
string return_url = 3;
|
|
108
|
+
string payment_method = 4; // YOOKASSA | SAVED_CARD | CRYPTO (default YOOKASSA)
|
|
109
|
+
string saved_card_id = 5; // required when payment_method=SAVED_CARD
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
message CreateCheckoutRequest {
|
|
113
|
+
string user_id = 1;
|
|
114
|
+
string product_id = 2;
|
|
115
|
+
string payment_method = 3; // BALANCE | YOOKASSA | SAVED_CARD | CRYPTO (default YOOKASSA)
|
|
116
|
+
string return_url = 4;
|
|
117
|
+
// When payment_method=SAVED_CARD — required. ID of a SavedCard row owned
|
|
118
|
+
// by user_id. Ignored otherwise.
|
|
119
|
+
string saved_card_id = 5;
|
|
120
|
+
// When payment_method=YOOKASSA — optional. If true, save the card token
|
|
121
|
+
// after success; the bound card becomes available in /account/cards.
|
|
122
|
+
bool save_payment_method = 6;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
message BindCardRequest {
|
|
126
|
+
string user_id = 1;
|
|
127
|
+
string return_url = 2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
message GetPaymentIntentRequest {
|
|
131
|
+
string intent_id = 1;
|
|
132
|
+
string user_id = 2; // ownership check
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
message PaymentIntentStatus {
|
|
136
|
+
string id = 1;
|
|
137
|
+
string user_id = 2;
|
|
138
|
+
string purpose = 3; // TOPUP | PREMIUM
|
|
139
|
+
string status = 4; // PENDING | COMPLETED | FAILED | CANCELED
|
|
140
|
+
string amount = 5;
|
|
141
|
+
string currency = 6;
|
|
142
|
+
string purchase_id = 7; // set when purpose=PREMIUM (else empty)
|
|
143
|
+
string created_at = 8;
|
|
144
|
+
string updated_at = 9;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
message CheckoutResponse {
|
|
148
|
+
string purchase_id = 1;
|
|
149
|
+
string payment_id = 2;
|
|
150
|
+
string confirmation_url = 3; // empty when paid from balance (instant)
|
|
151
|
+
string status = 4; // PENDING (redirect) | COMPLETED (balance)
|
|
152
|
+
string intent_id = 5; // poll via GetPaymentIntent for TOPUP / bind-card flows
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
message GetMyPurchasesRequest { string user_id = 1; int32 page = 2; int32 limit = 3; }
|
|
156
|
+
message PurchasesListResponse { repeated Purchase items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
157
|
+
message GetPurchaseRequest { string id = 1; string user_id = 2; }
|
|
158
|
+
message RefundPurchaseRequest { string purchase_id = 1; string actor_user_id = 2; bool is_admin = 3; string reason = 4; }
|
|
159
|
+
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
// Wallet & statement
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
message GetWalletRequest { string user_id = 1; }
|
|
164
|
+
message WalletResponse {
|
|
165
|
+
string spending = 1;
|
|
166
|
+
string pending = 2;
|
|
167
|
+
string payout = 3;
|
|
168
|
+
string spendable = 4; // spending + payout
|
|
169
|
+
string withdrawable = 5; // payout
|
|
170
|
+
string currency = 6;
|
|
171
|
+
int32 lifetime_sales = 7;
|
|
172
|
+
string current_commission_percent = 8;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
message ListTransactionsRequest {
|
|
176
|
+
string user_id = 1;
|
|
177
|
+
// Legacy low-level filter (one of LedgerTxType). Kept for backward
|
|
178
|
+
// compatibility — admin tooling still uses it directly.
|
|
179
|
+
string type = 2;
|
|
180
|
+
int32 page = 3;
|
|
181
|
+
int32 limit = 4;
|
|
182
|
+
// ↓ added for the wallet statement page (Round 3)
|
|
183
|
+
// UI-semantic filter mapped onto displayKind:
|
|
184
|
+
// ALL | SALES | INCOME | OUTCOME | REFUND | WITHDRAWAL | PREMIUM
|
|
185
|
+
// SALES = the seller's earnings on this account (USER_PENDING credits from
|
|
186
|
+
// PURCHASE transactions); these stay separate from INCOME (TOPUP).
|
|
187
|
+
string flow = 5;
|
|
188
|
+
// Period selection. `month` is the convenience form (YYYY-MM) used by the
|
|
189
|
+
// month dropdown; from/to override it for an arbitrary range.
|
|
190
|
+
string month = 6;
|
|
191
|
+
string from = 7;
|
|
192
|
+
string to = 8;
|
|
193
|
+
// Filter wallet to purchases/refunds of a specific Product category. Has
|
|
194
|
+
// no effect on TOPUP/WITHDRAWAL/PREMIUM/ADJUSTMENT entries (they have no
|
|
195
|
+
// product).
|
|
196
|
+
string product_category_id = 9;
|
|
197
|
+
// sort_by ∈ { date | amount | type }. Default: date.
|
|
198
|
+
string sort_by = 10;
|
|
199
|
+
// order ∈ { asc | desc }. Default: desc.
|
|
200
|
+
string order = 11;
|
|
201
|
+
}
|
|
202
|
+
message StatementEntry {
|
|
203
|
+
string id = 1;
|
|
204
|
+
string tx_id = 2;
|
|
205
|
+
string type = 3; // raw tx type (TOPUP|PURCHASE|...)
|
|
206
|
+
string account_kind = 4;
|
|
207
|
+
string direction = 5; // DEBIT | CREDIT
|
|
208
|
+
string amount = 6;
|
|
209
|
+
string description = 7;
|
|
210
|
+
string created_at = 8;
|
|
211
|
+
// ↓ added for the wallet statement page (Round 3)
|
|
212
|
+
// UI-friendly classification computed server-side:
|
|
213
|
+
// TOPUP | PURCHASE | SALE | REFUND | PREMIUM | WITHDRAWAL | ADJUSTMENT
|
|
214
|
+
// SALE is the seller's view of someone else's PURCHASE (CREDIT to their
|
|
215
|
+
// USER_PENDING) — distinct from PURCHASE which is the buyer's DEBIT.
|
|
216
|
+
// PREMIUM is split out of PURCHASE/REFUND so the UI can show
|
|
217
|
+
// "Продление Premium" / refund-of-premium in their own filter bucket.
|
|
218
|
+
// SALE_CLEAR transactions are excluded from the wallet view — the maturity
|
|
219
|
+
// event is surfaced via sale_status on the original SALE row instead.
|
|
220
|
+
string display_kind = 9;
|
|
221
|
+
string balance_after = 10; // affected-account running balance, Decimal-as-string
|
|
222
|
+
string product_id = 11; // empty for non-product entries
|
|
223
|
+
string product_name = 12;
|
|
224
|
+
string product_category = 13; // "Assets" | "Project File" | "Templates"
|
|
225
|
+
string product_preview = 14; // optional thumbnail URL for richer rows
|
|
226
|
+
// Sale lifecycle. Populated only when display_kind=SALE.
|
|
227
|
+
// PENDING — held in USER_PENDING, not yet withdrawable.
|
|
228
|
+
// MATURED — SALE_CLEAR has fired; money is in USER_PAYOUT.
|
|
229
|
+
string sale_status = 15;
|
|
230
|
+
// ISO 8601 when the sale becomes withdrawable (sale_completed_at +
|
|
231
|
+
// GRACE_DAYS). Empty for non-sale rows.
|
|
232
|
+
string matures_at = 16;
|
|
233
|
+
}
|
|
234
|
+
message TransactionsListResponse { repeated StatementEntry items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
235
|
+
|
|
236
|
+
message GetTransactionMonthsRequest { string user_id = 1; }
|
|
237
|
+
message GetTransactionMonthsResponse {
|
|
238
|
+
// Newest first. "YYYY-MM" strings; the dropdown renders them
|
|
239
|
+
// localized client-side.
|
|
240
|
+
repeated string months = 1;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
// Withdrawals
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
message Withdrawal {
|
|
247
|
+
string id = 1;
|
|
248
|
+
string seller_id = 2;
|
|
249
|
+
string amount = 3;
|
|
250
|
+
string status = 4; // PENDING | PROCESSING | COMPLETED | REJECTED
|
|
251
|
+
string method = 5;
|
|
252
|
+
string details = 6;
|
|
253
|
+
string comment = 7;
|
|
254
|
+
string processed_by = 8;
|
|
255
|
+
string processed_at = 9;
|
|
256
|
+
string created_at = 10;
|
|
257
|
+
}
|
|
258
|
+
message RequestWithdrawalRequest { string seller_id = 1; string amount = 2; string method = 3; string details = 4; }
|
|
259
|
+
message ListWithdrawalsRequest { string seller_id = 1; string status = 2; int32 page = 3; int32 limit = 4; }
|
|
260
|
+
message WithdrawalsListResponse { repeated Withdrawal items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
261
|
+
message ProcessWithdrawalRequest { string withdrawal_id = 1; string admin_id = 2; string action = 3; string comment = 4; }
|
|
262
|
+
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
// Webhook
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
message PaymentEventRequest { string event = 1; string payment_id = 2; }
|
|
267
|
+
|
|
268
|
+
message ProviderCallbackRequest {
|
|
269
|
+
string provider = 1; // yookassa | heleket | …
|
|
270
|
+
string raw_body = 2; // exact raw JSON body as received (signature input)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
// FX rates / payment methods
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
message GetRatesRequest {}
|
|
277
|
+
|
|
278
|
+
message FxRate {
|
|
279
|
+
string currency = 1; // USD | EUR
|
|
280
|
+
string rate = 2; // RUB per 1 unit, Decimal as string
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
message GetRatesResponse {
|
|
284
|
+
string base = 1; // always RUB
|
|
285
|
+
string as_of = 2; // YYYY-MM-DD the rates are for
|
|
286
|
+
repeated FxRate rates = 3;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
message GetPaymentMethodsRequest {}
|
|
290
|
+
|
|
291
|
+
message PaymentMethodInfo {
|
|
292
|
+
string method = 1; // YOOKASSA | SAVED_CARD | CRYPTO | BALANCE
|
|
293
|
+
string provider = 2; // yookassa | heleket | '' (BALANCE)
|
|
294
|
+
repeated string currencies = 3;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
message GetPaymentMethodsResponse {
|
|
298
|
+
repeated PaymentMethodInfo methods = 1;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// Admin
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
message AdminOverviewRequest { string from = 1; string to = 2; }
|
|
305
|
+
message AdminOverviewResponse {
|
|
306
|
+
string revenue = 1; // platform commission earned (period)
|
|
307
|
+
string gmv = 2; // gross merchandise value (period)
|
|
308
|
+
string liabilities = 3; // Σ all users' (pending+payout+spending) — what we owe
|
|
309
|
+
string psp_clearing = 4; // money in transit at PSP
|
|
310
|
+
string payouts_payable = 5; // reserved for approved withdrawals
|
|
311
|
+
string refunds_total = 6;
|
|
312
|
+
string topups_total = 7;
|
|
313
|
+
string withdrawals_total = 8;
|
|
314
|
+
int32 sales_count = 9;
|
|
315
|
+
string currency = 10;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
message AdminListTransactionsRequest {
|
|
319
|
+
string type = 1;
|
|
320
|
+
string user_id = 2;
|
|
321
|
+
string account_kind = 3;
|
|
322
|
+
string from = 4;
|
|
323
|
+
string to = 5;
|
|
324
|
+
int32 page = 6;
|
|
325
|
+
int32 limit = 7;
|
|
326
|
+
}
|
|
327
|
+
message AdminEntry { string account_id = 1; string account_kind = 2; string owner_id = 3; string direction = 4; string amount = 5; }
|
|
328
|
+
message AdminLedgerTx {
|
|
329
|
+
string id = 1;
|
|
330
|
+
string type = 2;
|
|
331
|
+
string status = 3;
|
|
332
|
+
string ref_type = 4;
|
|
333
|
+
string ref_id = 5;
|
|
334
|
+
string description = 6;
|
|
335
|
+
string created_by = 7;
|
|
336
|
+
string created_at = 8;
|
|
337
|
+
repeated AdminEntry entries = 9;
|
|
338
|
+
}
|
|
339
|
+
message AdminTransactionsListResponse { repeated AdminLedgerTx items = 1; int32 total = 2; int32 page = 3; int32 limit = 4; }
|
|
340
|
+
|
|
341
|
+
message GetUserFinanceRequest { string user_id = 1; }
|
|
342
|
+
message AccountBalance { string kind = 1; string balance = 2; string currency = 3; }
|
|
343
|
+
message UserFinanceResponse {
|
|
344
|
+
WalletResponse wallet = 1;
|
|
345
|
+
repeated AccountBalance accounts = 2;
|
|
346
|
+
repeated StatementEntry recent = 3;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
message CreateAdjustmentRequest {
|
|
350
|
+
string admin_id = 1;
|
|
351
|
+
string user_id = 2;
|
|
352
|
+
string account_kind = 3; // USER_SPENDING | USER_PAYOUT | USER_PENDING
|
|
353
|
+
string direction = 4; // CREDIT (give) | DEBIT (take)
|
|
354
|
+
string amount = 5;
|
|
355
|
+
string reason = 6;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
message SalesAnalyticsRequest { string from = 1; string to = 2; string granularity = 3; } // day|week|month
|
|
359
|
+
message SalesPoint { string date = 1; int32 sales_count = 2; string gmv = 3; string revenue = 4; }
|
|
360
|
+
message SellerStat { string seller_id = 1; string username = 2; int32 sales = 3; string gmv = 4; }
|
|
361
|
+
message SalesAnalyticsResponse {
|
|
362
|
+
repeated SalesPoint points = 1;
|
|
363
|
+
repeated SellerStat top_sellers = 2;
|
|
364
|
+
string refund_rate = 3; // % refunded purchases
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ---------------------------------------------------------------------------
|
|
368
|
+
// Premium
|
|
369
|
+
// ---------------------------------------------------------------------------
|
|
370
|
+
message GetPremiumPlansRequest {}
|
|
371
|
+
|
|
372
|
+
// One plan per (period). Prices are computed server-side from BASE_PRICE × months
|
|
373
|
+
// × (1 − discount); kept here as canonical strings so the gateway has no math.
|
|
374
|
+
message PremiumPlan {
|
|
375
|
+
string period = 1; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
376
|
+
int32 months = 2;
|
|
377
|
+
string price = 3; // total to charge, Decimal-as-string
|
|
378
|
+
string monthly_price = 4; // for UI "≈ X ₽/month"
|
|
379
|
+
string discount_percent = 5;
|
|
380
|
+
string currency = 6;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
message PremiumPlansResponse {
|
|
384
|
+
repeated PremiumPlan plans = 1;
|
|
385
|
+
string base_monthly_price = 2;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
message PurchasePremiumRequest {
|
|
389
|
+
string user_id = 1;
|
|
390
|
+
string period = 2; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
391
|
+
string payment_method = 3; // BALANCE | YOOKASSA | SAVED_CARD (empty = smart default)
|
|
392
|
+
string return_url = 4; // YooKassa only
|
|
393
|
+
// Save the YooKassa payment_method for future auto-renewals. Ignored for
|
|
394
|
+
// BALANCE. Kept for backwards compatibility; auto_renew=true implies save.
|
|
395
|
+
bool save_payment_method = 5;
|
|
396
|
+
bool auto_renew = 6; // default false; requires off-session-capable method
|
|
397
|
+
string saved_card_id = 7; // optional for SAVED_CARD; empty = default card
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
message PurchasePremiumResponse {
|
|
401
|
+
string payment_id = 1; // PremiumPayment.id
|
|
402
|
+
string confirmation_url = 2; // empty for BALANCE (instant) or YooKassa-issued
|
|
403
|
+
string status = 3; // PENDING (redirect) | COMPLETED (balance)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
message RunPremiumRenewalsRequest {
|
|
407
|
+
int32 max_batch = 1; // safety cap; default 100
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
message RunPremiumRenewalsResponse {
|
|
411
|
+
int32 attempted = 1;
|
|
412
|
+
int32 succeeded = 2;
|
|
413
|
+
int32 failed = 3;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
message SetPremiumPaymentMethodRequest {
|
|
417
|
+
string user_id = 1;
|
|
418
|
+
string method = 2; // BALANCE | YOOKASSA | SAVED_CARD
|
|
419
|
+
string saved_card_id = 3; // optional for SAVED_CARD; empty = default card
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
message PremiumPaymentMethodResponse {
|
|
423
|
+
string method = 1; // BALANCE | YOOKASSA | SAVED_CARD
|
|
424
|
+
string saved_card_id = 2; // empty unless SAVED_CARD
|
|
425
|
+
bool auto_renew = 3;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
message PremiumPaymentRow {
|
|
429
|
+
string id = 1;
|
|
430
|
+
string user_id = 2;
|
|
431
|
+
string amount = 3;
|
|
432
|
+
string period = 4; // MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12
|
|
433
|
+
string method = 5; // BALANCE | YOOKASSA
|
|
434
|
+
string status = 6; // PENDING | COMPLETED | FAILED | REFUNDED
|
|
435
|
+
bool is_renewal = 7;
|
|
436
|
+
string created_at = 8;
|
|
437
|
+
string completed_at = 9;
|
|
438
|
+
string refunded_at = 10;
|
|
439
|
+
string refunded_amount = 11;
|
|
440
|
+
// Convenience: true if this payment is currently inside the 7-day refund
|
|
441
|
+
// window AND status == COMPLETED AND not already refunded.
|
|
442
|
+
bool refundable = 12;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
message RefundPremiumRequest {
|
|
446
|
+
string user_id = 1;
|
|
447
|
+
string payment_id = 2;
|
|
448
|
+
string reason = 3; // optional
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
message RefundPremiumResponse {
|
|
452
|
+
PremiumPaymentRow payment = 1;
|
|
453
|
+
string new_expires_at = 2; // ISO 8601 after rollback
|
|
454
|
+
bool subscription_revoked = 3; // true when rollback put expiresAt <= now
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
message GetMyPremiumPaymentsRequest {
|
|
458
|
+
string user_id = 1;
|
|
459
|
+
int32 page = 2;
|
|
460
|
+
int32 limit = 3;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
message GetPremiumPaymentRequest {
|
|
464
|
+
string user_id = 1;
|
|
465
|
+
string payment_id = 2;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
message PremiumPaymentsListResponse {
|
|
469
|
+
repeated PremiumPaymentRow items = 1;
|
|
470
|
+
int32 total = 2;
|
|
471
|
+
int32 page = 3;
|
|
472
|
+
int32 limit = 4;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ---------------------------------------------------------------------------
|
|
476
|
+
// Saved cards (YooKassa payment_method tokens; we never see PAN)
|
|
477
|
+
// ---------------------------------------------------------------------------
|
|
478
|
+
message SavedCard {
|
|
479
|
+
string id = 1;
|
|
480
|
+
string brand = 2; // "MIR" | "VISA" | "MASTERCARD" | ""
|
|
481
|
+
string last4 = 3; // "0000" etc, display-only
|
|
482
|
+
int32 exp_month = 4;
|
|
483
|
+
int32 exp_year = 5;
|
|
484
|
+
bool is_default = 6;
|
|
485
|
+
string nickname = 7; // user-set label
|
|
486
|
+
string created_at = 8;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
message ListSavedCardsRequest { string user_id = 1; }
|
|
490
|
+
message ListSavedCardsResponse { repeated SavedCard items = 1; }
|
|
491
|
+
|
|
492
|
+
message DeleteSavedCardRequest { string user_id = 1; string id = 2; }
|
|
493
|
+
|
|
494
|
+
message SetDefaultSavedCardRequest { string user_id = 1; string id = 2; }
|
|
495
|
+
|
|
496
|
+
message UpdateSavedCardRequest {
|
|
497
|
+
string user_id = 1;
|
|
498
|
+
string id = 2;
|
|
499
|
+
string nickname = 3; // empty = clear
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// ---------------------------------------------------------------------------
|
|
503
|
+
// Payout details (persistent default; per-withdrawal override still allowed)
|
|
504
|
+
// ---------------------------------------------------------------------------
|
|
505
|
+
message UpdatePayoutDetailsRequest {
|
|
506
|
+
string user_id = 1;
|
|
507
|
+
string method = 2; // "card" | "sbp" | "bank" | "" (clear)
|
|
508
|
+
string details = 3; // JSON string — payments-service treats opaquely
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
message UpdatePayoutDetailsResponse {
|
|
512
|
+
string method = 1;
|
|
513
|
+
string details = 2;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
message GetPayoutDetailsRequest { string user_id = 1; }
|