{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://odexa.io/schemas/1.2.0-draft.3/payment.schema.json",
  "title": "Odexa draft3 fixed quote payment contracts (structural superset)",
  "$defs": {
    "quote": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "protocol_version",
        "profile",
        "record_type",
        "quote_id",
        "origin",
        "service_id",
        "verification_service_id",
        "provider_id",
        "verification_endpoint",
        "payer_id",
        "offer_id",
        "currency",
        "minor_unit_scale",
        "items",
        "total_minor",
        "issued_at",
        "expires_at"
      ],
      "properties": {
        "protocol_version": {
          "const": "1.2.0-draft.3"
        },
        "profile": {
          "const": "fixed-quote-v1"
        },
        "record_type": {
          "const": "payment.quote"
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "origin": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "verification_service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "provider_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "verification_endpoint": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "payer_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "offer_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Z]{3}$"
        },
        "minor_unit_scale": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9
        },
        "items": {
          "type": "array",
          "minItems": 1,
          "maxItems": 64,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "item_id",
              "kind",
              "payee_id",
              "amount_minor",
              "description"
            ],
            "properties": {
              "item_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$"
              },
              "kind": {
                "enum": [
                  "resource_license",
                  "provider_service"
                ]
              },
              "payee_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 4096,
                "pattern": "^https://[^?#]+$"
              },
              "amount_minor": {
                "type": "string",
                "pattern": "^(0|[1-9][0-9]{0,17})$"
              },
              "description": {
                "type": "string",
                "minLength": 1,
                "maxLength": 256,
                "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
              }
            }
          },
          "contains": {
            "type": "object",
            "properties": {
              "kind": {
                "const": "resource_license"
              }
            },
            "required": [
              "kind"
            ]
          },
          "minContains": 1
        },
        "total_minor": {
          "type": "string",
          "pattern": "^[1-9][0-9]{0,17}$"
        },
        "issued_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "expires_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        }
      }
    },
    "accepted_binding": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "protocol_version",
        "profile",
        "record_type",
        "agreement_id",
        "origin",
        "service_id",
        "principal_id",
        "offer_id",
        "quote_digest",
        "accepted_at",
        "access_expires_at",
        "use_expires_at",
        "offer_digest",
        "request"
      ],
      "properties": {
        "protocol_version": {
          "const": "1.2.0-draft.3"
        },
        "profile": {
          "const": "fixed-quote-v1"
        },
        "record_type": {
          "const": "payment.accepted_binding"
        },
        "agreement_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "origin": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "principal_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "offer_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "accepted_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "access_expires_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "use_expires_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "offer_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "request": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "url",
            "actions",
            "purposes",
            "supported_obligations"
          ],
          "properties": {
            "url": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4096,
              "pattern": "^https://[^#]+$"
            },
            "actions": {
              "type": "array",
              "minItems": 1,
              "maxItems": 4,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "redistribute",
                  "retrieve",
                  "store",
                  "transform"
                ]
              }
            },
            "purposes": {
              "type": "array",
              "minItems": 1,
              "maxItems": 6,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "internal_knowledge",
                  "model_fine_tuning",
                  "model_training",
                  "public_retrieval",
                  "redistribution",
                  "search_indexing"
                ]
              }
            },
            "supported_obligations": {
              "type": "array",
              "minItems": 0,
              "maxItems": 3,
              "uniqueItems": true,
              "items": {
                "enum": [
                  "attribution",
                  "report_usage",
                  "retention"
                ]
              }
            }
          }
        }
      }
    },
    "mandate": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "protocol_version",
        "profile",
        "record_type",
        "mandate_id",
        "agreement_id",
        "origin",
        "service_id",
        "quote_id",
        "quote_digest",
        "provider_id",
        "payer_id",
        "currency",
        "minor_unit_scale",
        "total_minor",
        "authorization",
        "issued_at",
        "expires_at"
      ],
      "properties": {
        "protocol_version": {
          "const": "1.2.0-draft.3"
        },
        "profile": {
          "const": "fixed-quote-v1"
        },
        "record_type": {
          "const": "payment.mandate"
        },
        "mandate_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "agreement_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "origin": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "provider_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "payer_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Z]{3}$"
        },
        "minor_unit_scale": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9
        },
        "total_minor": {
          "type": "string",
          "pattern": "^[1-9][0-9]{0,17}$"
        },
        "authorization": {
          "const": "pay_exact_quote_once"
        },
        "issued_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "expires_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        }
      }
    },
    "check": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "protocol_version",
        "profile",
        "record_type",
        "check_id",
        "quote_id",
        "quote_digest",
        "agreement_id",
        "mandate_id",
        "origin",
        "verification_service_id",
        "provider_id",
        "payer_id",
        "currency",
        "minor_unit_scale",
        "total_minor",
        "offer_digest",
        "request_digest"
      ],
      "properties": {
        "protocol_version": {
          "const": "1.2.0-draft.3"
        },
        "profile": {
          "const": "fixed-quote-v1"
        },
        "record_type": {
          "const": "payment.check"
        },
        "check_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "agreement_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "mandate_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "origin": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "verification_service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "provider_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "payer_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Z]{3}$"
        },
        "minor_unit_scale": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9
        },
        "total_minor": {
          "type": "string",
          "pattern": "^[1-9][0-9]{0,17}$"
        },
        "offer_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "request_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        }
      }
    },
    "verification": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "protocol_version",
        "profile",
        "record_type",
        "check_id",
        "quote_id",
        "quote_digest",
        "agreement_id",
        "mandate_id",
        "origin",
        "verification_service_id",
        "provider_id",
        "payer_id",
        "currency",
        "minor_unit_scale",
        "total_minor",
        "sequence",
        "state",
        "provider_reference",
        "effective_at",
        "checked_at",
        "offer_digest",
        "request_digest"
      ],
      "properties": {
        "protocol_version": {
          "const": "1.2.0-draft.3"
        },
        "profile": {
          "const": "fixed-quote-v1"
        },
        "record_type": {
          "const": "payment.verification"
        },
        "check_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "quote_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "agreement_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "mandate_id": {
          "type": "string",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "origin": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "verification_service_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "provider_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "payer_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^https://[^?#]+$"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Z]{3}$"
        },
        "minor_unit_scale": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9
        },
        "total_minor": {
          "type": "string",
          "pattern": "^[1-9][0-9]{0,17}$"
        },
        "sequence": {
          "type": "integer",
          "minimum": 1,
          "maximum": 9007199254740991
        },
        "state": {
          "enum": [
            "pending",
            "confirmed",
            "failed",
            "reversed"
          ]
        },
        "provider_reference": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
            },
            {
              "type": "null"
            }
          ]
        },
        "effective_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "checked_at": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
        },
        "offer_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "request_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "state": {
                "enum": [
                  "confirmed",
                  "reversed"
                ]
              }
            },
            "required": [
              "state"
            ]
          },
          "then": {
            "properties": {
              "provider_reference": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
              }
            }
          }
        }
      ]
    },
    "free": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "required"
      ],
      "properties": {
        "required": {
          "const": false
        }
      }
    }
  },
  "oneOf": [
    {
      "$ref": "#/$defs/quote"
    },
    {
      "$ref": "#/$defs/accepted_binding"
    },
    {
      "$ref": "#/$defs/mandate"
    },
    {
      "$ref": "#/$defs/check"
    },
    {
      "$ref": "#/$defs/verification"
    },
    {
      "$ref": "#/$defs/free"
    }
  ]
}
