> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# サブスクリプションの金額と期間ごとのスケジューリング FAQ

> scheduledAmounts の意味、Waffo が各請求期間の金額をどう決めるか、/subscription/update で変更できること・できないこと（金額の引き下げは可能、引き上げにはプラン変更またはシート追加のトップアップが必要）、金額更新の Webhook、日割り計算のフィールドが存在しない理由。

このページでは、**各請求期間にいくら請求されるか**を扱います。期間ごとに異なる金額の設定、稼働中のサブスクリプションの
金額変更、そして期間の途中での価格変更について Waffo が何をする（そして何をしない）かです。

作成時のバリデーションとステータス値については
[サブスクリプションの作成とバリデーション FAQ](/docs/ja/support/subscription-creation-validation-faq)を参照してください。
開始日の繰り延べ、決済手段、リトライについては
[サブスクリプションのライフサイクルと決済手段の管理](/docs/ja/support/subscription-lifecycle-management)と
[サブスクリプション FAQ](/docs/ja/support/subscription-faq)を参照してください。

## サブスクリプションのリクエストにおける `scheduledAmounts` とは何ですか？

`scheduledAmounts` は `productInfo` 内の任意のリストで、毎期間同じ `amount` を請求する代わりに、
**特定の請求期間に異なる金額**を請求できるようにします。各エントリはちょうど 2 つのフィールドを持ちます。

| フィールド | 型 | 意味 |
| - | - | - |
| `period` | String | この金額が適用される請求期間。正の整数で、`1` = サブスクリプションの**最初の**期間。 |
| `amount` | String | その期間に請求する金額。サブスクリプションと同じ通貨。 |

```json theme={null}
{
  "amount": "99.90",
  "productInfo": {
    "periodType": "MONTHLY",
    "periodInterval": "1",
    "numberOfPeriod": "12",
    "scheduledAmounts": [
      { "period": "1", "amount": "9.90" },
      { "period": "2", "amount": "49.90" }
    ]
  }
}
```

このサブスクリプションは第 1 期に 9.90、第 2 期に 49.90、第 3 期から第 12 期まではすべて 99.90 を請求します。
列挙されていない期間は単に `amount` にフォールバックし、列挙する期間は連続している必要は**ありません**。
第 1 期と第 5 期だけを列挙するのも有効です。

`scheduledAmounts` はサブスクリプション作成時に設定でき、後から `/api/v1/subscription/update` で変更できます。

## `period` は最初の期間から数えますか、それともトライアル後の最初の期間から数えますか？

**サブスクリプションの最初の期間からです。** `period` はすべての請求期間にわたる絶対的な 1 始まりのインデックスであり、
トライアル期間もその数に含まれます。

これはトライアルが存在するときに重要になります。2 期間のトライアルを設定した場合、`period: 1` と `period: 2` は
2 つの**トライアル**期間を指し、通常価格での最初の期間は `period: 3` になります。

| サブスクリプション | `period: 1` が指すもの |
| - | - |
| トライアルなし | 最初の通常の請求 |
| 2 期間のトライアル | **最初のトライアル**の請求 |

どこにもオフセットは適用されません。Waffo はこれから作成する請求の期間番号を調べ、その番号ちょうどで
`scheduledAmounts` を参照します。稼働中のサブスクリプションが現在どこにいるかは、`/api/v1/subscription/inquiry` の
`productInfo.currentPeriod` を読んでください。保存されているプランは同じレスポンスの
`productInfo.scheduledAmounts` として返るため、更新を送る前にどの期間番号がまだ将来なのかを常に確認できます。

## Waffo は各期間の金額をどのように決めますか？

3 つの入力がこの順序で参照され、**最後に**一致したルールが適用されます。

| 優先度 | ルール | 適用条件 |
| - | - | - |
| 1（最高） | `period` がこの期間の番号と一致する `scheduledAmounts` のエントリ | その期間がプランに列挙されている |
| 2 | `trialPeriodAmount` | この期間の番号が `numberOfTrialPeriod` の範囲内で、スケジュール金額が一致しなかった |
| 3（フォールバック） | `amount` | 上記のいずれも一致しなかった |

したがって、`scheduledAmounts` のエントリはその期間について**トライアル金額を上書きします**。トライアルを
`trialPeriodAmount` で請求したい場合は、トライアル期間の番号を `scheduledAmounts` に列挙しないでください。

請求が想定と一致しないときに最初に確認すべきはこれです。その請求の期間番号を割り出し、3 つのルールを順に辿ってください。

## `scheduledAmounts` の正確な制限は何ですか？

| 制約 | ルール | 違反した場合 |
| - | - | - |
| リストの長さ | 最大 **10** エントリ | パラメーターのバリデーションエラー |
| `period` | 正の整数（`≥ 1`） | パラメーターのバリデーションエラー |
| `period` の一意性 | 1 リクエスト内に重複なし | パラメーターのバリデーションエラー、メッセージは `scheduledAmounts.period must be unique` |
| `period` の上限（作成時） | `numberOfPeriod` を超えてはならない | 該当する期間を示すパラメーターのバリデーションエラー |
| `period` の上限（更新時） | サブスクリプションの最終期間数を超えてはならない | 該当する期間を示すパラメーターのバリデーションエラー |
| `period` の下限（更新時） | 現在の期間より**厳密に大きい**必要がある | 現在の期間を示すパラメーターのバリデーションエラー |
| `amount` | エントリごとに必須。負であってはならない | パラメーターのバリデーションエラー |
| `amount` の精度 | 通貨の ISO 4217 のスケール、およびその通貨の整数単位倍数のルールに一致する必要がある | 金額の小数エラー |
| `amount` の範囲 | サブスクリプション契約の金額範囲内である必要がある | 金額範囲外エラー |

逆に想定されがちな 2 点を明示しておきます。

* **金額は最小単位ではなく、通貨の通常の単位での小数文字列です。** `"990"` ではなく `"9.90"` です。余分な小数桁は
  丸められるのではなく**拒否されます**。
* **`amount: "0"` はフィールドのバリデーションを通過する**ため、無料の期間を表現できます。ただしその値は契約上の
  最小金額を満たす必要があるため、0 が受け付けられるかどうかは契約次第です。

## 次の期間のサブスクリプション金額を直接引き上げられますか？

**いいえ。`/api/v1/subscription/update` ではできません。** 既定では、このエンドポイントはあらゆる引き上げを拒否します。
これは 3 つの金額フィールドすべてで強制されます。

| フィールド | ルール |
| - | - |
| `amount` | 新しい値は現在の `amount` **以下**である必要がある |
| `productInfo.trialPeriodAmount` | 新しい値は現在のトライアル金額**以下**である必要がある |
| `productInfo.scheduledAmounts[].amount` | 期間ごとに、新しい値はその期間の基準値**以下**である必要がある |

期間ごとの基準値は、**その同じ期間について現在保存されているスケジュール金額**、またはその期間が保存済みプランに
ない場合はサブスクリプションの `amount` です。これにより明らかな抜け道が塞がれます。ある期間をいったん引き下げてから
2 回目の呼び出しで元に戻すことはできません。2 回目の呼び出しは、たった今書き込んだ値と比較されるからです。

違反はパラメーターエラーとして返り、メッセージには拒否された内容が示されます
（`amount is not allowed to increase`、
`trialPeriodAmount is not allowed to increase`、
`scheduledAmounts.amount is not allowed to increase for period N`）。

**より多く**請求するには、`/api/v1/subscription/change` を使ってユーザーを新しいプランに移すか、引き上げが
シート追加である場合は `topupInfo` ブロックを付けて更新を送ってください。この経路は現在の期間の差額を直ちに回収し、
次の期間から `amount` を引き上げることが許可されています（下の日割りの表を参照）。`update` による単純な引き上げは
一般のアカウントには開放されていません。連携上どうしても必要だと考える場合は、回避策を設計するのではなく
連携サポートに相談してください。

## 日割り計算（prorate）はどう設定しますか？

**日割りのフィールドは存在せず、Waffo は日割り計算を行いません。** `prorate` / `proration_behavior` のような
パラメーターを探している場合、それは `/subscription/update` にも `/subscription/change` にも存在しません。

貴社側で何を実装すべきかを判断できるよう、各ケースで実際に何が起こるかを示します。

| したいこと | Waffo がすること | 貴社がすべきこと |
| - | - | - |
| 次の期間以降の金額を変更する | `/subscription/update` が**次の請求期間から**新しい金額を適用します。現在の期間は影響を受けず、その期間についてのクレジットやデビットは計算されません。 | 追加の作業はありません。ただし期間の按分調整を期待しないでください。 |
| ユーザーを別のプランに移す | `/subscription/change` は元のサブスクリプションをロックし、**それを元にした新しいサブスクリプションを作成**します。繰り越す残存価値を渡すことができ、Waffo は新しいサブスクリプションの請求に対してそれを取り崩します。 | 繰り越す価値は貴社自身で計算し、変更リクエストで渡してください。Waffo は計算しません。 |
| 期間途中の差額を直ちに回収する | `topupInfo` ブロックを付けた `/subscription/update`（**シート追加**）は、現在の期間内の追加注文として `topupAmount` を直ちに請求し、次の期間から新しい `amount` を適用します。`topupAmount` は貴社が計算し、Waffo は日割りしません。 | `topupInfo` を送信してください（冪等キーとしての `topupRequest`、`topupAmount`、任意の `description` と `orderExpiredAt`）。レスポンスにはトップアップの注文とそのステータスが含まれます。新しい金額はその請求が成功した時点で初めて適用されます。あるいは、差額を別の単発の注文として回収してください。 |

要するに、金額の変更は**期間の境界で起こるイベント**であり、変更が期間の途中に発生したことによって動かすべき資金は、
貴社が計算し、貴社が回収するものです。

## `/subscription/update` は正確に何を変更し、いつ有効になりますか？

変更するのは金額のみで、次の請求期間以降に適用されます。

**変更できるもの：** `amount`、`productInfo.trialPeriodAmount`、`productInfo.scheduledAmounts`。個別にも組み合わせても
可能です。3 つのうち少なくとも 1 つが存在しなければリクエストは拒否されます。

**変更しないもの：** プラン、`periodType`、`periodInterval`、残りの期間数、請求日、決済手段。日割りを発生させず、
新しいサブスクリプションも作成しません。

**タイミング：** 新しい値は次の期間から適用されます。すでに生成済み、または進行中である現在の期間の請求には
影響**しません**。レスポンスは変更が適用される期間番号を示します。

| レスポンスのフィールド | 意味 |
| - | - |
| `subscriptionId` / `subscriptionRequest` | サブスクリプションを識別 |
| `previousAmount` / `newAmount` | 変更前後の基本金額（変更がなければ同じ） |
| `previousTrialPeriodAmount` / `newTrialPeriodAmount` | 変更前後のトライアル金額 |
| `previousScheduledAmounts` / `newScheduledAmounts` | 変更前後のプラン。プランが保存されていなかった場合は省略 |
| `nextEffectivePeriod` | 新しい金額が適用される**期間番号** |

## 金額の更新はどのような場合に直ちに拒否されますか？

| 条件 | 動作 |
| - | - |
| `subscriptionRequest` も `subscriptionId` も指定されていない | 拒否 |
| `amount` / `trialPeriodAmount` / `scheduledAmounts` のいずれも指定されていない | 拒否 |
| 貴社の MID 配下にそのサブスクリプションが存在しない | Not-found エラー |
| サブスクリプションが `ACTIVE` でない | 拒否 — ステータスエラー |
| サブスクリプションがすでに最終期間に達している | 最終期間番号をメッセージに含めて拒否 |
| トライアル終了後に `trialPeriodAmount` を送信 | 拒否 — トライアル金額はもう変更できない |
| サブスクリプションのスケジュールが Waffo ではなく決済手段によって駆動されている | そのサブスクリプションではサポート対象外 |
| 同じサブスクリプションについて別の更新または更新（継続課金）が処理中 | 拒否 — 少し待って再試行 |

最後の行は、更新がサブスクリプションごとに**直列化される**ことを意味します。多数のサブスクリプションを再価格設定する
場合、「変更処理中のため後で再試行してください」というレスポンスは失敗ではなくリトライ可能なものとして扱ってください。

## 更新で `scheduledAmounts` を送ると、既存のプランとマージされますか？

**いいえ。送信したリストが保存済みプラン全体を置き換えます。** パッチではありません。旧プランに存在してリクエストに
ない期間はスケジュール金額を失い、`amount` にフォールバックします。

設計上考慮すべき 2 つの帰結：

* 変更する期間だけでなく、価格を設定したい将来の期間の**完全な**セットを常に送信してください。
* 更新は現在の期間**より後**の期間しか指定できないため、すでに請求済みの期間のエントリはプランを置き換える際に
  保存から除かれます。これは想定どおりで、すでに発生した請求が変わることはありません。

**空の配列**の送信、またはフィールドの省略は*変更なし*として扱われ、プランをクリアすることは**ありません**。
`/subscription/update` でスケジュール金額のプランをクリアする方法はありません。単一の一律金額に戻すには、
残りの将来の期間すべてを希望の金額で列挙するか、`/subscription/change` でユーザーを新しいプランに移してください。

## アップグレードやダウングレードのとき、`scheduledAmounts` はどうなりますか？

何も引き継がれません。`/subscription/change` は**新しい**サブスクリプションを作成し、その新しいサブスクリプションの
`amount` と `scheduledAmounts` は**すべて変更リクエストから**取られます。そこで `scheduledAmounts` を省略すると、
新しいサブスクリプションには期間ごとのプランがまったくなく、すべての期間が新しい `amount` で請求されます。

したがって、段階的な価格の推移をアップグレード後も維持したい場合は、変更リクエストで改めて記述する必要があります。

## エンドユーザーに金額の変更は伝えられますか？

はい。金額の更新が成功すると、Waffo は加入者にメールを送信します。メールには変更前の金額、新しい金額、変更前と
変更後の期間ごとのプラン、そして変更が有効になる期間番号が記載されます。

運用上の注意が 2 点：

* メールは、貴社のアカウントとプロダクトで金額変更の通知が有効になっている場合にのみ送信されます。オフになっていれば
  ユーザーには何も送信されません。
* 送信はベストエフォートかつ非同期です。メールの失敗によって金額の変更がロールバックされることは**ありません**。
  変更内容の記録は API のレスポンスです。

## 金額の更新が成功したとき、Waffo は Webhook を送りますか？

はい。`/subscription/update` が成功すると、Waffo はサブスクリプションに保存された `notifyUrl` に
**`SUBSCRIPTION_UPDATE_NOTIFICATION`** をプッシュします。単純な金額変更では更新が確定した時点で送信され、
シート追加（下記参照）ではトップアップの請求が成功して新しい金額が適用された時点で送信されます。ペイロードは
照会 API が返すサブスクリプションそのものなので、すでに新しい金額が反映されています。

貴社の記録を揃えるために：

* `/subscription/update` のレスポンスを主たる記録として扱い、`newAmount`、`newScheduledAmounts`、
  `nextEffectivePeriod` を読み取って保存してください。Webhook は同じ変更を非同期に確認するものであり、変更が
  即時のリクエスト経路の外で確定した場合（トップアップのケース）に使うべきシグナルです。
* 各期間の**実際に請求された金額**については、期間ごとの通知とサブスクリプション決済注文の通知を引き続き受信して
  ください。それらが実際に徴収された金額を反映しており、照合すべき数値です。

## そもそもどのサブスクリプションが期間ごとの金額を使えますか？

期間ごとの金額と `/subscription/update` は、**Waffo が請求スケジュールを駆動する**サブスクリプションで利用できます。
一部の決済手段では決済手段自身がスケジュールを駆動します。そのようなサブスクリプションは作成時に `scheduledAmounts` を
拒否し、金額更新の対象にもなりません。作成呼び出しでスケジュール金額がそのサブスクリプションではサポートされていないと
返ってきた場合の理由はこれです。修正すべきはリクエストの形ではなく、別の決済手段です。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.