273 lines
9.0 KiB
Markdown
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`
|