{"version":3,"sources":["../../src/payment-id/types.ts","../../src/payment-id/server.ts","../../src/payment-id/client.ts"],"sourcesContent":["/**\n * Payment ID Extension Type Definitions\n *\n * Allows servers to attach unique identifiers to payments for\n * correlation, idempotency, and audit trails.\n */\n\n/**\n * Extension key for payment ID in requirements/payload extensions.\n */\nexport const PAYMENT_ID_EXTENSION_KEY = \"paymentId\";\n\n/**\n * Information provided by server about the payment identifier.\n */\nexport interface PaymentIdExtensionInfo {\n  /** Unique payment identifier (UUID v4) */\n  id: string;\n\n  /** Optional idempotency key for replay protection */\n  idempotencyKey?: string;\n\n  /** Optional payment group for batching */\n  groupId?: string;\n\n  /** Optional metadata */\n  metadata?: Record<string, string>;\n}\n\n/**\n * Payment ID extension declaration for server responses.\n */\nexport interface PaymentIdExtension {\n  /** Extension information */\n  info: PaymentIdExtensionInfo;\n\n  /** JSON Schema for validation */\n  schema: object;\n}\n\n/**\n * Payment ID payload echoed back by the client.\n */\nexport interface PaymentIdPayload {\n  /** Payment ID echoed back from requirements */\n  id: string;\n\n  /** Optional client-generated correlation ID */\n  clientId?: string;\n}\n\n/**\n * Options for declaring a payment ID extension.\n */\nexport interface DeclarePaymentIdOptions {\n  /** Custom payment ID (defaults to crypto.randomUUID()) */\n  id?: string;\n\n  /** Optional idempotency key for replay protection */\n  idempotencyKey?: string;\n\n  /** Optional payment group for batching */\n  groupId?: string;\n\n  /** Optional metadata */\n  metadata?: Record<string, string>;\n}\n","/**\n * Payment ID Extension Server-Side Implementation\n *\n * Provides functions for servers to declare payment ID requirements,\n * parse client payloads, and validate payment IDs.\n */\n\nimport { randomUUID } from \"crypto\";\nimport {\n  PaymentIdExtension,\n  PaymentIdExtensionInfo,\n  PaymentIdPayload,\n  DeclarePaymentIdOptions,\n  PAYMENT_ID_EXTENSION_KEY,\n} from \"./types.js\";\n\n/**\n * JSON Schema for payment ID payload validation.\n */\nconst PAYMENT_ID_SCHEMA = {\n  type: \"object\",\n  required: [\"id\"],\n  properties: {\n    id: { type: \"string\", format: \"uuid\" },\n    clientId: { type: \"string\" },\n  },\n};\n\n/**\n * Declares a payment ID extension for server responses.\n *\n * @param options - Optional configuration for the payment ID\n * @returns Payment ID extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declarePaymentIdExtension();\n * // Include in PaymentRequired response extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: extension }\n * ```\n */\nexport function declarePaymentIdExtension(\n  options: DeclarePaymentIdOptions = {},\n): PaymentIdExtension {\n  const info: PaymentIdExtensionInfo = {\n    id: options.id || randomUUID(),\n    idempotencyKey: options.idempotencyKey,\n    groupId: options.groupId,\n    metadata: options.metadata,\n  };\n\n  return {\n    info,\n    schema: PAYMENT_ID_SCHEMA,\n  };\n}\n\n/**\n * Parses a payment ID payload from client request extensions.\n *\n * @param extensions - Extensions object from the payment payload\n * @returns Parsed payment ID payload, or null if not present\n * @throws Error if payload is present but invalid\n *\n * @example\n * ```typescript\n * const payload = parsePaymentIdPayload(paymentPayload.extensions);\n * if (payload) {\n *   console.log(\"Payment ID:\", payload.id);\n * }\n * ```\n */\nexport function parsePaymentIdPayload(\n  extensions?: Record<string, unknown>,\n): PaymentIdPayload | null {\n  if (!extensions || !(PAYMENT_ID_EXTENSION_KEY in extensions)) {\n    return null;\n  }\n\n  const raw = extensions[PAYMENT_ID_EXTENSION_KEY];\n  if (typeof raw !== \"object\" || raw === null) {\n    throw new Error(\"Invalid paymentId extension: expected object\");\n  }\n\n  const obj = raw as Record<string, unknown>;\n\n  if (typeof obj.id !== \"string\" || obj.id.length === 0) {\n    throw new Error(\"Invalid paymentId extension: missing or empty id\");\n  }\n\n  return {\n    id: obj.id,\n    clientId: typeof obj.clientId === \"string\" ? obj.clientId : undefined,\n  };\n}\n\n/**\n * Validates that a client's payment ID payload matches the expected extension.\n *\n * @param payload - The client's payment ID payload\n * @param expected - The expected payment ID from the server extension\n * @returns True if the payment ID matches\n *\n * @example\n * ```typescript\n * const isValid = validatePaymentId(clientPayload, serverExtension.info);\n * if (!isValid) {\n *   throw new Error(\"Payment ID mismatch\");\n * }\n * ```\n */\nexport function validatePaymentId(\n  payload: PaymentIdPayload,\n  expected: PaymentIdExtensionInfo,\n): boolean {\n  return payload.id === expected.id;\n}\n","/**\n * Payment ID Extension Client-Side Implementation\n *\n * Provides functions for clients to echo payment IDs back to servers.\n */\n\nimport { PaymentIdExtension, PaymentIdPayload } from \"./types.js\";\n\n/**\n * Creates a payment ID payload from a server extension.\n *\n * Reads the payment ID from requirements and echoes it back.\n *\n * @param extension - Payment ID extension from server's 402 response\n * @param clientId - Optional client-generated correlation ID\n * @returns Payment ID payload for inclusion in payment extensions\n *\n * @example\n * ```typescript\n * const extension = paymentRequirements.extensions?.paymentId;\n * const payload = createPaymentIdPayload(extension, \"my-correlation-id\");\n * // Include in payment payload extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: payload }\n * ```\n */\nexport function createPaymentIdPayload(\n  extension: PaymentIdExtension,\n  clientId?: string,\n): PaymentIdPayload {\n  return {\n    id: extension.info.id,\n    clientId,\n  };\n}\n\n/**\n * Encodes a payment ID payload for header-based transport.\n *\n * @param payload - The payment ID payload to encode\n * @returns Base64-encoded JSON string\n */\nexport function encodePaymentIdHeader(payload: PaymentIdPayload): string {\n  const json = JSON.stringify(payload);\n  if (typeof Buffer !== \"undefined\") {\n    return Buffer.from(json, \"utf-8\").toString(\"base64\");\n  }\n  return btoa(json);\n}\n"],"mappings":";AAUO,IAAM,2BAA2B;;;ACHxC,SAAS,kBAAkB;AAY3B,IAAM,oBAAoB;AAAA,EACxB,MAAM;AAAA,EACN,UAAU,CAAC,IAAI;AAAA,EACf,YAAY;AAAA,IACV,IAAI,EAAE,MAAM,UAAU,QAAQ,OAAO;AAAA,IACrC,UAAU,EAAE,MAAM,SAAS;AAAA,EAC7B;AACF;AAeO,SAAS,0BACd,UAAmC,CAAC,GAChB;AACpB,QAAM,OAA+B;AAAA,IACnC,IAAI,QAAQ,MAAM,WAAW;AAAA,IAC7B,gBAAgB,QAAQ;AAAA,IACxB,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,EACV;AACF;AAiBO,SAAS,sBACd,YACyB;AACzB,MAAI,CAAC,cAAc,EAAE,4BAA4B,aAAa;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,WAAW,wBAAwB;AAC/C,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAEA,QAAM,MAAM;AAEZ,MAAI,OAAO,IAAI,OAAO,YAAY,IAAI,GAAG,WAAW,GAAG;AACrD,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,UAAU,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AAAA,EAC9D;AACF;AAiBO,SAAS,kBACd,SACA,UACS;AACT,SAAO,QAAQ,OAAO,SAAS;AACjC;;;AC3FO,SAAS,uBACd,WACA,UACkB;AAClB,SAAO;AAAA,IACL,IAAI,UAAU,KAAK;AAAA,IACnB;AAAA,EACF;AACF;AAQO,SAAS,sBAAsB,SAAmC;AACvE,QAAM,OAAO,KAAK,UAAU,OAAO;AACnC,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,OAAO,KAAK,MAAM,OAAO,EAAE,SAAS,QAAQ;AAAA,EACrD;AACA,SAAO,KAAK,IAAI;AAClB;","names":[]}