Skip to content

docs: clarify participant identifier in payment handler examples - #791

Open
prasad-stripe wants to merge 2 commits into
mainfrom
prasad-stripe/docs-participant-identity
Open

docs: clarify participant identifier in payment handler examples#791
prasad-stripe wants to merge 2 commits into
mainfrom
prasad-stripe/docs-participant-identity

Conversation

@prasad-stripe

Copy link
Copy Markdown
Contributor

Description

The three payment handler examples describe the same participant identifier in three different ways, and one of them teaches the wrong threat model. This aligns all three with tokenization.md.

Since #746 moved identity out of binding, identity.access_token is a participant identifier, and tokenization.md Binding rule 4 states that a Tokenizer MUST NOT accept it as authentication. The examples had not caught up.

Four fixes:

  1. processor-tokenizer: "Issue identity.access_token (Merchant Secure Identifier) to merchants" framed the identifier as a secret, which contradicts Binding rule 4. Replaced with participant identifier framing, and added a Security Considerations row stating the rule explicitly.
  2. processor-tokenizer: a MUST required the credential provider to send the handler configuration's identity object, but no config table or example declaration in that document defines an identity member. The config publishes business_id. Reworded against the field that exists, split by the document's own PSP Mode and Direct Mode framing.
  3. platform-tokenizer: the same value appeared as identity.access_token in Prerequisites Output and as business_id in the config table, with no stated mapping, while three normative statements referenced "the business's identity from the handler declaration". The mapping is now stated once where the config is defined, and the three statements reference config.business_id.
  4. encrypted-credential: Prerequisites Output listed identity.access_token and References pointed at payment_identity.json, but this handler implements neither /tokenize nor /detokenize, and its encrypted payload carries credential plus binding. Replaced with business_id, which the next paragraph already uses, and repointed the reference to binding.json.

No schema file is touched, and no new normative requirement is introduced. The added Security Considerations row restates Binding rule 4, and fix 2 repoints an existing MUST at the config member the examples actually publish.

config deliberately stays handler-defined. An identity member was not added to the config tables, because config inherits from ucp.json#/$defs/entity as additionalProperties: true with "Structure defined by each entity's schema". The examples state the mapping instead of reserving a UCP member name inside a handler-defined object.

Category (Required)

  • Documentation: Updates to README, or documentations regarding schema or capabilities. (Requires Maintainer approval)

Related Issues

Follow-up to #746, which separated participant scope from resource scope. Related to #394, which raises the naming of access_token; this PR does not change any field name.

Checklist

  • I have followed the Contributing Guide (including Conventional Commits title requirements and ! for breaking changes).
  • I have updated the documentation (if applicable).
  • My changes pass all local linting and formatting checks.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • (For Core/Capability) I have included/updated the relevant JSON schemas.
  • I have regenerated Python Pydantic models by running generate_models.sh under python_sdk.

Screenshots / Logs (if applicable)

Prose and table edits only, no rendering change. Verified locally with markdownlint (repo config .github/linters/.markdownlint.json), cspell, and git diff --check. Diff is 35 insertions and 26 deletions across three files.

The three payment handler examples describe the participant identifier three different ways, and one of them teaches the wrong threat model. This aligns the examples with tokenization.md.

1. processor-tokenizer: "Merchant Secure Identifier" framed identity.access_token as a secret, contradicting tokenization.md Binding rule 4, which states that identity is a participant identifier, not a credential, and that a Tokenizer MUST NOT accept it as authentication. Replaced with participant identifier framing, plus a Security Considerations row stating the rule explicitly.

2. processor-tokenizer: a MUST required the credential provider to send the handler configuration's identity object, but no config table or example declaration in that document defines an identity member; the config publishes business_id. Reworded against the config field that exists, using the document's own PSP Mode and Direct Mode framing.

3. platform-tokenizer: the same value appeared as identity.access_token in Prerequisites and as business_id in the config table, with no stated mapping, while three normative statements referenced "the business's identity from the handler declaration". The mapping from config.business_id to identity.access_token is now stated once where the config is defined, and the three statements reference it. config remains handler-defined, per ucp.json#/$defs/entity.

4. encrypted-credential: Prerequisites listed identity.access_token and References pointed at payment_identity.json, but this handler implements neither /tokenize nor /detokenize, and its encrypted payload carries only credential and binding. Replaced with business_id, which the document's own next paragraph already uses, and with binding.json.

No schema file is touched. The added Security Considerations row restates tokenization.md Binding rule 4, and item 2 repoints an existing MUST at the config member the examples actually publish.
@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Sep 1, 2026
@carolinerg1 carolinerg1 added status:under-review and removed status:needs-triage Signal that the PR is ready for human triage labels Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants