skill-service 0.2.0__tar.gz
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.
- skill_service-0.2.0/.env.example +57 -0
- skill_service-0.2.0/.gitignore +65 -0
- skill_service-0.2.0/Dockerfile +11 -0
- skill_service-0.2.0/PKG-INFO +73 -0
- skill_service-0.2.0/README.md +55 -0
- skill_service-0.2.0/alembic/versions/0001_init_skills.sql +40 -0
- skill_service-0.2.0/alembic/versions/0002_wallet_and_billing.sql +74 -0
- skill_service-0.2.0/alembic/versions/0003_recharge_and_payments.sql +53 -0
- skill_service-0.2.0/alembic/versions/0004_subscriptions.sql +26 -0
- skill_service-0.2.0/alembic/versions/0005_admin_config_logs.sql +19 -0
- skill_service-0.2.0/alembic/versions/0006_sessions.sql +15 -0
- skill_service-0.2.0/alembic/versions/0007_order_pay_params.sql +9 -0
- skill_service-0.2.0/alembic/versions/0008_subscription_stripe.sql +48 -0
- skill_service-0.2.0/alembic/versions/0009_subscription_billing_period.sql +5 -0
- skill_service-0.2.0/alembic/versions/0010_subscription_stripe_unique.sql +5 -0
- skill_service-0.2.0/alembic/versions/0011_subscription_constraints.sql +25 -0
- skill_service-0.2.0/deploy/.env.live.example +35 -0
- skill_service-0.2.0/deploy/nginx/skill.deinai.ai.conf +60 -0
- skill_service-0.2.0/deploy/nginx/skill.prod.conf +66 -0
- skill_service-0.2.0/deploy/nginx/skill.test.conf +104 -0
- skill_service-0.2.0/deploy/scripts/deploy-test-server.ps1 +37 -0
- skill_service-0.2.0/deploy/scripts/deploy-test-server.sh +69 -0
- skill_service-0.2.0/docker-compose.dev.yml +65 -0
- skill_service-0.2.0/docker-compose.prod.yml +25 -0
- skill_service-0.2.0/docker-compose.yml +24 -0
- skill_service-0.2.0/docs/DEPLOY_CHECKLIST.md +343 -0
- skill_service-0.2.0/docs/DeiNai_SKILL_/344/272/244/344/273/230/347/211/251/350/257/264/346/230/216.txt +122 -0
- skill_service-0.2.0/docs/OPENCLAW_E2E_TEST.md +193 -0
- skill_service-0.2.0/docs/PAYMENT_CALLBACKS.md +204 -0
- skill_service-0.2.0/docs/PAYMENT_LIVE_SETUP.md +200 -0
- skill_service-0.2.0/docs/PAYMENT_STRIPE.md +119 -0
- skill_service-0.2.0/docs/PRODUCTION_RELEASE.md +482 -0
- skill_service-0.2.0/docs/SCRIPTS.md +397 -0
- skill_service-0.2.0/main.py +9 -0
- skill_service-0.2.0/output/registry/.gitignore +2 -0
- skill_service-0.2.0/output/registry/IMPLEMENTATION.md +36 -0
- skill_service-0.2.0/output/registry/PUBLISH.md +97 -0
- skill_service-0.2.0/output/registry/README.md +122 -0
- skill_service-0.2.0/output/registry/server.json +50 -0
- skill_service-0.2.0/output/registry/server.json.legacy-backend.json +50 -0
- skill_service-0.2.0/output/registry/server.json.md +29 -0
- skill_service-0.2.0/pyproject.toml +29 -0
- skill_service-0.2.0/scripts/deploy_prod_server.py +208 -0
- skill_service-0.2.0/scripts/init_db.py +55 -0
- skill_service-0.2.0/scripts/prod_test_account_flow.py +340 -0
- skill_service-0.2.0/scripts/seed_dev_account.py +108 -0
- skill_service-0.2.0/scripts/sync_prod_stripe_plans.py +221 -0
- skill_service-0.2.0/skill_service/__init__.py +2 -0
- skill_service-0.2.0/skill_service/api/__init__.py +2 -0
- skill_service-0.2.0/skill_service/api/authz.py +16 -0
- skill_service-0.2.0/skill_service/api/middleware/__init__.py +2 -0
- skill_service-0.2.0/skill_service/api/middleware/skill_auth.py +125 -0
- skill_service-0.2.0/skill_service/api/routes/__init__.py +28 -0
- skill_service-0.2.0/skill_service/api/routes/admin.py +103 -0
- skill_service-0.2.0/skill_service/api/routes/auth.py +74 -0
- skill_service-0.2.0/skill_service/api/routes/locations.py +36 -0
- skill_service-0.2.0/skill_service/api/routes/payments.py +181 -0
- skill_service-0.2.0/skill_service/api/routes/portal.py +37 -0
- skill_service-0.2.0/skill_service/api/routes/recharge.py +66 -0
- skill_service-0.2.0/skill_service/api/routes/search.py +106 -0
- skill_service-0.2.0/skill_service/api/routes/subscriptions.py +179 -0
- skill_service-0.2.0/skill_service/api/routes/tokens.py +67 -0
- skill_service-0.2.0/skill_service/api/routes/wallet.py +90 -0
- skill_service-0.2.0/skill_service/app.py +62 -0
- skill_service-0.2.0/skill_service/config/__init__.py +2 -0
- skill_service-0.2.0/skill_service/config/settings.py +66 -0
- skill_service-0.2.0/skill_service/db.py +72 -0
- skill_service-0.2.0/skill_service/integrations/__init__.py +2 -0
- skill_service-0.2.0/skill_service/integrations/modash/__init__.py +2 -0
- skill_service-0.2.0/skill_service/integrations/modash/client.py +119 -0
- skill_service-0.2.0/skill_service/integrations/modash/types.py +189 -0
- skill_service-0.2.0/skill_service/integrations/payments/alipay_notify.py +68 -0
- skill_service-0.2.0/skill_service/integrations/payments/alipay_qr.py +79 -0
- skill_service-0.2.0/skill_service/integrations/payments/base.py +23 -0
- skill_service-0.2.0/skill_service/integrations/payments/config_status.py +98 -0
- skill_service-0.2.0/skill_service/integrations/payments/mock_provider.py +33 -0
- skill_service-0.2.0/skill_service/integrations/payments/notify_urls.py +12 -0
- skill_service-0.2.0/skill_service/integrations/payments/pem_util.py +12 -0
- skill_service-0.2.0/skill_service/integrations/payments/providers.py +174 -0
- skill_service-0.2.0/skill_service/integrations/payments/stripe_checkout.py +65 -0
- skill_service-0.2.0/skill_service/integrations/payments/stripe_notify.py +70 -0
- skill_service-0.2.0/skill_service/integrations/payments/stripe_subscription.py +88 -0
- skill_service-0.2.0/skill_service/integrations/payments/wechat_v3.py +83 -0
- skill_service-0.2.0/skill_service/integrations/payments/wechat_v3_notify.py +100 -0
- skill_service-0.2.0/skill_service/mcp/__init__.py +2 -0
- skill_service-0.2.0/skill_service/mcp/match.py +51 -0
- skill_service-0.2.0/skill_service/mcp/models/__init__.py +2 -0
- skill_service-0.2.0/skill_service/mcp/models/common.py +13 -0
- skill_service-0.2.0/skill_service/mcp/models/get_location_ids.py +12 -0
- skill_service-0.2.0/skill_service/mcp/models/search_influencers.py +88 -0
- skill_service-0.2.0/skill_service/mcp/server.py +35 -0
- skill_service-0.2.0/skill_service/mcp/tools/__init__.py +10 -0
- skill_service-0.2.0/skill_service/mcp/tools/common.py +21 -0
- skill_service-0.2.0/skill_service/mcp/tools/get_location_ids.py +48 -0
- skill_service-0.2.0/skill_service/mcp/tools/search_influencers.py +113 -0
- skill_service-0.2.0/skill_service/portal/static/checkout.html +137 -0
- skill_service-0.2.0/skill_service/portal/static/common.css +154 -0
- skill_service-0.2.0/skill_service/portal/static/index.html +21 -0
- skill_service-0.2.0/skill_service/portal/static/login.html +38 -0
- skill_service-0.2.0/skill_service/portal/static/mock-checkout.html +37 -0
- skill_service-0.2.0/skill_service/portal/static/recharge.html +12 -0
- skill_service-0.2.0/skill_service/portal/static/subscription.html +330 -0
- skill_service-0.2.0/skill_service/portal/static/tokens.html +138 -0
- skill_service-0.2.0/skill_service/services/__init__.py +2 -0
- skill_service-0.2.0/skill_service/services/admin_service.py +184 -0
- skill_service-0.2.0/skill_service/services/auth_service.py +105 -0
- skill_service-0.2.0/skill_service/services/influencer_search_executor.py +59 -0
- skill_service-0.2.0/skill_service/services/influencer_search_filters.py +75 -0
- skill_service-0.2.0/skill_service/services/location_service.py +28 -0
- skill_service-0.2.0/skill_service/services/payment_checkout_service.py +104 -0
- skill_service-0.2.0/skill_service/services/payment_security.py +29 -0
- skill_service-0.2.0/skill_service/services/recharge_service.py +232 -0
- skill_service-0.2.0/skill_service/services/search_service.py +129 -0
- skill_service-0.2.0/skill_service/services/session_service.py +115 -0
- skill_service-0.2.0/skill_service/services/subscription_errors.py +19 -0
- skill_service-0.2.0/skill_service/services/subscription_service.py +1524 -0
- skill_service-0.2.0/skill_service/services/token_service.py +101 -0
- skill_service-0.2.0/skill_service/services/wallet_service.py +127 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Skill Service — environment template
|
|
2
|
+
# Copy to .env and fill in values. Do not commit .env.
|
|
3
|
+
|
|
4
|
+
# --- docker-compose.dev.yml (host-side scripts) ---
|
|
5
|
+
# SKILL_DATABASE_URL=postgresql://skill_app:skill_dev_pass@127.0.0.1:5433/skills
|
|
6
|
+
# SKILL_REDIS_URL=redis://127.0.0.1:6380/0
|
|
7
|
+
|
|
8
|
+
APP_NAME=Creator SKILL
|
|
9
|
+
APP_VERSION=0.2.0
|
|
10
|
+
SKILL_HTTP_PORT=8080
|
|
11
|
+
|
|
12
|
+
SKILL_DATABASE_URL=postgresql://skill_app:CHANGE_ME@127.0.0.1:5432/skills
|
|
13
|
+
SKILL_DATABASE_NAME=skills
|
|
14
|
+
SKILL_REDIS_URL=redis://:CHANGE_ME@127.0.0.1:6379/0
|
|
15
|
+
|
|
16
|
+
MODASH_API_KEY=
|
|
17
|
+
MODASH_BASE_URL=https://api.modash.io/v1
|
|
18
|
+
MODASH_TIMEOUT=30
|
|
19
|
+
MODASH_MAX_RETRIES=3
|
|
20
|
+
|
|
21
|
+
SKILL_TOKEN_PREFIX=sk_live_
|
|
22
|
+
SESSION_TOKEN_PREFIX=sk_sess_
|
|
23
|
+
SESSION_TTL_HOURS=24
|
|
24
|
+
|
|
25
|
+
PAYMENT_MODE=mock
|
|
26
|
+
# live 时建议 false,避免凭证缺失却走 mock
|
|
27
|
+
PAYMENT_ALLOW_MOCK_FALLBACK=false
|
|
28
|
+
|
|
29
|
+
SKILL_PUBLIC_BASE_URL=http://127.0.0.1:8080
|
|
30
|
+
|
|
31
|
+
# --- WeChat Pay API v3 ---
|
|
32
|
+
WECHAT_APP_ID=
|
|
33
|
+
WECHAT_MCH_ID=
|
|
34
|
+
WECHAT_MCH_SERIAL_NO=
|
|
35
|
+
WECHAT_MCH_PRIVATE_KEY=
|
|
36
|
+
WECHAT_MCH_PRIVATE_KEY_PATH=
|
|
37
|
+
WECHAT_API_V3_KEY=
|
|
38
|
+
WECHAT_PLATFORM_PUBLIC_KEY=
|
|
39
|
+
|
|
40
|
+
# --- Alipay ---
|
|
41
|
+
ALIPAY_APP_ID=
|
|
42
|
+
ALIPAY_PRIVATE_KEY=
|
|
43
|
+
ALIPAY_PRIVATE_KEY_PATH=
|
|
44
|
+
ALIPAY_PUBLIC_KEY=
|
|
45
|
+
ALIPAY_GATEWAY_URL=https://openapi.alipay.com/gateway.do
|
|
46
|
+
|
|
47
|
+
STRIPE_SECRET_KEY=
|
|
48
|
+
STRIPE_WEBHOOK_SECRET=
|
|
49
|
+
STRIPE_PUBLISHABLE_KEY=
|
|
50
|
+
STRIPE_CURRENCY=cny
|
|
51
|
+
|
|
52
|
+
# OpenClaw test-only: enables POST /api/v1/subscriptions/automation/complete-checkout
|
|
53
|
+
# SKILL_OPENCLAW_AUTOMATION_KEY=
|
|
54
|
+
|
|
55
|
+
# mock / dev HMAC callbacks (optional)
|
|
56
|
+
WECHAT_NOTIFY_SECRET=
|
|
57
|
+
ALIPAY_NOTIFY_SECRET=
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# --- Secrets & local config (never commit) ---
|
|
2
|
+
.env
|
|
3
|
+
.env_prod
|
|
4
|
+
prod.yaml
|
|
5
|
+
deploy/.env.test-server
|
|
6
|
+
secrets/
|
|
7
|
+
|
|
8
|
+
# --- Python ---
|
|
9
|
+
.venv/
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
*.egg-info/
|
|
14
|
+
.eggs/
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
|
|
21
|
+
# --- Build / deploy artifacts ---
|
|
22
|
+
*.tgz
|
|
23
|
+
deploy.tgz
|
|
24
|
+
deploy-sync.tgz
|
|
25
|
+
skill-service-deploy.tgz
|
|
26
|
+
|
|
27
|
+
# --- scripts/: only init_db + seed_dev_account go to remote ---
|
|
28
|
+
scripts/*
|
|
29
|
+
!scripts/init_db.py
|
|
30
|
+
!scripts/seed_dev_account.py
|
|
31
|
+
!scripts/deploy_prod_server.py
|
|
32
|
+
!scripts/sync_prod_stripe_plans.py
|
|
33
|
+
!scripts/prod_test_account_flow.py
|
|
34
|
+
|
|
35
|
+
# --- Tests (local only) ---
|
|
36
|
+
tests/
|
|
37
|
+
|
|
38
|
+
# --- Dev / E2E docs (see docs/SCRIPTS.md for script index) ---
|
|
39
|
+
docs/CI_SMOKE.md
|
|
40
|
+
docs/CURSOR_DEBUG.md
|
|
41
|
+
docs/PAYMENT_E2E_TEST.md
|
|
42
|
+
docs/SUBSCRIPTION_E2E_TEST.md
|
|
43
|
+
docs/STRIPE_TEST_ENV_SETUP.md
|
|
44
|
+
docs/PLAN.md
|
|
45
|
+
|
|
46
|
+
# --- CI workflow (needs remote smoke secrets) ---
|
|
47
|
+
.github/
|
|
48
|
+
|
|
49
|
+
# --- Dev-only compose ---
|
|
50
|
+
docker-compose.test-deploy.yml
|
|
51
|
+
|
|
52
|
+
# --- Registry local publish helpers ---
|
|
53
|
+
output/registry/publish-registry.cmd
|
|
54
|
+
output/registry/publish-registry.ps1
|
|
55
|
+
|
|
56
|
+
# --- Logs ---
|
|
57
|
+
*.log
|
|
58
|
+
|
|
59
|
+
# --- IDE / OS ---
|
|
60
|
+
.idea/
|
|
61
|
+
.vscode/
|
|
62
|
+
*.swp
|
|
63
|
+
*~
|
|
64
|
+
.DS_Store
|
|
65
|
+
Thumbs.db
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skill-service
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Standalone Creator SKILL MCP service
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: asyncpg>=0.29.0
|
|
7
|
+
Requires-Dist: cryptography>=42.0.0
|
|
8
|
+
Requires-Dist: email-validator>=2.2.0
|
|
9
|
+
Requires-Dist: fastapi>=0.115.0
|
|
10
|
+
Requires-Dist: fastmcp<4,>=3.3.1
|
|
11
|
+
Requires-Dist: httpx>=0.27.0
|
|
12
|
+
Requires-Dist: loguru>=0.7.2
|
|
13
|
+
Requires-Dist: pydantic-settings>=2.3.0
|
|
14
|
+
Requires-Dist: pydantic>=2.8.0
|
|
15
|
+
Requires-Dist: stripe>=10.0.0
|
|
16
|
+
Requires-Dist: uvicorn>=0.30.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# skill-service
|
|
20
|
+
|
|
21
|
+
Standalone Creator SKILL service — MCP + REST API + independent billing.
|
|
22
|
+
|
|
23
|
+
<!-- mcp-name: ai.deinai/creator-skill-v2 -->
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd apps/skill-service
|
|
29
|
+
python -m venv .venv
|
|
30
|
+
.venv/Scripts/python -m pip install -U pip
|
|
31
|
+
.venv/Scripts/pip install -e .
|
|
32
|
+
cp .env.example .env # edit database / modash keys
|
|
33
|
+
.venv/Scripts/python scripts/init_db.py
|
|
34
|
+
.venv/Scripts/python scripts/seed_dev_account.py --email dev@demo.com --password "12345678" --credits 5000
|
|
35
|
+
.venv/Scripts/python main.py
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Health: `GET http://127.0.0.1:8080/health`
|
|
39
|
+
MCP: `http://127.0.0.1:8080/mcp` (Bearer `sk_live_...`)
|
|
40
|
+
|
|
41
|
+
## Production
|
|
42
|
+
|
|
43
|
+
- **Release (Stripe only)**: [docs/PRODUCTION_RELEASE.md](docs/PRODUCTION_RELEASE.md)
|
|
44
|
+
- **Prod deploy script**: `python scripts/deploy_prod_server.py` (uses `prod.yaml` + `.env_prod`)
|
|
45
|
+
- Deploy: [docs/DEPLOY_CHECKLIST.md](docs/DEPLOY_CHECKLIST.md)
|
|
46
|
+
- Local dev: `docker compose -f docker-compose.dev.yml up -d --build` or `scripts/dev_up.ps1 -Build`
|
|
47
|
+
- Payments: [docs/PAYMENT_CALLBACKS.md](docs/PAYMENT_CALLBACKS.md)
|
|
48
|
+
- Payment E2E (Plan A/C): [docs/PAYMENT_E2E_TEST.md](docs/PAYMENT_E2E_TEST.md)
|
|
49
|
+
- Subscription E2E: [docs/SUBSCRIPTION_E2E_TEST.md](docs/SUBSCRIPTION_E2E_TEST.md)
|
|
50
|
+
- **OpenClaw + ClawHub E2E**: [docs/OPENCLAW_E2E_TEST.md](docs/OPENCLAW_E2E_TEST.md)
|
|
51
|
+
- **Stripe 测试环境配置**: [docs/STRIPE_TEST_ENV_SETUP.md](docs/STRIPE_TEST_ENV_SETUP.md)
|
|
52
|
+
- MCP Registry: [output/registry/](output/registry/)
|
|
53
|
+
- Coze HTTP SOP: `deinai_backend/output/coze/PATH-A-SOP.md`
|
|
54
|
+
|
|
55
|
+
## Stdio bridge (Cursor / Claude Desktop)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export SKILL_TOKEN="sk_live_..."
|
|
59
|
+
skill-service-match
|
|
60
|
+
# or: uvx --from skill-service skill-service-match
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Optional: `SKILL_MCP_URL` (default `https://skill.deinai.ai/mcp`).
|
|
64
|
+
|
|
65
|
+
## Status
|
|
66
|
+
|
|
67
|
+
- Independent account / session (`sk_sess_`) / API token (`sk_live_`)
|
|
68
|
+
- Wallet, recharge, consumption ledger
|
|
69
|
+
- **Portal** (`/portal/`): login, recharge, mock checkout, token management
|
|
70
|
+
- **Payment checkout**: `POST /recharge/orders` returns `payParams` (mock / wechat / alipay)
|
|
71
|
+
- MCP tools: `ping`, `get_location_ids`, `searchInfluencers`
|
|
72
|
+
- REST: `GET /api/v1/account/status`, `POST /api/v1/search/influencers`
|
|
73
|
+
- Admin: credit packages, consume rules, audit logs
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# skill-service
|
|
2
|
+
|
|
3
|
+
Standalone Creator SKILL service — MCP + REST API + independent billing.
|
|
4
|
+
|
|
5
|
+
<!-- mcp-name: ai.deinai/creator-skill-v2 -->
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd apps/skill-service
|
|
11
|
+
python -m venv .venv
|
|
12
|
+
.venv/Scripts/python -m pip install -U pip
|
|
13
|
+
.venv/Scripts/pip install -e .
|
|
14
|
+
cp .env.example .env # edit database / modash keys
|
|
15
|
+
.venv/Scripts/python scripts/init_db.py
|
|
16
|
+
.venv/Scripts/python scripts/seed_dev_account.py --email dev@demo.com --password "12345678" --credits 5000
|
|
17
|
+
.venv/Scripts/python main.py
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Health: `GET http://127.0.0.1:8080/health`
|
|
21
|
+
MCP: `http://127.0.0.1:8080/mcp` (Bearer `sk_live_...`)
|
|
22
|
+
|
|
23
|
+
## Production
|
|
24
|
+
|
|
25
|
+
- **Release (Stripe only)**: [docs/PRODUCTION_RELEASE.md](docs/PRODUCTION_RELEASE.md)
|
|
26
|
+
- **Prod deploy script**: `python scripts/deploy_prod_server.py` (uses `prod.yaml` + `.env_prod`)
|
|
27
|
+
- Deploy: [docs/DEPLOY_CHECKLIST.md](docs/DEPLOY_CHECKLIST.md)
|
|
28
|
+
- Local dev: `docker compose -f docker-compose.dev.yml up -d --build` or `scripts/dev_up.ps1 -Build`
|
|
29
|
+
- Payments: [docs/PAYMENT_CALLBACKS.md](docs/PAYMENT_CALLBACKS.md)
|
|
30
|
+
- Payment E2E (Plan A/C): [docs/PAYMENT_E2E_TEST.md](docs/PAYMENT_E2E_TEST.md)
|
|
31
|
+
- Subscription E2E: [docs/SUBSCRIPTION_E2E_TEST.md](docs/SUBSCRIPTION_E2E_TEST.md)
|
|
32
|
+
- **OpenClaw + ClawHub E2E**: [docs/OPENCLAW_E2E_TEST.md](docs/OPENCLAW_E2E_TEST.md)
|
|
33
|
+
- **Stripe 测试环境配置**: [docs/STRIPE_TEST_ENV_SETUP.md](docs/STRIPE_TEST_ENV_SETUP.md)
|
|
34
|
+
- MCP Registry: [output/registry/](output/registry/)
|
|
35
|
+
- Coze HTTP SOP: `deinai_backend/output/coze/PATH-A-SOP.md`
|
|
36
|
+
|
|
37
|
+
## Stdio bridge (Cursor / Claude Desktop)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export SKILL_TOKEN="sk_live_..."
|
|
41
|
+
skill-service-match
|
|
42
|
+
# or: uvx --from skill-service skill-service-match
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Optional: `SKILL_MCP_URL` (default `https://skill.deinai.ai/mcp`).
|
|
46
|
+
|
|
47
|
+
## Status
|
|
48
|
+
|
|
49
|
+
- Independent account / session (`sk_sess_`) / API token (`sk_live_`)
|
|
50
|
+
- Wallet, recharge, consumption ledger
|
|
51
|
+
- **Portal** (`/portal/`): login, recharge, mock checkout, token management
|
|
52
|
+
- **Payment checkout**: `POST /recharge/orders` returns `payParams` (mock / wechat / alipay)
|
|
53
|
+
- MCP tools: `ping`, `get_location_ids`, `searchInfluencers`
|
|
54
|
+
- REST: `GET /api/v1/account/status`, `POST /api/v1/search/influencers`
|
|
55
|
+
- Admin: credit packages, consume rules, audit logs
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- 0001_init_skills.sql
|
|
2
|
+
-- Minimal Phase-3 schema for DB-backed token auth.
|
|
3
|
+
|
|
4
|
+
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
5
|
+
|
|
6
|
+
CREATE TABLE IF NOT EXISTS skill_accounts (
|
|
7
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
8
|
+
email VARCHAR UNIQUE,
|
|
9
|
+
password_hash VARCHAR,
|
|
10
|
+
display_name VARCHAR,
|
|
11
|
+
status VARCHAR NOT NULL DEFAULT 'active',
|
|
12
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
13
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS skill_tokens (
|
|
17
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
18
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
19
|
+
token_hash VARCHAR NOT NULL UNIQUE,
|
|
20
|
+
token_prefix VARCHAR(16) NOT NULL,
|
|
21
|
+
name VARCHAR,
|
|
22
|
+
scopes TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[],
|
|
23
|
+
expires_at TIMESTAMPTZ,
|
|
24
|
+
revoked_at TIMESTAMPTZ,
|
|
25
|
+
last_used_at TIMESTAMPTZ,
|
|
26
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS skill_account_roles (
|
|
30
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
31
|
+
role VARCHAR NOT NULL,
|
|
32
|
+
granted_by UUID,
|
|
33
|
+
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
34
|
+
PRIMARY KEY (account_id, role)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_skill_tokens_account_id ON skill_tokens(account_id);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_skill_tokens_revoked_at ON skill_tokens(revoked_at);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_skill_accounts_status ON skill_accounts(status);
|
|
40
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
-- 0002_wallet_and_billing.sql
|
|
2
|
+
-- Wallet, billing rules, and consumption records.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS skill_wallets (
|
|
5
|
+
account_id UUID PRIMARY KEY REFERENCES skill_accounts(id),
|
|
6
|
+
balance BIGINT NOT NULL DEFAULT 0,
|
|
7
|
+
frozen_balance BIGINT NOT NULL DEFAULT 0,
|
|
8
|
+
version INT NOT NULL DEFAULT 0,
|
|
9
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS skill_pricing_rules (
|
|
13
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
14
|
+
feature VARCHAR NOT NULL,
|
|
15
|
+
unit_price INT NOT NULL,
|
|
16
|
+
effective_from TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
17
|
+
effective_to TIMESTAMPTZ
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS skill_feature_consume_rules (
|
|
21
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
22
|
+
feature VARCHAR UNIQUE NOT NULL,
|
|
23
|
+
unit_type VARCHAR NOT NULL DEFAULT 'per_result',
|
|
24
|
+
unit_price INT NOT NULL DEFAULT 1,
|
|
25
|
+
min_charge INT NOT NULL DEFAULT 0,
|
|
26
|
+
max_charge INT NOT NULL DEFAULT 0,
|
|
27
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
28
|
+
effective_from TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
29
|
+
effective_to TIMESTAMPTZ,
|
|
30
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE IF NOT EXISTS skill_ledger_entries (
|
|
34
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
35
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
36
|
+
entry_type VARCHAR NOT NULL,
|
|
37
|
+
amount BIGINT NOT NULL,
|
|
38
|
+
balance_after BIGINT NOT NULL,
|
|
39
|
+
ref_type VARCHAR,
|
|
40
|
+
ref_id UUID,
|
|
41
|
+
idempotency_key VARCHAR UNIQUE,
|
|
42
|
+
metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
43
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS skill_consumption_records (
|
|
47
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
48
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
49
|
+
token_id UUID REFERENCES skill_tokens(id),
|
|
50
|
+
tool_name VARCHAR NOT NULL,
|
|
51
|
+
request_id VARCHAR,
|
|
52
|
+
units INT NOT NULL,
|
|
53
|
+
unit_price INT NOT NULL,
|
|
54
|
+
total_cost INT NOT NULL,
|
|
55
|
+
ledger_entry_id UUID REFERENCES skill_ledger_entries(id),
|
|
56
|
+
metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
57
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_skill_ledger_account_id ON skill_ledger_entries(account_id);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_skill_consumption_account_id ON skill_consumption_records(account_id);
|
|
62
|
+
|
|
63
|
+
INSERT INTO skill_feature_consume_rules (feature, unit_type, unit_price, min_charge, max_charge, is_active)
|
|
64
|
+
VALUES ('search', 'per_result', 1, 0, 0, true)
|
|
65
|
+
ON CONFLICT (feature) DO NOTHING;
|
|
66
|
+
|
|
67
|
+
INSERT INTO skill_feature_consume_rules (feature, unit_type, unit_price, min_charge, max_charge, is_active)
|
|
68
|
+
VALUES ('get_location_ids', 'per_call', 0, 0, 0, true)
|
|
69
|
+
ON CONFLICT (feature) DO NOTHING;
|
|
70
|
+
|
|
71
|
+
INSERT INTO skill_feature_consume_rules (feature, unit_type, unit_price, min_charge, max_charge, is_active)
|
|
72
|
+
VALUES ('ping', 'per_call', 0, 0, 0, true)
|
|
73
|
+
ON CONFLICT (feature) DO NOTHING;
|
|
74
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
-- 0003_recharge_and_payments.sql
|
|
2
|
+
-- Recharge packages, orders, and payment transaction tables.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS skill_credit_packages (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
code VARCHAR UNIQUE NOT NULL,
|
|
7
|
+
credits INT NOT NULL,
|
|
8
|
+
price_cents INT NOT NULL,
|
|
9
|
+
list_price_cents INT,
|
|
10
|
+
title VARCHAR,
|
|
11
|
+
description VARCHAR,
|
|
12
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
13
|
+
effective_from TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
14
|
+
effective_to TIMESTAMPTZ,
|
|
15
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS skill_recharge_orders (
|
|
20
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
21
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
22
|
+
order_no VARCHAR UNIQUE NOT NULL,
|
|
23
|
+
package_id UUID REFERENCES skill_credit_packages(id),
|
|
24
|
+
amount_cents INT NOT NULL,
|
|
25
|
+
credits_granted INT NOT NULL,
|
|
26
|
+
channel VARCHAR NOT NULL, -- wechat | alipay
|
|
27
|
+
status VARCHAR NOT NULL DEFAULT 'pending', -- pending | paid | closed | refunded
|
|
28
|
+
idempotency_key VARCHAR UNIQUE,
|
|
29
|
+
paid_at TIMESTAMPTZ,
|
|
30
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE IF NOT EXISTS skill_payment_transactions (
|
|
34
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
35
|
+
order_id UUID NOT NULL REFERENCES skill_recharge_orders(id),
|
|
36
|
+
channel VARCHAR NOT NULL,
|
|
37
|
+
provider_txn_id VARCHAR UNIQUE,
|
|
38
|
+
raw_notify JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
39
|
+
status VARCHAR NOT NULL,
|
|
40
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_skill_recharge_orders_account_id ON skill_recharge_orders(account_id);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_skill_recharge_orders_status ON skill_recharge_orders(status);
|
|
45
|
+
|
|
46
|
+
INSERT INTO skill_credit_packages (code, credits, price_cents, title, description, is_active)
|
|
47
|
+
VALUES
|
|
48
|
+
('D', 100, 2600, 'D 档', '入门体验,1.2 倍单价', true),
|
|
49
|
+
('C', 400, 9400, 'C 档', '轻度使用,1.1 倍单价', true),
|
|
50
|
+
('B', 1600, 34300, 'B 档', '标准包,基准定价', true),
|
|
51
|
+
('A', 5000, 85800, 'A 档', '高频大户,8 折优惠', true)
|
|
52
|
+
ON CONFLICT (code) DO NOTHING;
|
|
53
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- 0004_subscriptions.sql
|
|
2
|
+
-- Minimal subscription schema for renewal gate.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS skill_subscription_plans (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
name VARCHAR NOT NULL,
|
|
7
|
+
price_cents INT NOT NULL,
|
|
8
|
+
credits_per_period INT NOT NULL,
|
|
9
|
+
period_days INT NOT NULL,
|
|
10
|
+
auto_renew BOOLEAN NOT NULL DEFAULT false
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE TABLE IF NOT EXISTS skill_subscriptions (
|
|
14
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
15
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
16
|
+
plan_id UUID NOT NULL REFERENCES skill_subscription_plans(id),
|
|
17
|
+
status VARCHAR NOT NULL DEFAULT 'active', -- active | past_due | grace | canceled | expired
|
|
18
|
+
current_period_start TIMESTAMPTZ NOT NULL,
|
|
19
|
+
current_period_end TIMESTAMPTZ NOT NULL,
|
|
20
|
+
auto_renew BOOLEAN NOT NULL DEFAULT false,
|
|
21
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
CREATE INDEX IF NOT EXISTS idx_skill_subscriptions_account_id ON skill_subscriptions(account_id);
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_skill_subscriptions_status ON skill_subscriptions(status);
|
|
26
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- 0005_admin_config_logs.sql
|
|
2
|
+
-- Config change audit log for admin/ops operations.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS skill_config_change_logs (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
config_type VARCHAR NOT NULL, -- credit_package | consume_rule
|
|
7
|
+
config_key VARCHAR NOT NULL, -- package code or feature
|
|
8
|
+
action VARCHAR NOT NULL, -- create | update | enable | disable
|
|
9
|
+
before_value JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
10
|
+
after_value JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
11
|
+
operator_id UUID,
|
|
12
|
+
operator_email VARCHAR,
|
|
13
|
+
reason VARCHAR,
|
|
14
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_skill_cfg_logs_type_key ON skill_config_change_logs(config_type, config_key);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_skill_cfg_logs_created_at ON skill_config_change_logs(created_at);
|
|
19
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- 0006_sessions.sql
|
|
2
|
+
-- Portal session tokens for account management without password on each request.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS skill_sessions (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
account_id UUID NOT NULL REFERENCES skill_accounts(id),
|
|
7
|
+
session_hash VARCHAR NOT NULL UNIQUE,
|
|
8
|
+
expires_at TIMESTAMPTZ NOT NULL,
|
|
9
|
+
revoked_at TIMESTAMPTZ,
|
|
10
|
+
last_used_at TIMESTAMPTZ,
|
|
11
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_skill_sessions_account_id ON skill_sessions(account_id);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS idx_skill_sessions_expires_at ON skill_sessions(expires_at);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- 0007_order_pay_params.sql
|
|
2
|
+
-- Store gateway prepay payload on recharge orders.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE skill_recharge_orders
|
|
5
|
+
ADD COLUMN IF NOT EXISTS pay_params JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
6
|
+
ADD COLUMN IF NOT EXISTS provider_prepay_id VARCHAR,
|
|
7
|
+
ADD COLUMN IF NOT EXISTS expires_at TIMESTAMPTZ;
|
|
8
|
+
|
|
9
|
+
CREATE INDEX IF NOT EXISTS idx_skill_recharge_orders_order_no ON skill_recharge_orders(order_no);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- 0008_subscription_stripe.sql
|
|
2
|
+
-- Stripe auto-subscription plans + account linkage.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE skill_subscription_plans
|
|
5
|
+
ADD COLUMN IF NOT EXISTS code VARCHAR,
|
|
6
|
+
ADD COLUMN IF NOT EXISTS stripe_product_id VARCHAR,
|
|
7
|
+
ADD COLUMN IF NOT EXISTS stripe_price_id_monthly VARCHAR,
|
|
8
|
+
ADD COLUMN IF NOT EXISTS stripe_price_id_yearly VARCHAR,
|
|
9
|
+
ADD COLUMN IF NOT EXISTS seats INT NOT NULL DEFAULT 1;
|
|
10
|
+
|
|
11
|
+
DO $$
|
|
12
|
+
BEGIN
|
|
13
|
+
IF NOT EXISTS (
|
|
14
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'skill_subscription_plans_code_key'
|
|
15
|
+
) THEN
|
|
16
|
+
ALTER TABLE skill_subscription_plans ADD CONSTRAINT skill_subscription_plans_code_key UNIQUE (code);
|
|
17
|
+
END IF;
|
|
18
|
+
END $$;
|
|
19
|
+
|
|
20
|
+
ALTER TABLE skill_subscriptions
|
|
21
|
+
ADD COLUMN IF NOT EXISTS stripe_subscription_id VARCHAR,
|
|
22
|
+
ADD COLUMN IF NOT EXISTS stripe_customer_id VARCHAR,
|
|
23
|
+
ADD COLUMN IF NOT EXISTS credits_period_month VARCHAR;
|
|
24
|
+
|
|
25
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_skill_subscriptions_stripe_sub_id
|
|
26
|
+
ON skill_subscriptions(stripe_subscription_id) WHERE stripe_subscription_id IS NOT NULL;
|
|
27
|
+
|
|
28
|
+
ALTER TABLE skill_recharge_orders
|
|
29
|
+
ADD COLUMN IF NOT EXISTS order_kind VARCHAR NOT NULL DEFAULT 'one_time',
|
|
30
|
+
ADD COLUMN IF NOT EXISTS plan_code VARCHAR,
|
|
31
|
+
ADD COLUMN IF NOT EXISTS billing_interval VARCHAR;
|
|
32
|
+
|
|
33
|
+
INSERT INTO skill_subscription_plans (
|
|
34
|
+
code, name, price_cents, credits_per_period, period_days, auto_renew,
|
|
35
|
+
stripe_product_id, stripe_price_id_monthly, seats
|
|
36
|
+
) VALUES
|
|
37
|
+
('starter', '基础版 Starter', 4900, 1200, 30, true, 'prod_UkTCwwK294NReq', 'price_1TkyFp1IU0S8vi06Qlg2uLdD', 3),
|
|
38
|
+
('pro', '专业版 Pro', 19900, 6000, 30, true, 'prod_UkTCmMULdliGZ2', 'price_1TkyGO1IU0S8vi060XbAmbAr', 5),
|
|
39
|
+
('growth', '增长版 Growth', 49900, 20000, 30, true, 'prod_UkTD5o9CVt48dU', 'price_1TkyHI1IU0S8vi06h2pdiAQd', 10)
|
|
40
|
+
ON CONFLICT (code) DO UPDATE SET
|
|
41
|
+
name = EXCLUDED.name,
|
|
42
|
+
price_cents = EXCLUDED.price_cents,
|
|
43
|
+
credits_per_period = EXCLUDED.credits_per_period,
|
|
44
|
+
period_days = EXCLUDED.period_days,
|
|
45
|
+
auto_renew = EXCLUDED.auto_renew,
|
|
46
|
+
stripe_product_id = EXCLUDED.stripe_product_id,
|
|
47
|
+
stripe_price_id_monthly = EXCLUDED.stripe_price_id_monthly,
|
|
48
|
+
seats = EXCLUDED.seats;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- 0011_subscription_constraints.sql
|
|
2
|
+
-- One active subscription per account; faster pending-order lookup.
|
|
3
|
+
|
|
4
|
+
-- Keep newest billing period per account when cleaning legacy duplicates.
|
|
5
|
+
WITH ranked AS (
|
|
6
|
+
SELECT id,
|
|
7
|
+
ROW_NUMBER() OVER (
|
|
8
|
+
PARTITION BY account_id
|
|
9
|
+
ORDER BY current_period_end DESC NULLS LAST, created_at DESC
|
|
10
|
+
) AS rn
|
|
11
|
+
FROM skill_subscriptions
|
|
12
|
+
WHERE status = 'active'
|
|
13
|
+
)
|
|
14
|
+
UPDATE skill_subscriptions s
|
|
15
|
+
SET status = 'canceled', auto_renew = false
|
|
16
|
+
FROM ranked r
|
|
17
|
+
WHERE s.id = r.id AND r.rn > 1;
|
|
18
|
+
|
|
19
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_skill_subscriptions_one_active_per_account
|
|
20
|
+
ON skill_subscriptions(account_id)
|
|
21
|
+
WHERE status = 'active';
|
|
22
|
+
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_skill_recharge_orders_sub_pending
|
|
24
|
+
ON skill_recharge_orders(account_id, plan_code, status)
|
|
25
|
+
WHERE order_kind = 'subscription' AND status = 'pending';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Live payment — copy to server /root/apps/skill-service/.env (merge with existing)
|
|
2
|
+
# See docs/PAYMENT_LIVE_SETUP.md and docs/PAYMENT_STRIPE.md
|
|
3
|
+
|
|
4
|
+
PAYMENT_MODE=live
|
|
5
|
+
# Do NOT set true in production unless debugging
|
|
6
|
+
PAYMENT_ALLOW_MOCK_FALLBACK=false
|
|
7
|
+
|
|
8
|
+
SKILL_PUBLIC_BASE_URL=http://15.135.232.100:18080
|
|
9
|
+
|
|
10
|
+
# --- WeChat Pay API v3 (Native QR) ---
|
|
11
|
+
WECHAT_APP_ID=
|
|
12
|
+
WECHAT_MCH_ID=
|
|
13
|
+
WECHAT_MCH_SERIAL_NO=
|
|
14
|
+
# Option A: PEM inline with \n
|
|
15
|
+
WECHAT_MCH_PRIVATE_KEY=
|
|
16
|
+
# Option B: mount file in container e.g. /secrets/wechat_apiclient_key.pem
|
|
17
|
+
WECHAT_MCH_PRIVATE_KEY_PATH=
|
|
18
|
+
WECHAT_API_V3_KEY=
|
|
19
|
+
WECHAT_PLATFORM_PUBLIC_KEY=
|
|
20
|
+
|
|
21
|
+
# --- Alipay ---
|
|
22
|
+
ALIPAY_APP_ID=
|
|
23
|
+
ALIPAY_PRIVATE_KEY=
|
|
24
|
+
ALIPAY_PRIVATE_KEY_PATH=
|
|
25
|
+
ALIPAY_PUBLIC_KEY=
|
|
26
|
+
# Production:
|
|
27
|
+
ALIPAY_GATEWAY_URL=https://openapi.alipay.com/gateway.do
|
|
28
|
+
# Sandbox:
|
|
29
|
+
# ALIPAY_GATEWAY_URL=https://openapi-sandbox.dl.alipaydev.com/gateway.do
|
|
30
|
+
|
|
31
|
+
# --- Stripe (Checkout + Webhook) ---
|
|
32
|
+
STRIPE_SECRET_KEY=sk_test_...
|
|
33
|
+
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
34
|
+
STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
35
|
+
STRIPE_CURRENCY=cny
|