Files

273 lines
9.0 KiB
Markdown

# Paymenter Connector Setup (Read-Only + Managed)
Start in `read_only` to validate sync, then move to `managed` for full in-plugin checkout.
## Goal
- Keep package/payment authority in CHD billing backend.
- Let the plugin sync entitlements from CHD.
- Optionally allow direct purchase/upgrade initiation from the plugin in `managed` mode.
## Admin Settings (NuQloud -> Billing + Entitlements)
1. `Managed By CHD` = enabled
2. `Billing Provider` = `Paymenter`
3. `Connector Mode`:
- `Read-only` for sync-only
- `Managed` for registration + checkout + entitlements
4. `CHD Billing Base URL` = your connector API base URL
5. `CHD Entitlements Sync Path` = endpoint path (default: `/api/sovereign/v1/entitlements/sync`)
6. `CHD Instance ID` = unique tenant/instance identifier
7. `CHD Instance Token` = bearer token for connector auth
8. Optional `CHD Instance Secret` = HMAC signing secret
9. `CHD Catalog Path` = endpoint path (default: `/api/sovereign/v1/billing/catalog`)
10. `Catalog Category ID` = Paymenter/connector category id for NuQloud products (optional but recommended)
11. `Catalog Audience Key` = audience rule key from CHD Admin catalog config (optional)
Then:
- Click `Save Billing Connectivity`
- Click `Test Connector (No Apply)`
- Click `Sync Entitlements From CHD`
- For managed checkout: click `Connect Installation + Sync` once, then `Start Buying Services`
## Connector Request From Plugin
Method: `POST`
Path: `{CHD Billing Base URL}{CHD Entitlements Sync Path}`
Headers:
- `Authorization: Bearer <instance token>` (if provided)
- `X-SC-Signature: <hmac_sha256(body, instance secret)>` (if provided)
Body JSON:
```json
{
"instanceId": "my-cloud-instance-001",
"nextcloudPublicUrl": "https://cloud.example.com",
"sovereignMode": "powered",
"billingProvider": "paymenter",
"billingSyncMode": "read_only",
"appVersion": "v1",
"source": "nextcloud-plugin"
}
```
For managed checkout, plugin also sends billing profile fields to connector (`billingProfile`) so the Paymenter customer record can be updated before checkout link generation.
## Catalog Discovery Request (Managed + Read-Only UI)
Method: `POST`
Path: `{CHD Billing Base URL}{CHD Catalog Path}`
Body JSON includes:
1. `instanceId`
2. `nextcloudPublicUrl`
3. `packageTier`
4. `billingProvider`
5. `billingSyncMode`
6. `categoryId` (when configured)
7. `catalogContract: "sc.billing.catalog.v1"`
8. optional context: `audience`, `billingScope`, `billingSubject`, `catalogContext`
## Connector Response (Required)
Return either:
1. Wrapped:
```json
{
"entitlements": {
"packageTier": "nuqloud_starter",
"billingEnabled": true,
"creditsBalance": 500,
"monthlyCredits": 500,
"encryptedCapacityGb": 10,
"replicationTarget": 2,
"userPublishingEnabled": true,
"qappsEnabled": true
}
}
```
2. Flat (same keys at top level).
## Keys Applied By Plugin
- `packageTier`
- `billingEnabled`
- `creditsBalance`
- `monthlyCredits`
- `encryptedCapacityGb`
- `replicationTarget`
- `userPublishingEnabled`
- `qappsEnabled`
## Safety
- `Test Connector (No Apply)` validates connectivity/shape only.
- `Sync Entitlements From CHD` applies values locally.
- Package/credits entitlement fields remain read-only in admin UI.
- Local admins do not directly override paid entitlement values.
## Next (Post-Sandbox)
When sandbox passes, keep same API shape and switch only base URL/token to production connector.
Canonical catalog schema reference:
- `docs/product/connector-catalog-contract-v1.md`
## Legacy Env Mapping (Old -> Current)
Use this when migrating older connector `.env` files.
### Core (typically keep)
- `PORT` -> unchanged. Runtime listen port.
- `HOST` -> unchanged. Runtime bind host.
- `LOG_LEVEL` -> unchanged. Connector logging level.
- `CONNECTOR_MODE` -> unchanged (`paymenter` for production).
- `INSTANCE_REGISTRY_PATH` -> unchanged. Where instance state is stored.
- `ALLOW_UNKNOWN_INSTANCES` -> unchanged. Security toggle for unknown instance requests.
- `ADMIN_API_TOKEN` -> unchanged. Required for CHD admin endpoints.
- `CHD_ADMIN_API_TOKEN` -> alias for `ADMIN_API_TOKEN`.
- `SOVEREIGN_ADMIN_API_TOKEN` -> alias for `ADMIN_API_TOKEN`.
- `REGISTRATION_TOKEN` -> unchanged. Protects install/register endpoint.
- `PAYMENTER_BASE_URL` -> unchanged.
- `PAYMENTER_API_TOKEN` -> unchanged.
- `PAYMENTER_TIMEOUT_MS` -> unchanged.
- `PAYMENTER_TRUST_SCOPED_QUERY_RESULTS` -> unchanged. Keep `false` in production unless you intentionally trust upstream scoped list responses.
### Domain verification (keep if used)
- `CHD_DOMAIN_VERIFY_REQUIRED` -> unchanged.
- `CHD_DOMAIN_VERIFY_TTL_SECONDS` -> unchanged.
- `CHD_DOMAIN_VERIFY_PATH_TEMPLATE` -> unchanged.
- `CHD_DOMAIN_VERIFY_TIMEOUT_MS` -> unchanged.
### Catalog/product mapping
These are still valid, but CHD Admin JSON can override product maps.
- `PAYMENTER_PACKAGE_PRODUCT_MAP` -> unchanged.
- `PAYMENTER_ONE_TIME_PRODUCT_MAP` -> unchanged.
- `PAYMENTER_ADDON_PRODUCT_MAP` -> unchanged (new split naming for monthly add-ons).
- `PAYMENTER_ONE_TIME_LABEL_MAP` -> unchanged.
- `PAYMENTER_ADDON_LABEL_MAP` -> unchanged.
- `PAYMENTER_PACKAGE_PRICE_MAP` -> unchanged (fallback pricing).
- `PAYMENTER_ADDON_PRICE_MAP` -> unchanged (fallback pricing for monthly add-ons).
- `PAYMENTER_ONE_TIME_PRICE_MAP` -> unchanged (fallback pricing).
- `PAYMENTER_PACKAGE_CHECKOUT_PATH_MAP` -> unchanged (public checkout path fallback).
- `PAYMENTER_ONE_TIME_CHECKOUT_PATH_MAP` -> unchanged (public checkout path fallback).
- `PAYMENTER_ADDON_CHECKOUT_PATH_MAP` -> unchanged.
- `PAYMENTER_CATALOG_CATEGORY_ID` -> unchanged.
- `PAYMENTER_CHECKOUT_CATEGORY_SLUG` -> optional storefront category slug used to generate public checkout links from product/category data.
- `PAYMENTER_CHECKOUT_PATH_TEMPLATE` -> optional storefront template, example `/products/{category}/{productSlug}/checkout`.
Precedence:
1. `ADMIN_CATALOG_CONFIG_PATH` JSON (CHD Admin plugin-managed) for product maps/audience rules
2. CHD Admin fallback price maps (`packagePriceMap`, `addonPriceMap`, `oneTimePriceMap`) are used when live Paymenter catalog data does not provide a price label.
3. `.env` map values above as fallback defaults
### Paymenter endpoint overrides (optional)
Still supported and unchanged:
- `PAYMENTER_USERS_ENDPOINT`
- `PAYMENTER_ORDERS_ENDPOINT`
- `PAYMENTER_SERVICES_ENDPOINT`
- `PAYMENTER_CREDITS_ENDPOINT`
- `PAYMENTER_INVOICES_ENDPOINT`
- `PAYMENTER_INVOICE_ITEMS_ENDPOINT_TEMPLATE`
- `PAYMENTER_PRODUCTS_ENDPOINT`
- `PAYMENTER_ADDONS_ENDPOINT`
- `PAYMENTER_PROPERTIES_ENDPOINT`
- `PAYMENTER_CREATE_USER_ENDPOINT`
- `PAYMENTER_CREATE_ORDER_ENDPOINT`
- `PAYMENTER_CHECKOUT_LINK_ENDPOINT`
Connector checkout resolution order:
1. explicit mapped `checkoutPath`
2. generated storefront path from `PAYMENTER_CHECKOUT_CATEGORY_SLUG` + `PAYMENTER_CHECKOUT_PATH_TEMPLATE`
3. custom `PAYMENTER_CHECKOUT_LINK_ENDPOINT`
4. order creation
5. invoice + invoice-item fallback
### Customer + property mapping
- `PAYMENTER_CUSTOMER_EXTERNAL_FIELD` -> unchanged.
- `PAYMENTER_QORTAL_ADDRESS_PROPERTY_KEY` -> unchanged.
- `PAYMENTER_QORTAL_ADDRESS_PROPERTY_NAME` -> unchanged.
- `PAYMENTER_QORTAL_ADDRESS_MODEL_TYPE` -> unchanged.
- `PAYMENTER_QORTAL_ADDRESS_UPSERT_ENDPOINT` -> unchanged.
- `PAYMENTER_QORTAL_ADDRESS_UPSERT_TOKEN` -> unchanged.
- `QORTAL_ADDRESS_UPSERT_ENDPOINT` -> legacy alias (still accepted).
- `QORTAL_ADDRESS_UPSERT_TOKEN` -> legacy alias (still accepted).
### SSO bridge keys
- `SSO_BRIDGE_ENABLED` -> unchanged.
- `SSO_BRIDGE_PAYMENTER_SSO_URL` -> unchanged.
- `SSO_BRIDGE_VERIFY_TOKEN` -> unchanged.
- `SSO_BRIDGE_VERIFY_PATH` -> unchanged.
- `SSO_BRIDGE_TOKEN_TTL_SECONDS` -> unchanged.
- `SSO_BRIDGE_REDIRECT_ALLOWLIST` -> unchanged.
- `SSO_PAYMENTER_URL` -> alias for `SSO_BRIDGE_PAYMENTER_SSO_URL`.
- `SSO_VERIFY_TOKEN` -> alias for `SSO_BRIDGE_VERIFY_TOKEN`.
- `SSO_VERIFY_PATH` -> alias for `SSO_BRIDGE_VERIFY_PATH`.
### No longer used (safe to remove)
- `SOVEREIGN_CONNECTOR_BASE_URL`
- `SOVEREIGN_SSO_VERIFY_PATH`
- `SOVEREIGN_SSO_VERIFY_TOKEN`
- `SOVEREIGN_SSO_TIMEOUT_SECONDS`
### Mock-mode defaults (optional in production)
Only relevant when `CONNECTOR_MODE=mock`:
- `DEFAULT_PACKAGE_TIER`
- `DEFAULT_BILLING_ENABLED`
- `DEFAULT_CREDITS_BALANCE`
- `DEFAULT_MONTHLY_CREDITS`
- `DEFAULT_ENCRYPTED_CAPACITY_GB`
- `DEFAULT_REPLICATION_TARGET`
- `DEFAULT_USER_PUBLISHING_ENABLED`
- `DEFAULT_QAPPS_ENABLED`
## Webhook Clarification
Connector endpoint:
- `POST /api/sovereign/v1/events/paymenter/post-payment`
Purpose:
- Trigger entitlement refresh immediately after payment events.
- Update instance state fields such as `lastPaymentEventAt`, `lastPaymentEventType`, and `lastResolvedEntitlements`.
Auth:
- If `PAYMENTER_WEBHOOK_TOKEN` is set, Paymenter must send header `X-SC-Webhook-Token` with that value.
- If token is empty, endpoint is still callable (not recommended for production).
Recommended Paymenter webhook target:
- `https://<connector-domain>/api/sovereign/v1/events/paymenter/post-payment`
If you are unsure whether Paymenter is calling it, check connector logs for:
- `payment webhook processed`
- `missing_webhook_token`
- `invalid_webhook_token`