合并最新 master 到作品管理分支
Project CI / Backend tests (pull_request) Failing after 39s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m44s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 3m43s
Project CI / Repository checks (pull_request) Failing after 40s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 5m52s
Project CI / Frontend tests (pull_request) Successful in 3m17s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m12s
Project CI / Native shell tests (pull_request) Successful in 6m41s

This commit is contained in:
2026-10-03 17:34:23 +08:00
105 changed files with 8656 additions and 10 deletions
+10
View File
@@ -2201,6 +2201,7 @@ fn admin_permission_requirement(_method: &Method, path: &str) -> AdminPermission
path if path.starts_with("/admin/api/agc-templates/") => AnyTab(&["agc-templates"]),
"/admin/api/dashboard" => AnyTab(&["dashboard"]),
"/admin/api/overview" => AnyTab(&["overview"]),
"/admin/api/payment/orders" => AnyTab(&["payment-orders"]),
"/admin/api/external-api-keys" => AnyTab(&["tables"]),
"/admin/api/debug/http" => AnyTab(&["debug"]),
"/admin/api/tracking/events" => AnyTab(&["tracking"]),
@@ -2856,6 +2857,15 @@ async fn fetch_admin_dashboard_rows(state: &AppState, sql: &str) -> Result<Vec<V
extract_first_sql_rows(payload)
}
pub(crate) async fn fetch_admin_payment_rows(
state: &AppState,
sql: &str,
) -> Result<Vec<Value>, AppError> {
fetch_admin_dashboard_rows(state, sql)
.await
.map_err(|message| AppError::from_status(StatusCode::BAD_GATEWAY).with_message(message))
}
/// 用户详情累计充值的单次读取上限:单个用户的历史订单远少于该值。
const ADMIN_USER_RECHARGE_SUMMARY_ROW_LIMIT: u32 = 500;
+5
View File
@@ -23,6 +23,7 @@ use crate::{
external_api_auth::ExternalApiPrincipal,
http_error::AppError,
modules,
payment::handle_payment_wechat_notify,
request_context::{RequestContext, attach_request_context, resolve_request_id},
response_headers::propagate_request_id_header,
state::{AppState, BackpressureState},
@@ -71,6 +72,10 @@ pub fn build_router(state: AppState) -> Router {
get(handle_wechat_virtual_payment_message_push_verify)
.post(handle_wechat_virtual_payment_notify),
)
.route(
"/api/payment/wechat/notify",
post(handle_payment_wechat_notify),
)
// HTTP 背压在业务路由外侧快拒绝,避免过载请求继续占用 SpacetimeDB facade 与业务执行资源。
.layer(middleware::from_fn_with_state(
BackpressureState::from_ref(&state),
@@ -8,7 +8,9 @@ use axum::{
response::Response,
};
use serde_json::json;
use spacetime_client::ExternalApiKeyAuthenticateRecordInput;
use spacetime_client::{
ExternalApiKeyAuthenticateRecordInput, PaymentApiKeyAuthenticateRecordInput,
};
use tracing::warn;
use crate::{
@@ -24,6 +26,9 @@ pub struct ExternalApiPrincipal {
owner_user_id: String,
key_id: String,
scopes: Vec<String>,
payment_app_id: Option<String>,
callback_url: Option<String>,
key_hash: String,
}
impl ExternalApiPrincipal {
@@ -33,6 +38,9 @@ impl ExternalApiPrincipal {
owner_user_id: owner_user_id.to_string(),
key_id: "external-api-key-test".to_string(),
scopes: scopes.iter().map(|scope| (*scope).to_string()).collect(),
payment_app_id: None,
callback_url: None,
key_hash: String::new(),
}
}
@@ -44,9 +52,21 @@ impl ExternalApiPrincipal {
self.key_id.as_str()
}
pub fn payment_app_id(&self) -> Option<&str> {
self.payment_app_id.as_deref()
}
pub fn has_scope(&self, scope: &str) -> bool {
self.scopes.iter().any(|item| item == scope)
}
pub fn payment_callback_url(&self) -> Option<&str> {
self.callback_url.as_deref()
}
pub fn payment_key_hash(&self) -> &str {
self.key_hash.as_str()
}
}
pub async fn require_external_api_key(
@@ -60,10 +80,11 @@ pub async fn require_external_api_key(
.map(|context| context.request_id().to_string())
.unwrap_or_else(|| "unknown".to_string());
let raw_key = extract_external_api_bearer(request.headers())?;
let key_hash = hash_external_api_key(raw_key.as_str());
let key = state
.authenticator()
.authenticate_external_api_key(ExternalApiKeyAuthenticateRecordInput {
key_hash: hash_external_api_key(raw_key.as_str()),
key_hash: key_hash.clone(),
used_at_micros: current_utc_micros(),
})
.await
@@ -79,6 +100,55 @@ pub async fn require_external_api_key(
owner_user_id: key.owner_user_id,
key_id: key.key_id,
scopes: key.scopes,
payment_app_id: None,
callback_url: None,
key_hash: String::new(),
};
request.extensions_mut().insert(principal.clone());
let mut response = next.run(request).await;
response.extensions_mut().insert(principal);
Ok(response)
}
pub async fn require_payment_api_key(
State(state): State<ExternalApiAuthState>,
mut request: Request,
next: Next,
) -> Result<Response, AppError> {
let request_id = request
.extensions()
.get::<RequestContext>()
.map(|context| context.request_id().to_string())
.unwrap_or_else(|| "unknown".to_string());
let raw_key = extract_external_api_bearer(request.headers())?;
let key_hash = hash_external_api_key(raw_key.as_str());
let (app, key) = state
.authenticator()
.authenticate_payment_api_key(PaymentApiKeyAuthenticateRecordInput {
key_hash: key_hash.clone(),
used_at_micros: current_utc_micros(),
})
.await
.map_err(|error| {
warn!(
%request_id,
error = %error,
"支付 API Key 校验失败"
);
AppError::from_status(StatusCode::UNAUTHORIZED)
.with_message("支付 API Key 不存在或已失效")
})?;
let scopes = serde_json::from_str::<Vec<String>>(key.scopes_json.as_str()).map_err(|_| {
AppError::from_status(StatusCode::UNAUTHORIZED).with_message("支付 API Key 权限配置无效")
})?;
let principal = ExternalApiPrincipal {
owner_user_id: app.owner_user_id,
key_id: key.key_id,
scopes,
payment_app_id: Some(app.app_id),
callback_url: app.callback_url,
key_hash,
};
request.extensions_mut().insert(principal.clone());
+5
View File
@@ -63,6 +63,9 @@ mod modules;
mod openai_image_generation;
mod password_entry;
mod password_management;
mod payment;
mod payment_admin;
mod payment_webhook;
mod phone_auth;
mod platform_errors;
mod process_metrics;
@@ -694,6 +697,8 @@ fn spawn_common_app_state_background_workers(state: &AppState) {
fn spawn_http_app_state_background_workers(state: &AppState, process_role: ProcessRole) {
spawn_common_app_state_background_workers(state);
crate::payment_webhook::PaymentWebhookWorker::new(state.spacetime_client().clone())
.spawn_worker();
crate::error_reports::spawn_cleanup_worker(state.clone());
if should_start_profile_recharge_expiration_listener(process_role) {
spawn_profile_recharge_expiration_listener(state.clone());
@@ -25,6 +25,7 @@ use crate::{
admin_register_recharge_refund, admin_resolve_recharge_refund_manual_review,
admin_update_wallet_restriction,
},
payment_admin::admin_list_payment_orders,
runtime_profile::{
admin_disable_profile_redeem_code, admin_disable_profile_task_config,
admin_get_profile_wallet_config, admin_list_profile_invite_codes,
@@ -83,6 +84,7 @@ pub fn router(state: AppState) -> Router<AppState> {
),
("/admin/api/me", get(admin_me)),
("/admin/api/overview", get(admin_overview)),
("/admin/api/payment/orders", get(admin_list_payment_orders)),
("/admin/api/dashboard", get(admin_dashboard)),
(
"/admin/api/debug/http",
@@ -7,7 +7,9 @@ use axum::{
use crate::{
editor_project::EDITOR_LAYOUT_REQUEST_BODY_MAX_BYTES,
external_api_auth::{require_external_api_key, require_external_mcp_api_key},
external_api_auth::{
require_external_api_key, require_external_mcp_api_key, require_payment_api_key,
},
external_assets_api::{
confirm_external_asset_object, create_external_direct_upload_ticket,
get_external_asset_read_url,
@@ -33,6 +35,7 @@ use crate::{
download_external_skill_archive, get_external_agent_integration_manifest,
get_external_skill_entry,
},
payment::{create_external_payment_order, get_external_payment_order},
state::AppState,
};
@@ -45,7 +48,8 @@ pub fn router(state: AppState) -> Router<AppState> {
require_external_mcp_api_key,
));
let auth = middleware::from_fn_with_state(state, require_external_api_key);
let auth = middleware::from_fn_with_state(state.clone(), require_external_api_key);
let payment_auth = middleware::from_fn_with_state(state.clone(), require_payment_api_key);
let protected_routes = [
(
"/api/external/v1/assets/direct-upload-tickets",
@@ -157,6 +161,15 @@ pub fn router(state: AppState) -> Router<AppState> {
.fold(Router::new(), |router, (path, methods)| {
router.route(path, methods.route_layer(auth.clone()))
});
let payment_router = Router::new()
.route(
"/api/external/v1/payment/orders",
post(create_external_payment_order).route_layer(payment_auth.clone()),
)
.route(
"/api/external/v1/payment/orders/{order_id}",
get(get_external_payment_order).route_layer(payment_auth),
);
Router::new()
.route("/api/external/v1/openapi.json", get(openapi_json))
@@ -173,6 +186,7 @@ pub fn router(state: AppState) -> Router<AppState> {
get(download_external_skill_archive),
)
.merge(protected_router)
.merge(payment_router)
.merge(mcp_router)
}
@@ -9,6 +9,10 @@ use crate::{
create_external_api_key, ensure_llm_router_api_key, list_external_api_keys,
revoke_external_api_key,
},
payment::{
create_payment_app, get_public_payment_checkout, list_payment_apps, revoke_payment_api_key,
update_payment_app,
},
profile_identity::update_profile_identity,
runtime_profile::{
claim_profile_task_reward, confirm_wechat_profile_recharge_order,
@@ -59,6 +63,29 @@ pub fn router(state: AppState) -> Router<AppState> {
require_bearer_auth,
)),
)
.route(
"/api/profile/payment/apps",
get(list_payment_apps).post(create_payment_app).route_layer(
middleware::from_fn_with_state(state.clone(), require_bearer_auth),
),
)
.route(
"/api/profile/payment/apps/{app_id}",
axum::routing::patch(update_payment_app).route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),
)
.route(
"/api/profile/payment/keys/{key_id}",
axum::routing::delete(revoke_payment_api_key).route_layer(
middleware::from_fn_with_state(state.clone(), require_bearer_auth),
),
)
.route(
"/api/payment/checkout/{checkout_token}",
get(get_public_payment_checkout),
)
.route(
"/api/profile/wallet-ledger",
get(get_profile_wallet_ledger).route_layer(middleware::from_fn_with_state(
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,144 @@
use crate::{
admin::{AuthenticatedAdmin, fetch_admin_payment_rows},
http_error::AppError,
request_context::RequestContext,
state::AppState,
};
use axum::{Extension, Json, extract::State};
use serde::Serialize;
use serde_json::Value;
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminPaymentOrderEntry {
pub order_id: String,
pub app_id: String,
pub owner_user_id: String,
pub merchant_order_id: String,
pub title: String,
pub amount_cents: u64,
pub currency: String,
pub provider: String,
pub provider_trade_no: Option<String>,
pub status: String,
pub created_at: String,
pub expires_at: String,
pub paid_at: Option<String>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminPaymentOrderListResponse {
pub entries: Vec<AdminPaymentOrderEntry>,
pub webhooks: Vec<AdminPaymentWebhookEntry>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminPaymentWebhookEntry {
pub delivery_id: String,
pub order_id: String,
pub app_id: String,
pub callback_url: String,
pub status: String,
pub attempt_count: u32,
pub available_at: String,
pub last_error_message: Option<String>,
pub updated_at: String,
}
pub async fn admin_list_payment_orders(
State(state): State<AppState>,
Extension(_admin): Extension<AuthenticatedAdmin>,
Extension(_request_context): Extension<RequestContext>,
) -> Result<Json<AdminPaymentOrderListResponse>, AppError> {
let rows = fetch_admin_payment_rows(
&state,
"SELECT order_id, app_id, owner_user_id, merchant_order_id, title, amount_cents, currency, provider, provider_trade_no, status, created_at, expires_at, paid_at FROM payment_order ORDER BY created_at DESC LIMIT 200",
)
.await?;
let entries = rows
.into_iter()
.filter_map(parse_payment_order_row)
.collect();
let webhook_rows = fetch_admin_payment_rows(
&state,
"SELECT delivery_id, order_id, app_id, callback_url, status, attempt_count, available_at, last_error_message, updated_at FROM payment_webhook_delivery ORDER BY updated_at DESC LIMIT 200",
)
.await?;
let webhooks = webhook_rows
.into_iter()
.filter_map(parse_payment_webhook_row)
.collect();
Ok(Json(AdminPaymentOrderListResponse { entries, webhooks }))
}
fn parse_payment_webhook_row(row: Value) -> Option<AdminPaymentWebhookEntry> {
let cells = row.as_array()?;
Some(AdminPaymentWebhookEntry {
delivery_id: cell_text(cells.get(0)?)?,
order_id: cell_text(cells.get(1)?)?,
app_id: cell_text(cells.get(2)?)?,
callback_url: cell_text(cells.get(3)?)?,
status: cell_text(cells.get(4)?)?,
attempt_count: cell_u64(cells.get(5)?)? as u32,
available_at: cell_timestamp(cells.get(6)?),
last_error_message: cell_option_text(cells.get(7)?),
updated_at: cell_timestamp(cells.get(8)?),
})
}
fn parse_payment_order_row(row: Value) -> Option<AdminPaymentOrderEntry> {
let cells = row.as_array()?;
Some(AdminPaymentOrderEntry {
order_id: cell_text(cells.get(0)?)?,
app_id: cell_text(cells.get(1)?)?,
owner_user_id: cell_text(cells.get(2)?)?,
merchant_order_id: cell_text(cells.get(3)?)?,
title: cell_text(cells.get(4)?)?,
amount_cents: cell_u64(cells.get(5)?)?,
currency: cell_text(cells.get(6)?)?,
provider: cell_text(cells.get(7)?)?,
provider_trade_no: cell_option_text(cells.get(8)?),
status: cell_text(cells.get(9)?)?,
created_at: cell_timestamp(cells.get(10)?),
expires_at: cell_timestamp(cells.get(11)?),
paid_at: cell_option_timestamp(cells.get(12)?),
})
}
fn cell_text(value: &Value) -> Option<String> {
match value {
Value::String(text) => Some(text.clone()),
Value::Number(number) => Some(number.to_string()),
Value::Array(values) if values.len() == 2 => cell_text(values.get(1)?),
Value::Array(values) if values.len() == 1 => cell_text(values.first()?),
Value::Object(object) if object.len() == 1 => cell_text(object.values().next()?),
_ => Some(value.to_string()),
}
}
fn cell_option_text(value: &Value) -> Option<String> {
if matches!(value, Value::Array(values) if values.first().and_then(Value::as_u64) == Some(1)) {
return None;
}
cell_text(value).filter(|text| !text.is_empty() && text != "null")
}
fn cell_u64(value: &Value) -> Option<u64> {
cell_text(value)?.parse().ok()
}
fn cell_timestamp(value: &Value) -> String {
cell_text(value)
.and_then(|text| text.parse::<i64>().ok())
.map(module_runtime::format_utc_micros)
.unwrap_or_else(|| "-".to_string())
}
fn cell_option_timestamp(value: &Value) -> Option<String> {
if matches!(value, Value::Array(values) if values.first().and_then(Value::as_u64) == Some(1)) {
return None;
}
Some(cell_timestamp(value))
}
@@ -0,0 +1,135 @@
use std::sync::Arc;
use std::time::Duration;
use reqwest::header::{CONTENT_TYPE, HeaderName, HeaderValue};
use spacetime_client::{
PaymentWebhookClaimRecordInput, PaymentWebhookCompleteRecordInput,
PaymentWebhookDeliveryRecord, SpacetimeClient,
};
use tokio::time::sleep;
use tracing::{debug, warn};
use crate::editor_project::current_utc_micros;
const PAYMENT_WEBHOOK_WORKER_ID: &str = "api-server-payment-webhook";
const PAYMENT_WEBHOOK_BATCH_SIZE: u32 = 20;
const PAYMENT_WEBHOOK_INTERVAL: Duration = Duration::from_secs(5);
const PAYMENT_WEBHOOK_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
#[derive(Clone)]
pub struct PaymentWebhookWorker {
spacetime_client: SpacetimeClient,
http_client: reqwest::Client,
}
impl PaymentWebhookWorker {
pub fn new(spacetime_client: SpacetimeClient) -> Arc<Self> {
Arc::new(Self {
spacetime_client,
http_client: reqwest::Client::builder()
.connect_timeout(Duration::from_secs(3))
.timeout(PAYMENT_WEBHOOK_REQUEST_TIMEOUT)
.build()
.expect("payment webhook client should build"),
})
}
pub fn spawn_worker(self: Arc<Self>) {
tokio::spawn(async move {
loop {
if let Err(error) = self.process_once().await {
warn!(error = %error, "支付外部回调 worker 处理失败,将继续重试");
}
sleep(PAYMENT_WEBHOOK_INTERVAL).await;
}
});
}
async fn process_once(&self) -> Result<(), String> {
let now_micros = current_utc_micros();
let lease_expires_at_micros = now_micros.saturating_add(60_000_000);
let deliveries = self
.spacetime_client
.claim_payment_webhooks(PaymentWebhookClaimRecordInput {
worker_id: PAYMENT_WEBHOOK_WORKER_ID.to_string(),
limit: PAYMENT_WEBHOOK_BATCH_SIZE,
now_micros,
lease_expires_at_micros,
})
.await
.map_err(|error| error.to_string())?;
for delivery in deliveries {
self.deliver_one(delivery).await;
}
Ok(())
}
async fn deliver_one(&self, delivery: PaymentWebhookDeliveryRecord) {
let result = self
.http_client
.post(&delivery.callback_url)
.header(CONTENT_TYPE, "application/json")
.header(
HeaderName::from_static("x-genarrative-signature"),
HeaderValue::from_str(delivery.signature.as_str())
.unwrap_or_else(|_| HeaderValue::from_static("invalid")),
)
.header(
HeaderName::from_static("x-genarrative-event"),
"payment.paid",
)
.header(
HeaderName::from_static("x-genarrative-delivery-id"),
delivery.delivery_id.as_str(),
)
.body(delivery.payload_json.clone())
.send()
.await;
let (success, error_message) = match result {
Ok(response) if response.status().is_success() => (true, None),
Ok(response) => (
false,
Some(format!("callback HTTP {}", response.status().as_u16())),
),
Err(error) => (false, Some(format!("callback request failed: {error}"))),
};
let now_micros = current_utc_micros();
let next_available_at_micros = if success {
now_micros
} else {
let delay_seconds = 2_i64
.saturating_pow(delivery.attempt_count.min(7))
.saturating_mul(5)
.min(300);
now_micros.saturating_add(delay_seconds.saturating_mul(1_000_000))
};
if let Err(error) = self
.spacetime_client
.complete_payment_webhook(PaymentWebhookCompleteRecordInput {
delivery_id: delivery.delivery_id.clone(),
worker_id: PAYMENT_WEBHOOK_WORKER_ID.to_string(),
success,
error_message,
now_micros,
next_available_at_micros,
attempt_count: delivery.attempt_count,
})
.await
{
warn!(
delivery_id = %delivery.delivery_id,
error = %error,
"支付外部回调结果写回失败"
);
} else {
debug!(
delivery_id = %delivery.delivery_id,
success,
attempt_count = delivery.attempt_count,
"支付外部回调处理完成"
);
}
}
}
@@ -3,7 +3,8 @@ use std::sync::Arc;
use axum::extract::FromRef;
use futures_util::future::BoxFuture;
use spacetime_client::{
ExternalApiKeyAuthenticateRecordInput, ExternalApiKeyRecord, SpacetimeClient,
ExternalApiKeyAuthenticateRecordInput, ExternalApiKeyRecord,
PaymentApiKeyAuthenticateRecordInput, PaymentApiKeyRecord, PaymentAppRecord, SpacetimeClient,
SpacetimeClientError,
};
@@ -14,6 +15,17 @@ pub(crate) trait ExternalApiKeyAuthenticator: Send + Sync {
&self,
input: ExternalApiKeyAuthenticateRecordInput,
) -> BoxFuture<'_, Result<ExternalApiKeyRecord, SpacetimeClientError>>;
fn authenticate_payment_api_key(
&self,
_input: PaymentApiKeyAuthenticateRecordInput,
) -> BoxFuture<'_, Result<(PaymentAppRecord, PaymentApiKeyRecord), SpacetimeClientError>> {
Box::pin(async {
Err(SpacetimeClientError::Procedure(
"支付 API Key 认证未配置".to_string(),
))
})
}
}
impl ExternalApiKeyAuthenticator for SpacetimeClient {
@@ -23,6 +35,13 @@ impl ExternalApiKeyAuthenticator for SpacetimeClient {
) -> BoxFuture<'_, Result<ExternalApiKeyRecord, SpacetimeClientError>> {
Box::pin(SpacetimeClient::authenticate_external_api_key(self, input))
}
fn authenticate_payment_api_key(
&self,
input: PaymentApiKeyAuthenticateRecordInput,
) -> BoxFuture<'_, Result<(PaymentAppRecord, PaymentApiKeyRecord), SpacetimeClientError>> {
Box::pin(SpacetimeClient::authenticate_payment_api_key(self, input))
}
}
#[derive(Clone)]
@@ -1089,6 +1089,23 @@ pub fn build_wechat_web_payment_request(
description: format!("陶泥儿 - {product_title}"),
amount_cents,
payer_client_ip,
notify_url: None,
}
}
pub fn build_wechat_payment_service_order_request(
order_id: String,
product_title: String,
amount_cents: u64,
payer_client_ip: String,
notify_url: String,
) -> WechatWebOrderRequest {
WechatWebOrderRequest {
order_id,
description: format!("陶泥儿 - {product_title}"),
amount_cents,
payer_client_ip,
notify_url: Some(notify_url),
}
}
@@ -2,6 +2,8 @@ pub mod agc_analytics;
mod agc_models;
mod llm_billing;
pub use llm_billing::*;
mod payment;
pub use payment::*;
mod application;
pub use agc_models::*;
mod commands;
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -192,6 +192,7 @@ pub struct WechatWebOrderRequest {
pub description: String,
pub amount_cents: u64,
pub payer_client_ip: String,
pub notify_url: Option<String>,
}
#[derive(Clone, Debug)]
@@ -985,7 +986,7 @@ impl RealWechatPayClient {
description: &request.description,
out_trade_no: &request.order_id,
time_expire: &expires_at_text,
notify_url: &self.notify_url,
notify_url: request.notify_url.as_deref().unwrap_or(&self.notify_url),
amount: WechatJsapiAmount {
total: amount_total,
currency: "CNY",
@@ -1040,7 +1041,7 @@ impl RealWechatPayClient {
description: &request.description,
out_trade_no: &request.order_id,
time_expire: &expires_at_text,
notify_url: &self.notify_url,
notify_url: request.notify_url.as_deref().unwrap_or(&self.notify_url),
amount: WechatJsapiAmount {
total: amount_total,
currency: "CNY",
@@ -23,4 +23,5 @@ pub mod game_creation_app;
pub mod game_distribution;
pub mod hyper3d;
pub mod llm;
pub mod payment;
pub mod runtime;
@@ -0,0 +1,106 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentAppCreateRequest {
pub name: String,
#[serde(default)]
pub callback_url: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentAppResponse {
pub app_id: String,
pub name: String,
pub callback_url: Option<String>,
pub enabled: bool,
pub created_at: String,
pub updated_at: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentApiKeyResponse {
pub key_id: String,
pub app_id: String,
pub name: String,
pub key_prefix: String,
pub scopes: Vec<String>,
pub created_at: String,
pub last_used_at: Option<String>,
pub revoked_at: Option<String>,
pub updated_at: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentAppCreateResponse {
pub app: PaymentAppResponse,
pub api_key: String,
pub key: PaymentApiKeyResponse,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentAppListResponse {
pub apps: Vec<PaymentAppResponse>,
pub keys: Vec<PaymentApiKeyResponse>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentOrderCreateRequest {
pub merchant_order_id: String,
pub title: String,
#[serde(default)]
pub items: Vec<Value>,
pub amount_cents: u64,
#[serde(default = "default_payment_currency")]
pub currency: String,
#[serde(default = "default_payment_provider")]
pub provider: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentOrderResponse {
pub order_id: String,
pub app_id: String,
pub merchant_order_id: String,
pub title: String,
pub items: Vec<Value>,
pub amount_cents: u64,
pub currency: String,
pub provider: String,
pub provider_trade_no: Option<String>,
pub checkout_token: String,
pub status: String,
pub checkout_url: String,
pub provider_qr_code: Option<String>,
pub created_at: String,
pub expires_at: String,
pub paid_at: Option<String>,
pub updated_at: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentOrderCreateResponse {
pub order: PaymentOrderResponse,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PaymentOrderListResponse {
pub orders: Vec<PaymentOrderResponse>,
}
pub fn default_payment_currency() -> String {
"CNY".to_string()
}
pub fn default_payment_provider() -> String {
"wechat_native".to_string()
}
@@ -36,6 +36,8 @@ pub use game_distribution::{
#[path = "active/external_generation.rs"]
pub mod external_generation;
pub mod llm_router_account;
#[path = "active/payment.rs"]
pub mod payment;
pub use external_generation::{
ExternalGenerationJobPhaseUpdateError, ExternalGenerationQueueWakeSubscription,
};
@@ -24,6 +24,8 @@ mod external_generation;
mod game_distribution;
#[path = "mapper/llm_router_account.rs"]
pub(crate) mod llm_router_account;
#[path = "mapper/payment.rs"]
mod payment;
#[path = "mapper/runtime.rs"]
mod runtime;
#[path = "mapper/runtime_profile.rs"]
@@ -103,6 +105,15 @@ pub use self::game_distribution::{
GameDistributionVersionRecord,
};
pub use self::llm_router_account::{LlmRouterAccountRecord, LlmRouterAccountUpsertRecordInput};
pub use self::payment::{
PaymentApiKeyAuthenticateRecordInput, PaymentApiKeyCreateRecordInput, PaymentApiKeyRecord,
PaymentApiKeyRevokeRecordInput, PaymentAppCreateRecordInput, PaymentAppRecord,
PaymentAppUpdateRecordInput, PaymentOrderCreateRecordInput, PaymentOrderGetRecordInput,
PaymentOrderListRecordInput, PaymentOrderMarkPaidRecordInput,
PaymentOrderProviderAttemptRecordInput, PaymentOrderProviderCodeRecordInput,
PaymentOrderRecord, PaymentWebhookClaimRecordInput, PaymentWebhookCompleteRecordInput,
PaymentWebhookDeliveryRecord, PaymentWebhookEnqueueRecordInput,
};
pub use self::runtime::FeatureGateConfigRecord;
pub(crate) use self::admin_account::{
@@ -161,6 +172,12 @@ pub(crate) use self::game_distribution::{
map_game_distribution_public_game_result, map_game_distribution_review_list_result,
map_game_distribution_version_result, map_review_moderation_operation, map_user_review,
};
pub(crate) use self::payment::{
map_payment_api_key_list_result, map_payment_api_key_result, map_payment_app_list_result,
map_payment_app_result, map_payment_authenticate_result, map_payment_order_list_result,
map_payment_order_result, map_payment_webhook_claim_result,
map_payment_webhook_complete_result, map_payment_webhook_enqueue_result,
};
pub(crate) use self::runtime::{
map_feature_gate_config_procedure_result, map_runtime_setting_procedure_result,
map_runtime_tracking_event_batch_procedure_result, map_runtime_tracking_event_procedure_result,
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,324 @@
use super::*;
impl SpacetimeClient {
pub async fn create_payment_app(
&self,
input: PaymentAppCreateRecordInput,
) -> Result<PaymentAppRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("create_payment_app", move |connection, sender| {
connection
.procedures()
.create_payment_app_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_app_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn list_payment_apps(
&self,
owner_user_id: String,
) -> Result<Vec<PaymentAppRecord>, SpacetimeClientError> {
let input = PaymentAppListInput { owner_user_id };
self.call_after_connect("list_payment_apps", move |connection, sender| {
connection
.procedures()
.list_payment_apps_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_app_list_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn update_payment_app(
&self,
input: PaymentAppUpdateRecordInput,
) -> Result<PaymentAppRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("update_payment_app", move |connection, sender| {
connection
.procedures()
.update_payment_app_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_app_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn list_payment_api_keys(
&self,
owner_user_id: String,
) -> Result<Vec<PaymentApiKeyRecord>, SpacetimeClientError> {
let input = PaymentApiKeyListInput { owner_user_id };
self.call_after_connect("list_payment_api_keys", move |connection, sender| {
connection
.procedures()
.list_payment_api_keys_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_api_key_list_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn create_payment_api_key(
&self,
input: PaymentApiKeyCreateRecordInput,
) -> Result<PaymentApiKeyRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("create_payment_api_key", move |connection, sender| {
connection
.procedures()
.create_payment_api_key_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_api_key_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn revoke_payment_api_key(
&self,
input: PaymentApiKeyRevokeRecordInput,
) -> Result<PaymentApiKeyRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("revoke_payment_api_key", move |connection, sender| {
connection
.procedures()
.revoke_payment_api_key_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_api_key_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn authenticate_payment_api_key(
&self,
input: PaymentApiKeyAuthenticateRecordInput,
) -> Result<(PaymentAppRecord, PaymentApiKeyRecord), SpacetimeClientError> {
let input = input.into();
self.call_after_connect("authenticate_payment_api_key", move |connection, sender| {
connection
.procedures()
.authenticate_payment_api_key_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_authenticate_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn create_payment_order(
&self,
input: PaymentOrderCreateRecordInput,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("create_payment_order", move |connection, sender| {
connection
.procedures()
.create_payment_order_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn get_payment_order(
&self,
input: PaymentOrderGetRecordInput,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("get_payment_order", move |connection, sender| {
connection
.procedures()
.get_payment_order_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn get_payment_order_by_checkout_token(
&self,
checkout_token: String,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = PaymentOrderCheckoutGetInput { checkout_token };
self.call_after_connect(
"get_payment_order_by_checkout_token",
move |connection, sender| {
connection
.procedures()
.get_payment_order_by_checkout_token_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn list_payment_orders(
&self,
input: PaymentOrderListRecordInput,
) -> Result<Vec<PaymentOrderRecord>, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("list_payment_orders", move |connection, sender| {
connection
.procedures()
.list_payment_orders_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_list_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn mark_payment_order_paid(
&self,
input: PaymentOrderMarkPaidRecordInput,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("mark_payment_order_paid", move |connection, sender| {
connection
.procedures()
.mark_payment_order_paid_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn set_payment_order_provider_code(
&self,
input: PaymentOrderProviderCodeRecordInput,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect(
"set_payment_order_provider_code",
move |connection, sender| {
connection
.procedures()
.set_payment_order_provider_code_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
});
},
)
.await
}
pub async fn mark_payment_order_provider_attempted(
&self,
input: PaymentOrderProviderAttemptRecordInput,
) -> Result<PaymentOrderRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect(
"mark_payment_order_provider_attempted",
move |connection, sender| {
connection
.procedures()
.mark_payment_order_provider_attempted_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_order_result);
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn enqueue_payment_webhook(
&self,
input: PaymentWebhookEnqueueRecordInput,
) -> Result<Option<PaymentWebhookDeliveryRecord>, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("enqueue_payment_webhook", move |connection, sender| {
connection
.procedures()
.enqueue_payment_webhook_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_webhook_enqueue_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn claim_payment_webhooks(
&self,
input: PaymentWebhookClaimRecordInput,
) -> Result<Vec<PaymentWebhookDeliveryRecord>, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("claim_payment_webhooks", move |connection, sender| {
connection
.procedures()
.claim_payment_webhooks_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_webhook_claim_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn complete_payment_webhook(
&self,
input: PaymentWebhookCompleteRecordInput,
) -> Result<PaymentWebhookDeliveryRecord, SpacetimeClientError> {
let input = input.into();
self.call_after_connect("complete_payment_webhook", move |connection, sender| {
connection
.procedures()
.complete_payment_webhook_and_return_then(input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_payment_webhook_complete_result);
send_once(&sender, mapped);
});
})
.await
}
}
@@ -134,6 +134,7 @@ pub mod auth_store_projection_user_type;
pub mod auth_store_projection_view_type;
pub mod auth_store_projection_wechat_state_type;
pub mod authenticate_external_api_key_and_return_procedure;
pub mod authenticate_payment_api_key_and_return_procedure;
pub mod authorize_database_migration_operator_procedure;
pub mod backfill_editor_canvas_layout_and_return_procedure;
pub mod backfill_external_generation_job_summaries_and_return_procedure;
@@ -142,6 +143,7 @@ pub mod bind_asset_object_to_entity_reducer;
pub mod cancel_ai_task_and_return_procedure;
pub mod cancel_game_distribution_version_and_return_procedure;
pub mod claim_external_generation_jobs_and_return_procedure;
pub mod claim_payment_webhooks_and_return_procedure;
pub mod claim_profile_recharge_order_expiration_schedule_and_return_procedure;
pub mod claim_profile_task_reward_and_return_procedure;
pub mod clean_editor_image_asset_kind_and_return_procedure;
@@ -152,6 +154,7 @@ pub mod complete_ai_stage_and_return_procedure;
pub mod complete_ai_task_and_return_procedure;
pub mod complete_editor_asset_group_cohort_and_return_procedure;
pub mod complete_external_generation_job_and_return_procedure;
pub mod complete_payment_webhook_and_return_procedure;
pub mod complete_profile_recharge_order_expiration_schedule_and_return_procedure;
pub mod confirm_asset_object_and_return_procedure;
pub mod confirm_asset_object_reducer;
@@ -169,6 +172,9 @@ pub mod create_error_report_and_return_procedure;
pub mod create_external_api_key_and_return_procedure;
pub mod create_game_distribution_game_and_return_procedure;
pub mod create_game_distribution_version_and_return_procedure;
pub mod create_payment_api_key_and_return_procedure;
pub mod create_payment_app_and_return_procedure;
pub mod create_payment_order_and_return_procedure;
pub mod create_profile_recharge_order_and_return_procedure;
pub mod creation_entry_config_table;
pub mod creation_entry_config_type;
@@ -338,6 +344,7 @@ pub mod editor_spritesheet_slice_batch_persist_result_type;
pub mod editor_spritesheet_slice_persist_item_input_type;
pub mod editor_spritesheet_slice_persisted_item_type;
pub mod enqueue_external_generation_job_and_return_procedure;
pub mod enqueue_payment_webhook_and_return_procedure;
pub mod enqueue_profile_wallet_refund_outbox_and_return_procedure;
pub mod ensure_analytics_date_dimension_for_date_reducer;
pub mod error_report_create_input_type;
@@ -480,6 +487,8 @@ pub mod get_game_distribution_my_review_and_return_procedure;
pub mod get_game_distribution_version_and_return_procedure;
pub mod get_llm_router_account_and_return_procedure;
pub mod get_owner_game_distribution_version_and_return_procedure;
pub mod get_payment_order_and_return_procedure;
pub mod get_payment_order_by_checkout_token_and_return_procedure;
pub mod get_profile_dashboard_procedure;
pub mod get_profile_recharge_center_procedure;
pub mod get_profile_recharge_order_and_return_procedure;
@@ -512,6 +521,9 @@ pub mod list_game_distribution_review_games_and_return_procedure;
pub mod list_game_distribution_reviews_and_return_procedure;
pub mod list_game_distribution_user_reviews_and_return_procedure;
pub mod list_owner_game_distribution_games_and_return_procedure;
pub mod list_payment_api_keys_and_return_procedure;
pub mod list_payment_apps_and_return_procedure;
pub mod list_payment_orders_and_return_procedure;
pub mod list_profile_recharge_refund_holds_for_reconciliation_procedure;
pub mod list_profile_recharge_refunds_for_reconciliation_procedure;
pub mod list_profile_wallet_ledger_procedure;
@@ -531,10 +543,46 @@ pub mod llm_router_billing_checkpoint_type;
pub mod llm_router_quota_settlement_input_type;
pub mod llm_router_quota_settlement_result_type;
pub mod mark_editor_showcase_asset_refunded_and_return_procedure;
pub mod mark_payment_order_paid_and_return_procedure;
pub mod mark_payment_order_provider_attempted_and_return_procedure;
pub mod mark_profile_recharge_order_expiration_checked_procedure;
pub mod mark_profile_recharge_order_paid_and_return_procedure;
pub mod moderate_game_distribution_user_review_and_return_procedure;
pub mod normalize_editor_character_animation_metadata_and_return_procedure;
pub mod payment_api_key_authenticate_input_type;
pub mod payment_api_key_create_input_type;
pub mod payment_api_key_list_input_type;
pub mod payment_api_key_revoke_input_type;
pub mod payment_api_key_snapshot_type;
pub mod payment_api_key_table;
pub mod payment_api_key_type;
pub mod payment_app_create_input_type;
pub mod payment_app_list_input_type;
pub mod payment_app_procedure_result_type;
pub mod payment_app_snapshot_type;
pub mod payment_app_table;
pub mod payment_app_type;
pub mod payment_app_update_input_type;
pub mod payment_order_checkout_get_input_type;
pub mod payment_order_create_input_type;
pub mod payment_order_get_input_type;
pub mod payment_order_list_input_type;
pub mod payment_order_mark_paid_input_type;
pub mod payment_order_procedure_result_type;
pub mod payment_order_provider_attempt_input_type;
pub mod payment_order_provider_code_input_type;
pub mod payment_order_snapshot_type;
pub mod payment_order_status_type;
pub mod payment_order_table;
pub mod payment_order_type;
pub mod payment_provider_type;
pub mod payment_webhook_claim_input_type;
pub mod payment_webhook_complete_input_type;
pub mod payment_webhook_delivery_snapshot_type;
pub mod payment_webhook_delivery_table;
pub mod payment_webhook_delivery_type;
pub mod payment_webhook_enqueue_input_type;
pub mod payment_webhook_procedure_result_type;
pub mod persist_editor_generation_result_and_return_procedure;
pub mod persist_editor_pixel_art_result_and_return_procedure;
pub mod persist_editor_spritesheet_slice_batch_and_return_procedure;
@@ -628,6 +676,7 @@ pub mod resolve_profile_recharge_refund_manual_review_and_return_procedure;
pub mod restore_game_distribution_game_and_return_procedure;
pub mod revoke_database_migration_operator_procedure;
pub mod revoke_external_api_key_and_return_procedure;
pub mod revoke_payment_api_key_and_return_procedure;
pub mod rollback_editor_canvas_layout_and_return_procedure;
pub mod rotate_editor_generation_runtime_service_identity_and_return_procedure;
pub mod runtime_browse_history_theme_mode_type;
@@ -779,6 +828,7 @@ pub mod save_editor_project_layout_v_2_and_return_procedure;
pub mod save_game_distribution_my_review_and_return_procedure;
pub mod seed_analytics_date_dimensions_reducer;
pub mod set_editor_showcase_asset_like_for_viewer_and_return_procedure;
pub mod set_payment_order_provider_code_and_return_procedure;
pub mod settle_llm_router_quota_and_return_procedure;
pub mod start_ai_task_reducer;
pub mod start_ai_task_stage_reducer;
@@ -801,6 +851,7 @@ pub mod update_editor_showcase_asset_display_and_return_procedure;
pub mod update_error_report_and_return_procedure;
pub mod update_external_generation_job_phase_and_return_procedure;
pub mod update_game_distribution_game_metadata_and_return_procedure;
pub mod update_payment_app_and_return_procedure;
pub mod upload_agc_analytics_batch_procedure;
pub mod upsert_editor_generation_pricing_config_and_return_procedure;
pub mod upsert_editor_showcase_campaign_config_and_return_procedure;
@@ -941,6 +992,7 @@ pub use auth_store_projection_user_type::AuthStoreProjectionUser;
pub use auth_store_projection_view_type::AuthStoreProjectionView;
pub use auth_store_projection_wechat_state_type::AuthStoreProjectionWechatState;
pub use authenticate_external_api_key_and_return_procedure::authenticate_external_api_key_and_return;
pub use authenticate_payment_api_key_and_return_procedure::authenticate_payment_api_key_and_return;
pub use authorize_database_migration_operator_procedure::authorize_database_migration_operator;
pub use backfill_editor_canvas_layout_and_return_procedure::backfill_editor_canvas_layout_and_return;
pub use backfill_external_generation_job_summaries_and_return_procedure::backfill_external_generation_job_summaries_and_return;
@@ -949,6 +1001,7 @@ pub use bind_asset_object_to_entity_reducer::bind_asset_object_to_entity;
pub use cancel_ai_task_and_return_procedure::cancel_ai_task_and_return;
pub use cancel_game_distribution_version_and_return_procedure::cancel_game_distribution_version_and_return;
pub use claim_external_generation_jobs_and_return_procedure::claim_external_generation_jobs_and_return;
pub use claim_payment_webhooks_and_return_procedure::claim_payment_webhooks_and_return;
pub use claim_profile_recharge_order_expiration_schedule_and_return_procedure::claim_profile_recharge_order_expiration_schedule_and_return;
pub use claim_profile_task_reward_and_return_procedure::claim_profile_task_reward_and_return;
pub use clean_editor_image_asset_kind_and_return_procedure::clean_editor_image_asset_kind_and_return;
@@ -959,6 +1012,7 @@ pub use complete_ai_stage_and_return_procedure::complete_ai_stage_and_return;
pub use complete_ai_task_and_return_procedure::complete_ai_task_and_return;
pub use complete_editor_asset_group_cohort_and_return_procedure::complete_editor_asset_group_cohort_and_return;
pub use complete_external_generation_job_and_return_procedure::complete_external_generation_job_and_return;
pub use complete_payment_webhook_and_return_procedure::complete_payment_webhook_and_return;
pub use complete_profile_recharge_order_expiration_schedule_and_return_procedure::complete_profile_recharge_order_expiration_schedule_and_return;
pub use confirm_asset_object_and_return_procedure::confirm_asset_object_and_return;
pub use confirm_asset_object_reducer::confirm_asset_object;
@@ -976,6 +1030,9 @@ pub use create_error_report_and_return_procedure::create_error_report_and_return
pub use create_external_api_key_and_return_procedure::create_external_api_key_and_return;
pub use create_game_distribution_game_and_return_procedure::create_game_distribution_game_and_return;
pub use create_game_distribution_version_and_return_procedure::create_game_distribution_version_and_return;
pub use create_payment_api_key_and_return_procedure::create_payment_api_key_and_return;
pub use create_payment_app_and_return_procedure::create_payment_app_and_return;
pub use create_payment_order_and_return_procedure::create_payment_order_and_return;
pub use create_profile_recharge_order_and_return_procedure::create_profile_recharge_order_and_return;
pub use creation_entry_config_table::*;
pub use creation_entry_config_type::CreationEntryConfig;
@@ -1145,6 +1202,7 @@ pub use editor_spritesheet_slice_batch_persist_result_type::EditorSpritesheetSli
pub use editor_spritesheet_slice_persist_item_input_type::EditorSpritesheetSlicePersistItemInput;
pub use editor_spritesheet_slice_persisted_item_type::EditorSpritesheetSlicePersistedItem;
pub use enqueue_external_generation_job_and_return_procedure::enqueue_external_generation_job_and_return;
pub use enqueue_payment_webhook_and_return_procedure::enqueue_payment_webhook_and_return;
pub use enqueue_profile_wallet_refund_outbox_and_return_procedure::enqueue_profile_wallet_refund_outbox_and_return;
pub use ensure_analytics_date_dimension_for_date_reducer::ensure_analytics_date_dimension_for_date;
pub use error_report_create_input_type::ErrorReportCreateInput;
@@ -1287,6 +1345,8 @@ pub use get_game_distribution_my_review_and_return_procedure::get_game_distribut
pub use get_game_distribution_version_and_return_procedure::get_game_distribution_version_and_return;
pub use get_llm_router_account_and_return_procedure::get_llm_router_account_and_return;
pub use get_owner_game_distribution_version_and_return_procedure::get_owner_game_distribution_version_and_return;
pub use get_payment_order_and_return_procedure::get_payment_order_and_return;
pub use get_payment_order_by_checkout_token_and_return_procedure::get_payment_order_by_checkout_token_and_return;
pub use get_profile_dashboard_procedure::get_profile_dashboard;
pub use get_profile_recharge_center_procedure::get_profile_recharge_center;
pub use get_profile_recharge_order_and_return_procedure::get_profile_recharge_order_and_return;
@@ -1319,6 +1379,9 @@ pub use list_game_distribution_review_games_and_return_procedure::list_game_dist
pub use list_game_distribution_reviews_and_return_procedure::list_game_distribution_reviews_and_return;
pub use list_game_distribution_user_reviews_and_return_procedure::list_game_distribution_user_reviews_and_return;
pub use list_owner_game_distribution_games_and_return_procedure::list_owner_game_distribution_games_and_return;
pub use list_payment_api_keys_and_return_procedure::list_payment_api_keys_and_return;
pub use list_payment_apps_and_return_procedure::list_payment_apps_and_return;
pub use list_payment_orders_and_return_procedure::list_payment_orders_and_return;
pub use list_profile_recharge_refund_holds_for_reconciliation_procedure::list_profile_recharge_refund_holds_for_reconciliation;
pub use list_profile_recharge_refunds_for_reconciliation_procedure::list_profile_recharge_refunds_for_reconciliation;
pub use list_profile_wallet_ledger_procedure::list_profile_wallet_ledger;
@@ -1338,10 +1401,46 @@ pub use llm_router_billing_checkpoint_type::LlmRouterBillingCheckpoint;
pub use llm_router_quota_settlement_input_type::LlmRouterQuotaSettlementInput;
pub use llm_router_quota_settlement_result_type::LlmRouterQuotaSettlementResult;
pub use mark_editor_showcase_asset_refunded_and_return_procedure::mark_editor_showcase_asset_refunded_and_return;
pub use mark_payment_order_paid_and_return_procedure::mark_payment_order_paid_and_return;
pub use mark_payment_order_provider_attempted_and_return_procedure::mark_payment_order_provider_attempted_and_return;
pub use mark_profile_recharge_order_expiration_checked_procedure::mark_profile_recharge_order_expiration_checked;
pub use mark_profile_recharge_order_paid_and_return_procedure::mark_profile_recharge_order_paid_and_return;
pub use moderate_game_distribution_user_review_and_return_procedure::moderate_game_distribution_user_review_and_return;
pub use normalize_editor_character_animation_metadata_and_return_procedure::normalize_editor_character_animation_metadata_and_return;
pub use payment_api_key_authenticate_input_type::PaymentApiKeyAuthenticateInput;
pub use payment_api_key_create_input_type::PaymentApiKeyCreateInput;
pub use payment_api_key_list_input_type::PaymentApiKeyListInput;
pub use payment_api_key_revoke_input_type::PaymentApiKeyRevokeInput;
pub use payment_api_key_snapshot_type::PaymentApiKeySnapshot;
pub use payment_api_key_table::*;
pub use payment_api_key_type::PaymentApiKey;
pub use payment_app_create_input_type::PaymentAppCreateInput;
pub use payment_app_list_input_type::PaymentAppListInput;
pub use payment_app_procedure_result_type::PaymentAppProcedureResult;
pub use payment_app_snapshot_type::PaymentAppSnapshot;
pub use payment_app_table::*;
pub use payment_app_type::PaymentApp;
pub use payment_app_update_input_type::PaymentAppUpdateInput;
pub use payment_order_checkout_get_input_type::PaymentOrderCheckoutGetInput;
pub use payment_order_create_input_type::PaymentOrderCreateInput;
pub use payment_order_get_input_type::PaymentOrderGetInput;
pub use payment_order_list_input_type::PaymentOrderListInput;
pub use payment_order_mark_paid_input_type::PaymentOrderMarkPaidInput;
pub use payment_order_procedure_result_type::PaymentOrderProcedureResult;
pub use payment_order_provider_attempt_input_type::PaymentOrderProviderAttemptInput;
pub use payment_order_provider_code_input_type::PaymentOrderProviderCodeInput;
pub use payment_order_snapshot_type::PaymentOrderSnapshot;
pub use payment_order_status_type::PaymentOrderStatus;
pub use payment_order_table::*;
pub use payment_order_type::PaymentOrder;
pub use payment_provider_type::PaymentProvider;
pub use payment_webhook_claim_input_type::PaymentWebhookClaimInput;
pub use payment_webhook_complete_input_type::PaymentWebhookCompleteInput;
pub use payment_webhook_delivery_snapshot_type::PaymentWebhookDeliverySnapshot;
pub use payment_webhook_delivery_table::*;
pub use payment_webhook_delivery_type::PaymentWebhookDelivery;
pub use payment_webhook_enqueue_input_type::PaymentWebhookEnqueueInput;
pub use payment_webhook_procedure_result_type::PaymentWebhookProcedureResult;
pub use persist_editor_generation_result_and_return_procedure::persist_editor_generation_result_and_return;
pub use persist_editor_pixel_art_result_and_return_procedure::persist_editor_pixel_art_result_and_return;
pub use persist_editor_spritesheet_slice_batch_and_return_procedure::persist_editor_spritesheet_slice_batch_and_return;
@@ -1435,6 +1534,7 @@ pub use resolve_profile_recharge_refund_manual_review_and_return_procedure::reso
pub use restore_game_distribution_game_and_return_procedure::restore_game_distribution_game_and_return;
pub use revoke_database_migration_operator_procedure::revoke_database_migration_operator;
pub use revoke_external_api_key_and_return_procedure::revoke_external_api_key_and_return;
pub use revoke_payment_api_key_and_return_procedure::revoke_payment_api_key_and_return;
pub use rollback_editor_canvas_layout_and_return_procedure::rollback_editor_canvas_layout_and_return;
pub use rotate_editor_generation_runtime_service_identity_and_return_procedure::rotate_editor_generation_runtime_service_identity_and_return;
pub use runtime_browse_history_theme_mode_type::RuntimeBrowseHistoryThemeMode;
@@ -1586,6 +1686,7 @@ pub use save_editor_project_layout_v_2_and_return_procedure::save_editor_project
pub use save_game_distribution_my_review_and_return_procedure::save_game_distribution_my_review_and_return;
pub use seed_analytics_date_dimensions_reducer::seed_analytics_date_dimensions;
pub use set_editor_showcase_asset_like_for_viewer_and_return_procedure::set_editor_showcase_asset_like_for_viewer_and_return;
pub use set_payment_order_provider_code_and_return_procedure::set_payment_order_provider_code_and_return;
pub use settle_llm_router_quota_and_return_procedure::settle_llm_router_quota_and_return;
pub use start_ai_task_reducer::start_ai_task;
pub use start_ai_task_stage_reducer::start_ai_task_stage;
@@ -1608,6 +1709,7 @@ pub use update_editor_showcase_asset_display_and_return_procedure::update_editor
pub use update_error_report_and_return_procedure::update_error_report_and_return;
pub use update_external_generation_job_phase_and_return_procedure::update_external_generation_job_phase_and_return;
pub use update_game_distribution_game_metadata_and_return_procedure::update_game_distribution_game_metadata_and_return;
pub use update_payment_app_and_return_procedure::update_payment_app_and_return;
pub use upload_agc_analytics_batch_procedure::upload_agc_analytics_batch;
pub use upsert_editor_generation_pricing_config_and_return_procedure::upsert_editor_generation_pricing_config_and_return;
pub use upsert_editor_showcase_campaign_config_and_return_procedure::upsert_editor_showcase_campaign_config_and_return;
@@ -1780,6 +1882,10 @@ pub struct DbUpdate {
game_distribution_version: __sdk::TableUpdate<GameDistributionVersion>,
llm_router_account: __sdk::TableUpdate<LlmRouterAccount>,
llm_router_billing_checkpoint: __sdk::TableUpdate<LlmRouterBillingCheckpoint>,
payment_api_key: __sdk::TableUpdate<PaymentApiKey>,
payment_app: __sdk::TableUpdate<PaymentApp>,
payment_order: __sdk::TableUpdate<PaymentOrder>,
payment_webhook_delivery: __sdk::TableUpdate<PaymentWebhookDelivery>,
profile_code_operation: __sdk::TableUpdate<ProfileCodeOperation>,
profile_daily_free_points: __sdk::TableUpdate<ProfileDailyFreePoints>,
profile_dashboard_state: __sdk::TableUpdate<ProfileDashboardState>,
@@ -2011,6 +2117,18 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
"llm_router_billing_checkpoint" => db_update.llm_router_billing_checkpoint.append(
llm_router_billing_checkpoint_table::parse_table_update(table_update)?,
),
"payment_api_key" => db_update
.payment_api_key
.append(payment_api_key_table::parse_table_update(table_update)?),
"payment_app" => db_update
.payment_app
.append(payment_app_table::parse_table_update(table_update)?),
"payment_order" => db_update
.payment_order
.append(payment_order_table::parse_table_update(table_update)?),
"payment_webhook_delivery" => db_update.payment_webhook_delivery.append(
payment_webhook_delivery_table::parse_table_update(table_update)?,
),
"profile_code_operation" => db_update.profile_code_operation.append(
profile_code_operation_table::parse_table_update(table_update)?,
),
@@ -2422,6 +2540,21 @@ impl __sdk::DbUpdate for DbUpdate {
&self.llm_router_billing_checkpoint,
)
.with_updates_by_pk(|row| &row.account_key);
diff.payment_api_key = cache
.apply_diff_to_table::<PaymentApiKey>("payment_api_key", &self.payment_api_key)
.with_updates_by_pk(|row| &row.key_id);
diff.payment_app = cache
.apply_diff_to_table::<PaymentApp>("payment_app", &self.payment_app)
.with_updates_by_pk(|row| &row.app_id);
diff.payment_order = cache
.apply_diff_to_table::<PaymentOrder>("payment_order", &self.payment_order)
.with_updates_by_pk(|row| &row.order_id);
diff.payment_webhook_delivery = cache
.apply_diff_to_table::<PaymentWebhookDelivery>(
"payment_webhook_delivery",
&self.payment_webhook_delivery,
)
.with_updates_by_pk(|row| &row.delivery_id);
diff.profile_code_operation = cache
.apply_diff_to_table::<ProfileCodeOperation>(
"profile_code_operation",
@@ -2783,6 +2916,18 @@ impl __sdk::DbUpdate for DbUpdate {
"llm_router_billing_checkpoint" => db_update
.llm_router_billing_checkpoint
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"payment_api_key" => db_update
.payment_api_key
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"payment_app" => db_update
.payment_app
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"payment_order" => db_update
.payment_order
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"payment_webhook_delivery" => db_update
.payment_webhook_delivery
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"profile_code_operation" => db_update
.profile_code_operation
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
@@ -3057,6 +3202,18 @@ impl __sdk::DbUpdate for DbUpdate {
"llm_router_billing_checkpoint" => db_update
.llm_router_billing_checkpoint
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"payment_api_key" => db_update
.payment_api_key
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"payment_app" => db_update
.payment_app
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"payment_order" => db_update
.payment_order
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"payment_webhook_delivery" => db_update
.payment_webhook_delivery
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"profile_code_operation" => db_update
.profile_code_operation
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
@@ -3237,6 +3394,10 @@ pub struct AppliedDiff<'r> {
game_distribution_version: __sdk::TableAppliedDiff<'r, GameDistributionVersion>,
llm_router_account: __sdk::TableAppliedDiff<'r, LlmRouterAccount>,
llm_router_billing_checkpoint: __sdk::TableAppliedDiff<'r, LlmRouterBillingCheckpoint>,
payment_api_key: __sdk::TableAppliedDiff<'r, PaymentApiKey>,
payment_app: __sdk::TableAppliedDiff<'r, PaymentApp>,
payment_order: __sdk::TableAppliedDiff<'r, PaymentOrder>,
payment_webhook_delivery: __sdk::TableAppliedDiff<'r, PaymentWebhookDelivery>,
profile_code_operation: __sdk::TableAppliedDiff<'r, ProfileCodeOperation>,
profile_daily_free_points: __sdk::TableAppliedDiff<'r, ProfileDailyFreePoints>,
profile_dashboard_state: __sdk::TableAppliedDiff<'r, ProfileDashboardState>,
@@ -3534,6 +3695,22 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
&self.llm_router_billing_checkpoint,
event,
);
callbacks.invoke_table_row_callbacks::<PaymentApiKey>(
"payment_api_key",
&self.payment_api_key,
event,
);
callbacks.invoke_table_row_callbacks::<PaymentApp>("payment_app", &self.payment_app, event);
callbacks.invoke_table_row_callbacks::<PaymentOrder>(
"payment_order",
&self.payment_order,
event,
);
callbacks.invoke_table_row_callbacks::<PaymentWebhookDelivery>(
"payment_webhook_delivery",
&self.payment_webhook_delivery,
event,
);
callbacks.invoke_table_row_callbacks::<ProfileCodeOperation>(
"profile_code_operation",
&self.profile_code_operation,
@@ -4429,6 +4606,10 @@ impl __sdk::SpacetimeModule for RemoteModule {
game_distribution_version_table::register_table(client_cache);
llm_router_account_table::register_table(client_cache);
llm_router_billing_checkpoint_table::register_table(client_cache);
payment_api_key_table::register_table(client_cache);
payment_app_table::register_table(client_cache);
payment_order_table::register_table(client_cache);
payment_webhook_delivery_table::register_table(client_cache);
profile_code_operation_table::register_table(client_cache);
profile_daily_free_points_table::register_table(client_cache);
profile_dashboard_state_table::register_table(client_cache);
@@ -4518,6 +4699,10 @@ impl __sdk::SpacetimeModule for RemoteModule {
"game_distribution_version",
"llm_router_account",
"llm_router_billing_checkpoint",
"payment_api_key",
"payment_app",
"payment_order",
"payment_webhook_delivery",
"profile_code_operation",
"profile_daily_free_points",
"profile_dashboard_state",
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::payment_api_key_authenticate_input_type::PaymentApiKeyAuthenticateInput;
use super::payment_app_procedure_result_type::PaymentAppProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct AuthenticatePaymentApiKeyAndReturnArgs {
pub input: PaymentApiKeyAuthenticateInput,
}
impl __sdk::InModule for AuthenticatePaymentApiKeyAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `authenticate_payment_api_key_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait authenticate_payment_api_key_and_return {
fn authenticate_payment_api_key_and_return(&self, input: PaymentApiKeyAuthenticateInput) {
self.authenticate_payment_api_key_and_return_then(input, |_, _| {});
}
fn authenticate_payment_api_key_and_return_then(
&self,
input: PaymentApiKeyAuthenticateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentAppProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl authenticate_payment_api_key_and_return for super::RemoteProcedures {
fn authenticate_payment_api_key_and_return_then(
&self,
input: PaymentApiKeyAuthenticateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentAppProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, PaymentAppProcedureResult>(
"authenticate_payment_api_key_and_return",
AuthenticatePaymentApiKeyAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::payment_webhook_claim_input_type::PaymentWebhookClaimInput;
use super::payment_webhook_procedure_result_type::PaymentWebhookProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct ClaimPaymentWebhooksAndReturnArgs {
pub input: PaymentWebhookClaimInput,
}
impl __sdk::InModule for ClaimPaymentWebhooksAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `claim_payment_webhooks_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait claim_payment_webhooks_and_return {
fn claim_payment_webhooks_and_return(&self, input: PaymentWebhookClaimInput) {
self.claim_payment_webhooks_and_return_then(input, |_, _| {});
}
fn claim_payment_webhooks_and_return_then(
&self,
input: PaymentWebhookClaimInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentWebhookProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl claim_payment_webhooks_and_return for super::RemoteProcedures {
fn claim_payment_webhooks_and_return_then(
&self,
input: PaymentWebhookClaimInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentWebhookProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, PaymentWebhookProcedureResult>(
"claim_payment_webhooks_and_return",
ClaimPaymentWebhooksAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::payment_webhook_complete_input_type::PaymentWebhookCompleteInput;
use super::payment_webhook_procedure_result_type::PaymentWebhookProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct CompletePaymentWebhookAndReturnArgs {
pub input: PaymentWebhookCompleteInput,
}
impl __sdk::InModule for CompletePaymentWebhookAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `complete_payment_webhook_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait complete_payment_webhook_and_return {
fn complete_payment_webhook_and_return(&self, input: PaymentWebhookCompleteInput) {
self.complete_payment_webhook_and_return_then(input, |_, _| {});
}
fn complete_payment_webhook_and_return_then(
&self,
input: PaymentWebhookCompleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentWebhookProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl complete_payment_webhook_and_return for super::RemoteProcedures {
fn complete_payment_webhook_and_return_then(
&self,
input: PaymentWebhookCompleteInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<PaymentWebhookProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, PaymentWebhookProcedureResult>(
"complete_payment_webhook_and_return",
CompletePaymentWebhookAndReturnArgs { input },
__callback,
);
}
}

Some files were not shown because too many files have changed in this diff Show More