-
Notifications
You must be signed in to change notification settings - Fork 412
fix: add user_authorization to IntentMandate and intent binding to PaymentMandate #189
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: main
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,25 @@ class IntentMandate(BaseModel): | |
| ..., | ||
| description="When the intent mandate expires, in ISO 8601 format.", | ||
| ) | ||
| user_authorization: Optional[str] = Field( | ||
| None, | ||
| description=( | ||
| """ | ||
| A base64url-encoded JSON Web Token (JWT) that digitally signs the | ||
| intent mandate contents by the user's private key. This provides | ||
| non-repudiable proof of the user's intent and prevents tampering | ||
| by the shopping agent. | ||
|
|
||
| If this field is present, user_cart_confirmation_required can be | ||
| set to false, allowing the agent to execute purchases in the | ||
| user's absence. | ||
|
|
||
| If this field is None, user_cart_confirmation_required must be true, | ||
| requiring the user to confirm each specific purchase. | ||
| """ | ||
| ), | ||
| example="eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6ZXhhbXBsZ...", | ||
| ) | ||
|
|
||
|
|
||
| class CartContents(BaseModel): | ||
|
|
@@ -154,6 +173,24 @@ class PaymentMandateContents(BaseModel): | |
| ), | ||
| ) | ||
| merchant_agent: str = Field(..., description="Identifier for the merchant.") | ||
| intent_mandate_id: Optional[str] = Field( | ||
| None, | ||
| description=( | ||
| "Reference to the user-signed Intent Mandate that authorizes " | ||
| "this transaction in Human Not Present scenarios. This allows " | ||
| "the payment network to verify that the 'human not present' " | ||
| "transaction has pre-authorization support from a 'human present' " | ||
| "intent mandate. Required for HNP transactions." | ||
| ), | ||
| ) | ||
|
Comment on lines
+176
to
+185
Contributor
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. The description for Here's how you could implement this check: from pydantic import model_validator
class PaymentMandateContents(BaseModel):
# ... existing fields ...
@model_validator(mode='after')
def check_hnp_requirements(self) -> 'PaymentMandateContents':
if self.transaction_modality == 'human_not_present' and self.intent_mandate_id is None:
raise ValueError('intent_mandate_id is required for human_not_present transactions')
return self(Note: This example assumes |
||
| transaction_modality: Optional[str] = Field( | ||
| None, | ||
| description=( | ||
| "Transaction modality: 'human_present' or 'human_not_present'. " | ||
| "This signals to the payment network whether the user was present " | ||
| "at the time of payment authorization." | ||
| ), | ||
| ) | ||
|
Comment on lines
+186
to
+193
Contributor
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. The You could define an from enum import Enum
class TransactionModality(str, Enum):
HUMAN_PRESENT = "human_present"
HUMAN_NOT_PRESENT = "human_not_present"
class PaymentMandateContents(BaseModel):
# ...
transaction_modality: Optional[TransactionModality] = Field(
None,
description=(
"Transaction modality. This signals to the payment network whether "
"the user was present at the time of payment authorization."
),
)
# ... |
||
| timestamp: str = Field( | ||
| description=( | ||
| "The date and time the mandate was created, in ISO 8601 format." | ||
|
|
||
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.
The description for
user_authorizationstates an important business rule: "If this field is None, user_cart_confirmation_required must be true". To ensure data integrity and prevent invalid model states, this rule should be enforced with a Pydantic validator.Here is an example of how you could implement this with a
model_validator:This will make your model more robust.