{"id":"2JDR82DMmm","url":"https://pastebin.ca/2JDR82DMmm","raw_url":"https://raw.anybin.ca/2JDR82DMmm","visibility":"public","access":"public","created_at":1785040779721,"expires_at":1785645579721,"fetch_limit":null,"fetches_used":0,"reads_remaining":null,"size_bytes":8880,"syntax_hint":null,"title":null,"filename":null,"change_note":null,"cipher":null,"cipher_meta":null,"parent_id":null,"root_id":"2JDR82DMmm","version":1,"owner_id":null,"recipient_id":null,"body":"[2026/7/26 12:19] Desolate Pro20x 1128 Plus 118: 使用以下油猴脚本\n打开claude网页版，支付资料选德国，支付方式选sepa，使用http://randomiban.com/ 随机生成德国卡号填入直接支付就行了，max20到手\n\n// ==UserScript==\n// @name         TestExample Cassia Response Mock\n// @namespace    local.testexample.checkout\n// @version      1.1.0\n// @description  将 checkout_capabilities 响应改写为 cassia\n// @match        *://claude.ai/*\n// @match        *://*.claude.ai/*\n// @run-at       document-start\n// @grant        none\n// @sandbox      raw\n// ==/UserScript==\n\n(function () {\n  \"use strict\";\n\n  const TARGET_HOST = \"claude.ai\";\n\n  const TARGET_PATH =\n    /^\\/api\\/organizations\\/[^/]+\\/subscription\\/checkout_capabilities\\/?$/;\n\n  const MOCK_DATA = {\n    checkout_flow: \"cassia\"\n  };\n\n  const MOCK_BODY = JSON.stringify(MOCK_DATA);\n  const MOCK_LENGTH =\n    new TextEncoder().encode(MOCK_BODY).byteLength;\n\n  function getTargetUrl(input, method = \"GET\") {\n    try {\n      let rawUrl;\n\n      if (typeof input === \"string\" || input instanceof URL) {\n        rawUrl = String(input);\n      } else if (input && typeof input.url === \"string\") {\n        rawUrl = input.url;\n      } else {\n        return null;\n      }\n\n      const url = new URL(rawUrl, location.href);\n\n      if (String(method).toUpperCase() !== \"GET\") {\n        return null;\n      }\n\n      // 允许主域名以及其子域名\n      const hostMatched =\n        url.hostname === TARGET_HOST ||\n        url.hostname.endsWith(\".\" + TARGET_HOST);\n\n      if (!hostMatched) {\n        return null;\n      }\n\n      if (!TARGET_PATH.test(url.pathname)) {\n        return null;\n      }\n\n      return url;\n    } catch (error) {\n      console.error(\"[Cassia Mock] URL 解析失败：\", error);\n      return null;\n    }\n  }\n\n  function createMockResponse(originalResponse) {\n    const headers = new Headers(originalResponse.headers);\n\n    headers.delete(\"content-length\");\n    headers.delete(\"content-encoding\");\n    headers.delete(\"etag\");\n    headers.delete(\"content-md5\");\n\n    headers.set(\n      \"content-type\",\n      \"application/json; charset=utf-8\"\n    );\n    headers.set(\"content-length\", String(MOCK_LENGTH));\n    headers.set(\"cache-control\", \"no-store\");\n\n    const response = new Response(MOCK_BODY, {\n      status: 200,\n      statusText: \"OK\",\n      headers\n    });\n\n    // 尽量保留原始响应信息\n    try {\n      Object.defineProperties(response, {\n        url: {\n          value: originalResponse.url,\n          configurable: true\n        },\n        redirected: {\n          value: originalResponse.redirected,\n          configurable: true\n        },\n        type: {\n          value: originalResponse.type,\n          configurable: true\n        }\n      });\n    } catch (_) {\n      // 不影响主体改写\n    }\n\n    return response;\n  }\n\n  /*\n   * 拦截 Fetch\n   */\n  const nativeFetch = window.fetch;\n\n  window.fetch = async function (input, init) {\n    const method =\n      init?.method ||\n      (input instanceof Request ? input.method : \"GET\");\n\n    const targetUrl = getTargetUrl(input, method);\n\n    const originalResponse =\n      await nativeFetch.apply(this, arguments);\n\n    if (!targetUrl) {\n      return originalResponse;\n    }\n\n    console.warn(\n      \"[Cassia Mock] Fetch 响应已改写：\",\n      targetUrl.href,\n      MOCK_DATA\n    );\n\n    return createMockResponse(originalResponse);\n  };\n\n  /*\n   * 拦截 XMLHttpRequest\n   */\n  const XhrPrototype = XMLHttpRequest.prototype;\n  const xhrInfo = new WeakMap();\n  const loggedXhrs = new WeakSet();\n\n  const nativeOpen = XhrPrototype.open;\n  const nativeSend = XhrPrototype.send;\n  const nativeGetResponseHeader =\n    XhrPrototype.getResponseHeader;\n  const nativeGetAllResponseHeaders =\n    XhrPrototype.getAllResponseHeaders;\n\n  XhrPrototype.open = function (method, url) {\n    let absoluteUrl;\n\n    try {\n      absoluteUrl = new URL(\n        String(url),\n        location.href\n      ).href;\n    } catch (_) {\n      absoluteUrl = String(url);\n    }\n\n    xhrInfo.set(this, {\n      method: String(method || \"GET\").toUpperCase(),\n      url: absoluteUrl\n    });\n\n    return nativeOpen.apply(this, arguments);\n  };\n\n  function getMatchedXhr(xhr) {\n    const info = xhrInfo.get(xhr);\n[2026/7/26 12:19] Desolate Pro20x 1128 Plus 118: if (\n      !info ||\n      xhr.readyState !== XMLHttpRequest.DONE\n    ) {\n      return null;\n    }\n\n    return getTargetUrl(info.url, info.method);\n  }\n\n  function replaceXhrGetter(propertyName, replacement) {\n    const descriptor =\n      Object.getOwnPropertyDescriptor(\n        XhrPrototype,\n        propertyName\n      );\n\n    if (\n      !descriptor ||\n      typeof descriptor.get !== \"function\" ||\n      descriptor.configurable === false\n    ) {\n      console.warn(\n        [Cassia Mock] 无法接管 XHR.${propertyName}\n      );\n      return;\n    }\n\n    const nativeGetter = descriptor.get;\n\n    Object.defineProperty(XhrPrototype, propertyName, {\n      ...descriptor,\n\n      get: function () {\n        if (!getMatchedXhr(this)) {\n          return nativeGetter.call(this);\n        }\n\n        return replacement.call(this, nativeGetter);\n      }\n    });\n  }\n\n  replaceXhrGetter(\n    \"responseText\",\n    function (nativeGetter) {\n      if (\n        this.responseType !== \"\" &&\n        this.responseType !== \"text\"\n      ) {\n        return nativeGetter.call(this);\n      }\n\n      return MOCK_BODY;\n    }\n  );\n\n  replaceXhrGetter(\n    \"response\",\n    function (nativeGetter) {\n      if (this.responseType === \"json\") {\n        return {\n          checkout_flow: \"cassia\"\n        };\n      }\n\n      if (\n        this.responseType === \"\" ||\n        this.responseType === \"text\"\n      ) {\n        return MOCK_BODY;\n      }\n\n      return nativeGetter.call(this);\n    }\n  );\n\n  replaceXhrGetter(\"status\", function () {\n    return 200;\n  });\n\n  replaceXhrGetter(\"statusText\", function () {\n    return \"OK\";\n  });\n\n  XhrPrototype.getResponseHeader = function (name) {\n    if (!getMatchedXhr(this)) {\n      return nativeGetResponseHeader.apply(\n        this,\n        arguments\n      );\n    }\n\n    switch (String(name).toLowerCase()) {\n      case \"content-type\":\n        return \"application/json; charset=utf-8\";\n\n      case \"content-length\":\n        return String(MOCK_LENGTH);\n\n      case \"cache-control\":\n        return \"no-store\";\n\n      case \"content-encoding\":\n      case \"etag\":\n      case \"content-md5\":\n        return null;\n\n      default:\n        return nativeGetResponseHeader.apply(\n          this,\n          arguments\n        );\n    }\n  };\n\n  XhrPrototype.getAllResponseHeaders = function () {\n    const originalHeaders =\n      nativeGetAllResponseHeaders.apply(this, arguments);\n\n    if (!getMatchedXhr(this)) {\n      return originalHeaders;\n    }\n\n    const headers = String(originalHeaders || \"\")\n      .split(/\\r?\\n/)\n      .filter(Boolean)\n      .filter(function (line) {\n        const name = line\n          .split(\":\", 1)[0]\n          .trim()\n          .toLowerCase();\n\n        return ![\n          \"content-type\",\n          \"content-length\",\n          \"content-encoding\",\n          \"cache-control\",\n          \"etag\",\n          \"content-md5\"\n        ].includes(name);\n      });\n\n    headers.push(\n      \"content-type: application/json; charset=utf-8\",\n      content-length: ${MOCK_LENGTH},\n      \"cache-control: no-store\"\n    );\n\n    return headers.join(\"\\r\\n\") + \"\\r\\n\";\n  };\n\n  XhrPrototype.send = function () {\n    this.addEventListener(\n      \"readystatechange\",\n      function () {\n        const targetUrl = getMatchedXhr(this);\n\n        if (targetUrl && !loggedXhrs.has(this)) {\n          loggedXhrs.add(this);\n\n          console.warn(\n            \"[Cassia Mock] XHR 响应已改写：\",\n            targetUrl.href,\n            MOCK_DATA\n          );\n        }\n      }\n    );\n\n    return nativeSend.apply(this, arguments);\n  };\n\n  /*\n   * 显示运行标记\n   */\n  function showStatusBadge() {\n    if (!document.documentElement) {\n      document.addEventListener(\n        \"DOMContentLoaded\",\n        showStatusBadge,\n        { once: true }\n      );\n      return;\n    }\n\n    if (document.getElementById(\"cassia-mock-badge\")) {\n      return;\n    }\n\n    const badge = document.createElement(\"div\");\n    badge.id = \"cassia-mock-badge\";\n    badge.textContent = \"Cassia Mock ON\";\n[2026/7/26 12:19] Desolate Pro20x 1128 Plus 118: Object.assign(badge.style, {\n      position: \"fixed\",\n      right: \"12px\",\n      bottom: \"12px\",\n      zIndex: \"2147483647\",\n      padding: \"7px 11px\",\n      color: \"#ffffff\",\n      background: \"#167c3a\",\n      borderRadius: \"6px\",\n      fontSize: \"12px\",\n      fontFamily: \"sans-serif\",\n      boxShadow: \"0 2px 8px rgba(0,0,0,.3)\"\n    });\n\n    document.documentElement.appendChild(badge);\n  }\n\n  window.__cassiaMockInstalled = true;\n\n  console.info(\n    \"[Cassia Mock] 脚本已加载：\",\n    location.href\n  );\n\n  showStatusBadge();\n})();"}