コンテンツにスキップ
getnextpdf.com

Enterprise エディション

課金 — 詳細リファレンス

このページは、NextPDF Enterprise の課金サーフェスに関する詳細リファレンスです。このサーフェスには 2 つのレイヤーがあります。NextPDF\Enterprise\Billing の課金モデルは、プランティア、クォータ、超過ポリシー、重複排除された利用状況アラートを定義します。NextPDF\Enterprise\Billing\Substrate の強制 substrate は、そのモデルをライブのリクエストパス上に、フェイルクローズドかつ並行安全に配置します。エントリーポイントは PlanRegistryQuotaManagerOverageCalculatorBillingAlertServiceQuotaEnforcementGuard です。ワークフローレベルのガイドについては、課金の機能ページを参照してください。

この機能は NextPDF Enterprisenextpdf/enterprise)で提供され、Enterprise ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイメントは、この機能のクラスをロードしません。エディションを比較してライセンスを取得する

課金は Enterprise の基本機能であり、機能ごとの個別のフラグはありません。Core パッケージの隣に Enterprise パッケージがインストールされれば利用できます。NextPDF Core(Apache-2.0)と NextPDF Pro には、プラン、クォータ、超過のモデルがありません。このサーフェスには下位ティア相当のものが存在しません。プランの包含内容、クォータ、商業条件は、実行時の強制ではなくライセンス契約によって定められます。このリファレンスは法的または契約上の見解ではありません。

すべてのシンボルは NextPDF\Enterprise\Billing の下にあります。substrate とマークされた行は NextPDF\Enterprise\Billing\Substrate の下にあります。TenantContextNextPDF\Enterprise\SaaS の認証済みテナント型です。

シンボルパラメーターデフォルトの挙動戻り値スロー/失敗条件備考
SaaSPlan(enum)文字列ベースのプランティア。standardadvancedhigh_controlスローしないlabel() は表示名を返す
PlanDefinition::__constructSaaSPlan $plan, float $includedCuQuota, list<CapabilityCode> $capabilities, non-empty-string $priceTier, bool $intelligencePackIncluded, bool $privacyPackIncluded不変のプラン値オブジェクト。入力をそのまま格納新しいインスタンススローしないfinal readonly。昇格されたパブリックプロパティ
PlanDefinition::includesCapabilityCapabilityCode $capability厳密な同一性メンバーシップチェックboolスローしない
PlanRegistry::__constructlist<PlanDefinition> $definitions定義をティアごとにインデックス化。ティアごとに最後の定義が優先新しいレジストリスローしないテストおよびホワイトラベルのプランセット向け
PlanRegistry::getSaaSPlan $plan正規のプランルックアップPlanDefinitionプランが未登録の場合は InvalidArgumentException
PlanRegistry::hasSaaSPlan $plan登録の有無を確認boolスローしない
PlanRegistry::defaultRegistry(static)本番デフォルト。Standard 1,000 CU、Advanced 5,000 CU+Intelligence Pack、High Control 20,000 CU+Intelligence Pack および Privacy PackPlanRegistryスローしない契約条件でカスタム定義が求められない限り使用
OveragePolicy(enum)hard_stopsoft_stopbudget_alertスローしないhttpStatusCode() は 402 / 429 / 200 にマッピング。isBlocking() はハードストップとソフトストップのみ true
QuotaManager::__constructPlanRegistry $planRegistry, OveragePolicy $overagePolicyレジストリを 1 つのポリシーにバインド新しいインスタンススローしない
QuotaManager::checkQuotaTenantContext $tenant, SaaSPlan $plan, float $currentCuクォータ以下、または非ブロッキングポリシーの下では静かに返すvoidブロッキングポリシーの下での厳密な超過時は QuotaExceededException。未登録プランの場合はレジストリからの InvalidArgumentExceptionresetsAt = 翌月初日、UTC 真夜中
QuotaManager::remainingQuotaSaaSPlan $plan, float $currentCu純粋な読み取り。決してブロックしないfloatレジストリの InvalidArgumentException超過時はマイナス
QuotaManager::usagePercentageSaaSPlan $plan, float $currentCu純粋な読み取り。決してブロックしないfloatレジストリの InvalidArgumentException包含クォータが非正の場合は 0.0。超過時は 1.0 を超える
OverageCalculator::calculatePlanDefinition $plan, float $currentCu不変の超過スナップショットを算出OverageResultスローしないfinal readonly、ステートレス
OverageResultincludedCu, usedCu, overageCu, usageRatio, isOverage不変の計算結果スローしないoverageCu = max(0, used - included)isOverage は厳密な超過を要求
BillingAlertType(enum)quota_warning_80quota_warning_100budget_exceededmonthly_cap_reachedスローしないthreshold() は 0.8 / 1.0 / 1.0 / 1.0。severity() は warning / critical / critical / critical
BillingAlertService::__constructAlertStateRepositoryInterface $alertState重複排除ストアをバインド新しいインスタンススローしない
BillingAlertService::evaluateTenantContext $tenant, SaaSPlan $plan, PlanDefinition $planDef, float $currentCuまだ発火していないアラートをしきい値の昇順で発火し記録list<BillingAlertType>プランと定義の不一致時は InvalidArgumentException重複排除キー。テナント、タイプ、UTC YYYY-MM 期間
BillingAlertService::clearAlertsTenantContext $tenant現在の UTC 期間におけるテナントの発火状態をクリアvoidリポジトリ定義の失敗は伝播同一期間内でアラートを再アーム
AlertStateRepositoryInterfacehasAlertFired(), markAlertFired(), clearForPeriod()耐久性のあるアラート重複排除の永続化コントラクトメソッドごと実装定義オペレーターがレプリカ間の耐久性を所有
InMemoryAlertStateRepository配列ベースの発火状態インターフェイスに準拠スローしない単一リクエストのライフサイクルとテストのみ
QuotaExceededException読み取り専用の currentCu, limitCu, resetsAt, tenantId, isSaaSデプロイメントモードを認識するクォータ拒否スロー対象そのものhttpStatusCode() は 402 SaaS / 403 オンプレム。specCode()SPEC-BILLING-003 / SPEC-LIC-001toErrorEnvelope() は構造化されたエラーボディを生成
DeploymentMode(enum)saasself_hosted_osslocal_developmentスローしないSubstrate. enforcesQuota()Saas のみ true。オプトアウトは常に明示的
QuotaEnforcementGuard::__constructDeploymentMode, PlanResolverInterface, QuotaManager, UsageCounterStoreInterfaceライブクォータゲートを組み立て新しいインスタンススローしないSubstrate. final readonly
QuotaEnforcementGuard::enforce?TenantContext $tenant, non-empty-string $featureKey, float $amount = 1.0アトミックな予約を伴うフェイルクローズドなクォータゲートQuotaDecision(許可された結果のみ)下記の拒否分類を参照Substrate. テナント認証の後、課金対象ハンドラーの前にマウント
PlanResolverInterface::resolveTenantContext $tenantテナントをそのプランと機能ごとのポリシーに解決ResolvedPlanNoPlanForTenantExceptionSubstrate. 未知のテナントに対するデフォルトプランのフォールバックは欠陥
RegistryPlanResolverarray<non-empty-string, ResolvedPlan> $plansByTenantマップベースのリゾルバーResolvedPlanマッピングされていないテナントには NoPlanForTenantExceptionSubstrate. 構造上フェイルクローズド
ResolvedPlan::policyFornon-empty-string $featureKey解決済みプラン上のポリシールックアップ?QuotaPolicyスローしないSubstrate. null は未知の機能を意味し、ガードはそれを拒否
QuotaPolicynon-empty-string $featureKey, float $limit, OveragePolicy $overagePolicy機能ごとの上限と超過ポリシースローしないSubstrate. UNLIMITED = -1.00.0 の上限は無制限ではなくゼロ許容。isUnlimited()isBlocking()
QuotaDecision静的メソッド bypassed(), unlimited(), consumed()許可結果の値オブジェクトQuotaDecisionスローしないSubstrate. isAllowed() は常に true。拒否は代わりにすべてスロー
UsageCounter行スナップショット。テナント、機能、期間境界、used, limit, updatedAt不変の利用状況行スローしないSubstrate. remaining() はマイナスになり得る。wouldExceed() は厳密
UsageCounterStoreInterface::getテナント、機能、期間境界、float $limit利用状況行を読み取り、存在しない場合は used = 0 で作成UsageCounterUsageStoreUnavailableExceptionSubstrate. バックエンド障害時に falsy 値を返すことはない
UsageCounterStoreInterface::tryConsumeテナント、機能、期間境界、float $amount, float $limit上限内でのアトミックな比較設定(compare-and-set)予約?UsageCounter(予約が上限を超える場合は nullUsageStoreUnavailableExceptionSubstrate. バッキングストアに対する単一のアトミック操作でなければならない
InMemoryUsageCounterStoreストアコントラクトのインプロセス参照実装インターフェイスに準拠インターフェイスに準拠Substrate. 単一プロセスのみ。アトミック性の不変条件を文書化
QuotaEnforcementException(abstract)すべての substrate 拒否の基底型スロー可能なファミリーSubstrate. 各サブタイプが httpStatusCode() を宣言
public function checkQuota(TenantContext $tenant, SaaSPlan $plan, float $currentCu): void
public function evaluate(
TenantContext $tenant,
SaaSPlan $plan,
PlanDefinition $planDef,
float $currentCu,
): array
public function enforce(?TenantContext $tenant, string $featureKey, float $amount = 1.0): QuotaDecision
public function tryConsume(
string $tenantId,
string $featureKey,
DateTimeImmutable $periodStart,
DateTimeImmutable $periodEnd,
float $amount,
float $limit,
): ?UsageCounter;

QuotaEnforcementGuard::enforce の拒否分類

例外HTTP ステータス発生条件
MissingTenantContextException401SaaS モードで認証済みテナントコンテキストがない場合
NoPlanForTenantException402リゾルバーがテナントに割り当てられたプランを見つけられない場合
UnknownFeatureException402解決済みプランが機能キーに対するポリシーを定義していない場合
UsageStoreUnavailableException503利用状況ストアを読み取れない、またはアトミックに更新できない場合。非正の $amount に対しても発生
QuotaExceededException402(SaaS) / 403(オンプレム)ブロッキングポリシーのクォータを超過した場合、または並行する予約が最後の余裕を消費した場合
  • デフォルトのレジストリは、増加する CU クォータと機能セットを持つ 3 つのティア(Standard / Advanced / High Control)を同梱します。未登録のプランへのリクエストは、明示的な InvalidArgumentException で失敗します。
  • QuotaManager::checkQuota() は、両方の条件が成り立つ場合にのみ発生します。ポリシーがブロッキングであり、かつ現在の利用状況が包含クォータを厳密に上回っている場合です。バジェットアラートポリシーは決して発生させません。超過はアラートを通じて通知されます。
  • remainingQuota()usagePercentage() は純粋な読み取りであり、決してブロックしません。残りクォータは超過時にマイナスになり、利用率は超過時に 1.0 を超えます。
  • アラートはしきい値の昇順で評価されます。80% 警告、100% 警告(critical)、続いてバジェット超過(critical)です。バジェット超過は厳密な超過でゲートされます。ちょうど 100% の利用状況は、バジェット超過ではなく 100% 警告を発火します。
  • 各アラートタイプは、テナントごと、課金期間ごとに最大 1 回発火します。発火状態は AlertStateRepositoryInterface を通じて記録されるため、重複排除は選択された実装と同程度に耐久性があります。
  • 重複排除キーは UTC YYYY-MM 期間を埋め込んでいます。したがって、新しい暦月はすべてのアラートタイプを自動的に再アームします。ロールオーバーの再アームにクリア呼び出しは不要です。clearAlerts() は現在の期間をクリアし、たとえばプランのアップグレード後など、期間の途中でアラートを再アームします。
  • evaluate() のプラン不一致ガードは、供給されたプランとプラン定義が食い違う呼び出しを拒否し、テナントのプランとは異なるティアの定義から保護します。
  • すべての期間演算は UTC に固定されています。クォータ超過のリセット時刻は、翌暦月の初日の UTC 真夜中です。ソフトストップレスポンスは、これを再試行の期限として通知すべきです。
  • QuotaEnforcementGuard は SaaS モードでフェイルクローズドです。テナントの欠落、プランの欠落、未知の機能、ストア障害、クォータ超過はすべて拒否します。暗黙の許可へすり抜けるものはありません。非 SaaS のデプロイメントは、非 SaaS の DeploymentMode でガードを構築することによってのみオプトアウトします。
  • ブロッキングポリシーは、アトミックな比較設定(compare-and-set)である UsageCounterStoreInterface::tryConsume を通じて利用状況を予約します。並行するリクエストが集合的に利用状況を上限を超えて押し上げることはできません。競合に敗れた側は、事前チェックを通過していても QuotaExceededException を受け取ります。
  • バジェットアラートポリシーの下では、ガードは消費をベストエフォートで記録し、決して拒否しません。ソフト上限を超えた予約でも、行を上限で記録します。
  • QuotaExceededException はデプロイメントモードを認識します。SaaS の拒否は spec コード SPEC-BILLING-003 を伴う HTTP 402 にマッピングされ、再試行可能とマークされます。オンプレムの拒否は SPEC-LIC-001 を伴う HTTP 403 にマッピングされます。
  • ライブラリ自体は HTTP レスポンスを発行しません。宣言されたステータスコードはエッジレイヤーのためのコントラクトであり、エッジレイヤーはスローされた拒否をレスポンスにマッピングし、課金対象ハンドラーを呼び出してはなりません。
  • 非正の包含クォータ。 usagePercentage()evaluate()OverageCalculator::calculate() はいずれも、ゼロ除算の代わりに 0.0 の利用率を生じます。その場合、しきい値アラートは利用率のみからは決して発火しません。
  • バジェットアラートに加えて大きな超過。 マネージャーとガードはいずれも許可結果を返します。例外がないことを、クォータ内であることの証拠として扱わないでください。OverageResult またはアラートストリームを参照してください。
  • 上限にちょうど到達。 currentCu == includedCuQuota における checkQuota() は通過します。BudgetExceeded は厳密な超過を要求します。UsageCounter::wouldExceed() も同様に厳密です。
  • MonthlyCapReached enum はこの 4 番目のアラートタイプを宣言していますが、BillingAlertService::evaluate() はこれを決して発行しません。その候補リストは 3 つのしきい値アラートのみを対象とします。これは、このモジュールの外部にある上限追跡のエミッター向けに予約されています。
  • 重複するティア定義。 PlanRegistry はティア値でインデックス化し、あるティアに対する最後の定義が以前のものを暗黙のうちに置き換えます。重複排除されたリストからレジストリを構築してください。
  • ゼロ許容と無制限。 QuotaPolicy の上限 0.0 は、その期間内のすべての消費が超過であることを意味します。計量を無効にするのは負の UNLIMITED センチネルだけです。isUnlimited() は決してブロックしません。
  • 非正の予約量。 enforce() は非正の $amountUsageStoreUnavailableException(503)でフェイルクローズドに拒否します。これは呼び出し元の欠陥であり、ストア障害ではありません。
  • ストア障害。 読み取りまたは予約の失敗はすべて UsageStoreUnavailableException として表面化し、拒否します。ガードは、メーターがダウンしている間、計量されない処理を決して許可しません。
  • インメモリ実装。 InMemoryAlertStateRepositoryInMemoryUsageCounterStore は、単一の PHP プロセス内でのみ正しく動作します。マルチレプリカのデプロイメントは、真のアトミック性を備えたデータストアに裏打ちされた実装を提供しなければなりません。読み取り後書き込みのストアは、負荷時にクォータ超過を許してしまう欠陥です。
  • FIPS モード。 課金はそれ自体の暗号操作を実行せず、FIPS 固有の挙動を持ちません。課金が消費するテナント識別情報は、その FIPS 姿勢が SaaS サーフェスとあわせて文書化された認証済みのコンテキストから発生しなければなりません。
主張標準条項
402 ステータスコードは将来の使用のために予約されており、それ自体に規範的なリクエストセマンティクスを持ちません。RFC 9110§15.5.3
429 は、クライアントが一定時間内に過剰なリクエストを送信したこと(「レート制限」)を示します。RFC 6585§4
Retry-After は、ユーザーエージェントが後続のリクエストを行う前にどれだけ待つべきかを示します。RFC 9110§10.2.3

すべての条項は言い換えであり、NextPDF は規範的なテキストを複製しません。NextPDF は、このサーフェスについて HTTP プロトコルの適合性または認証の主張を一切行いません。 OveragePolicy::httpStatusCode() が宣言する 402 / 429 / 200 のマッピングと、ガードの 401 / 402 / 503 の拒否コードは、上記の条項に沿った製品上の慣例です。RFC 9110 は 402 を予約しているため、ここでの支払い拒否としての用法は、IETF が定義したセマンティクスではなく、業界で一般的な慣例です。ソフトストップの再試行の期限(resetsAt)は、エッジレイヤーが Retry-After のガイダンスとして表出すべき値です。実際の HTTP レスポンス、ヘッダー、キャッシュ挙動の発行は、ホスティングアプリケーションの責任です。

  • モデルは PlanRegistry::defaultRegistry()、1 つの OveragePolicyQuotaManager から構成します。アラート機能には、耐久性のある AlertStateRepositoryInterface 実装を伴う BillingAlertService を追加します。
  • QuotaEnforcementGuard は、リクエストパイプラインのテナント認証の後、課金対象ハンドラーの前にマウントします。エッジで QuotaEnforcementException と課金の QuotaExceededException を捕捉し、httpStatusCode() をレスポンスにマッピングします。
  • このモジュール内のプラン定義は、課金の単一の信頼できるソースです。デプロイメント内の他の場所で並行する課金定義を維持しないでください。
  • インメモリ実装により、サーフェス全体が I/O なしでユニットテスト可能になります。推奨される境界テストは、クォータちょうどの利用状況、1 単位上、0.8 と 1.0 の利用率しきい値、プラン不一致ガード、CAS 競合(最後の余裕 1 単位に対する 2 つの予約)、そしてストア障害の拒否です。
  • コアモデルのクラスは @since 2.2.0 を持ち、substrate は @since 2.3.0 を持ちます。現在のパッケージラインは 3.1.0 です。
  • オペレーターは、アラート状態リポジトリと利用状況ストアの実装、それらのレプリカ間の耐久性、そして clearAlerts() を通じた期間途中のアラート再アームを所有します。

このページは、外部から観測できる挙動とサポートされているパブリック API サーフェスのみを文書化します。内部の名前空間パス、ヘルパークラス、メカニズムテーブル、ランブックのファイル名、チケットプレフィックスは対象外です。