-
Notifications
You must be signed in to change notification settings - Fork 436
negotiate payment terms as a checkout selection #692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: raginpirate/payment-terms-simple
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| "final_sale", | ||
| "prop65", | ||
| "fulfillment_changed", | ||
| "payment_term_changed", | ||
| "age_restricted" | ||
| ] | ||
| } | ||
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,25 +2,48 @@ | |
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "https://ucp.dev/schemas/shopping/types/payment_schedule.json", | ||
| "title": "Payment Schedule", | ||
| "description": "A named payment obligation within a payment term. Timing is disclosed in buyer-facing text while totals provide a structured allocation amount.", | ||
| "description": "A single payment that settles part or all of the checkout under a payment term. Timing is stated in buyer-facing text; `type` and `due_at` are supplementary machine-readable signals derived from it.", | ||
| "type": "object", | ||
| "required": ["id", "type", "description", "totals"], | ||
| "required": [ | ||
| "id", | ||
| "type", | ||
| "description", | ||
| "totals" | ||
| ], | ||
| "additionalProperties": true, | ||
| "properties": { | ||
| "id": { | ||
| "type": "string", | ||
| "description": "Unique identifier for this payment schedule." | ||
| "description": "Identifier for this payment schedule, unique within its payment term. Businesses SHOULD keep it stable across responses while the schedule remains the same payment." | ||
| }, | ||
| "type": { | ||
| "$ref": "schedule_type.json", | ||
| "description": "Broad payment timing class. Well-known values: `immediate` and `deferred`." | ||
| "type": "string", | ||
| "description": "Timing class, drawn from an open vocabulary. `immediate` is the only value with defined meaning: the payment is captured when the checkout is completed. Any other value means the payment is not captured at completion, and `description` states when it is due. Businesses MAY use additional values (e.g. `deferred`, `on_shipment`); Platforms MUST treat unrecognized values as not captured at completion." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this describe when payment is due rather than when it is captured? Capture is payment-handler behavior: an amount can be due at completion but only authorized then and captured later. Defining |
||
| }, | ||
| "description": { | ||
| "$ref": "../../common/types/description.json", | ||
| "description": "Complete buyer-facing statement of when and how this payment is due. Businesses MUST make this field sufficient on its own: a Platform that recognizes no `type` value and reads no other field MUST be able to present this schedule correctly. Platforms MAY use `type` and `due_at` for enhanced presentation, but MUST NOT present derived timing that contradicts this field." | ||
| }, | ||
| "due_at": { | ||
| "type": "string", | ||
| "description": "Complete buyer-facing explanation of when and how the payment is due." | ||
| "format": "date-time", | ||
| "description": "Absolute RFC 3339 date-time when this payment is due, when the Business can determine one at checkout. Supplementary to `description`, never a replacement for it. Omitted when the due date depends on a future event (e.g. 'due on delivery'); the timing is then stated in `description` alone." | ||
| }, | ||
| "totals": { | ||
| "$ref": "totals.json", | ||
| "description": "Aggregate pricing breakdown for every payment represented by this schedule. The entry with `type: total` is the complete amount allocated to the schedule in the checkout or order currency." | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { "$ref": "total.json" }, | ||
| { | ||
| "if": { "properties": { "type": { "const": "total" } }, "required": ["type"] }, | ||
| "then": { "properties": { "amount": { "minimum": 0 } } } | ||
| } | ||
| ] | ||
| }, | ||
| "contains": { "properties": { "type": { "const": "total" } }, "required": ["type"] }, | ||
| "minContains": 1, | ||
| "maxContains": 1, | ||
| "description": "What this one payment costs. Businesses MUST include exactly one `total` entry with a non-negative amount: the final amount charged when this payment is taken, inclusive of tax and every other charge, in the checkout currency's minor units (ISO 4217). Unlike checkout totals, no `subtotal` is required, because the purchase is priced at the checkout rather than once per payment." | ||
| } | ||
| } | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we simplify the lifecycle by requiring the selected term to be established in an authoritative Update-Checkout response before Complete? Changing the term would happen through Update, which returns the final totals, disclosures, and eligible handlers. Complete would then echo the same
selected_term_idas an assertion and reject any mismatch, rather than selecting or repricing atomically. The default term from Create would already satisfy this invariant, so an extra Update is needed only when the buyer changes it, and any changing selected term will only be done via Update.