{"_id":"@autopayprotocol/sdk","_rev":"6-f3d1837f71c08543b467e627402d960b","name":"@autopayprotocol/sdk","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@autopayprotocol/sdk","version":"0.1.0","license":"MIT","_id":"@autopayprotocol/sdk@0.1.0","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"dist":{"shasum":"b178e97877e62dd2ed2d220f18069c31bb00a1ee","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.0.tgz","fileCount":8,"integrity":"sha512-e/vjiY7fPAohUx9/xYKPIxZMzvZ7bsrBDuhL//6uEL/p71BY7A2WKaL18l2HQ1wdY9fxmw0aDxliQgiDPcnAig==","signatures":[{"sig":"MEUCIQCmXPMJYnbpQCr8WcfEPcDOIjGZ8hZSPNp641fUiiXemQIgYXIAr/GY8/CUuQWODRMkJ9NX4boViQch902OKtDtB4I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":103725},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"90c92ee96cad58a9683fe485197ef3999c6cd64c","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"_npmVersion":"11.4.2","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1770440940158_0.8214856388078224","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@autopayprotocol/sdk","version":"0.1.1","license":"MIT","_id":"@autopayprotocol/sdk@0.1.1","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"dist":{"shasum":"10e6268d5c8b6257d2a3ecdb95f21fa811ce786f","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.1.tgz","fileCount":8,"integrity":"sha512-s3ohAci7x1BKab7hXDdWx1QtgE/kLIkSfUuYNQN8H0mJI/GH5UDDyRpgqVd/PnvqQx87kVBR1cAuF58Mm4cotg==","signatures":[{"sig":"MEQCIDQggxjgvCB4UDqAf+uK0OYcspNu2TZVrTc+10mJHS0/AiB0SZCuLCQvDYvK1xSxb2qQQfa9ii/vSkP6G3ODtPMv1g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104031},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"90c92ee96cad58a9683fe485197ef3999c6cd64c","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"repository":{"url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.4.2","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.1_1770441547587_0.15414940893596984","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@autopayprotocol/sdk","version":"0.1.2","license":"Apache-2.0","_id":"@autopayprotocol/sdk@0.1.2","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"dist":{"shasum":"5621f8a4eccbca0f00d3eecb2762058a283afaaa","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.2.tgz","fileCount":8,"integrity":"sha512-ZWf/PQb0Rim8x1zQYQSw3QoCVqZtiHj39fzOZJn2J7Ye5jas4dPejissOibI9Grs6OqlSDfXTjnT3zlO+dU67A==","signatures":[{"sig":"MEYCIQC2T68q58gdpKWgtO0u/XZE7YJie6qsdynjmtEajYBYHgIhAMJRPEG/t4hyY0xfB2r+P1rKs+Vp5ymWSmJAF8644fW7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104038},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"02035d5d43d02078f9861be99075e3e20bc24525","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"repository":{"url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.4.2","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.2_1770499902823_0.5739687867520238","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@autopayprotocol/sdk","version":"0.1.3","license":"Apache-2.0","_id":"@autopayprotocol/sdk@0.1.3","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"dist":{"shasum":"f5a5243a62ab370ce1a1ad4aff1824a9f999f935","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.3.tgz","fileCount":8,"integrity":"sha512-6lKMy+UBmCD6mVpAQZ+lSjILqd1HZ6gO1cbqJXwCweK/LYQOqpj4mdGvFRpwyI2DUayCGjEsGUmziuSuGhQiIA==","signatures":[{"sig":"MEUCIBye6xFMHAmBwdEGlznc+1ulIGp8tXuzzRv3JDyJpAViAiEA3nojPnYEavtR98rNfo93LDOX+jdVw5Uw1JAZJnKDvMg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105089},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"13d3b343a2f43ad17d06626a4877fc94c50ff19f","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"repository":{"url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.4.2","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.3_1770503930685_0.8025318028601383","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@autopayprotocol/sdk","version":"0.1.4","license":"Apache-2.0","_id":"@autopayprotocol/sdk@0.1.4","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"dist":{"shasum":"82d0cba05d628be010aba19152317b254c074f40","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.4.tgz","fileCount":8,"integrity":"sha512-wddYS5c8/EkNxzekTVc3dDbDZIDTE51tKaCpMJzCd9KHO60oNdXdgUMS5jGZO7/B10VKGEhgorpN2rbBKoPlRQ==","signatures":[{"sig":"MEUCIHI81E+jLqQ3czMQU37dIN9io8wjMPeUezskXa3xJf2LAiEAj7Thh78dadrsCL7Xrx2keMcAXZB0l9q2QSOPld0pnkA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158119},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"d0958e2b6de6809a6aa73272169721c5a31f2f12","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"repository":{"url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.4.2","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","vitest":"^1.2.0","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.4_1772150059771_0.7673458585002575","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@autopayprotocol/sdk","version":"0.1.5","description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","directory":"packages/sdk"},"homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"engines":{"node":">=20"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"devDependencies":{"@types/node":"^20.11.0","tsup":"^8.0.1","typescript":"^5.3.3","vitest":"^1.2.0"},"_id":"@autopayprotocol/sdk@0.1.5","gitHead":"5847bc9327cb16fd00b71f28d3cb8ff5e26b4d70","_nodeVersion":"24.3.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-VZ9YujagE0eNiTdoUH6jID29m0a2zl1rKqkmdXONnHRe5pEmc+ZXxbuzCkM+VE70Mo/dWFuk4yRfwedkNsULlA==","shasum":"7495ba2dfba7a21e9f65b1fd243dce044bcb9223","tarball":"https://registry.npmjs.org/@autopayprotocol/sdk/-/sdk-0.1.5.tgz","fileCount":8,"unpackedSize":158229,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC+O+acwycp+G4z5rbqArpjw/eCCIURvYaqBcpMraJzOAIgFpWAvwSPascIGX2UvUo7AJQwsvhiBqIYgtzPvREDLdw="}]},"_npmUser":{"name":"apeoverflow","email":"kieranmarcus@gmail.com"},"directories":{},"maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.5_1772905224069_0.7470305864654907"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-07T05:09:00.053Z","modified":"2026-03-07T17:40:24.318Z","0.1.0":"2026-02-07T05:09:00.316Z","0.1.1":"2026-02-07T05:19:07.806Z","0.1.2":"2026-02-07T21:31:42.977Z","0.1.3":"2026-02-07T22:38:50.836Z","0.1.4":"2026-02-26T23:54:19.946Z","0.1.5":"2026-03-07T17:40:24.204Z"},"bugs":{"url":"https://github.com/apeoverflow/Auto-Pay-Protocol/issues"},"license":"Apache-2.0","homepage":"https://github.com/apeoverflow/Auto-Pay-Protocol/tree/main/packages/sdk#readme","repository":{"type":"git","url":"git+https://github.com/apeoverflow/Auto-Pay-Protocol.git","directory":"packages/sdk"},"description":"Merchant SDK for AutoPay Protocol — checkout URLs, webhook verification, USDC helpers","maintainers":[{"name":"apeoverflow","email":"kieranmarcus@gmail.com"}],"readme":"# @autopayprotocol/sdk\n\nServer-side helpers for merchants integrating with [AutoPay Protocol](https://autopayprotocol.com) — crypto subscriptions that are 50% cheaper than Stripe, fully non-custodial, and multi-chain.\n\nThis SDK handles what merchants need on their backend: building checkout URLs, verifying webhook signatures, and working with USDC amounts. It has **zero runtime dependencies** and works with any Node.js framework.\n\n## Install\n\n```bash\nnpm install @autopayprotocol/sdk\n```\n\nRequires Node.js 20+.\n\n## Checkout URLs\n\nThe checkout URL is how you send users to subscribe. There are two ways to build one:\n\n### From a relayer-hosted plan\n\nIf you manage plans through the [merchant dashboard](https://autopayprotocol.com), the SDK fetches billing params and metadata automatically:\n\n```ts\nimport { createCheckoutUrlFromPlan } from '@autopayprotocol/sdk'\n\nconst url = await createCheckoutUrlFromPlan({\n  relayerUrl: 'https://relayer.autopayprotocol.com',\n  merchant: '0x2B8b9182c1c3A9bEf4a60951D9B7F49420D12B9B',\n  planId: 'pro-plan',\n  successUrl: 'https://mysite.com/success',\n  cancelUrl: 'https://mysite.com/cancel',\n})\n// Redirect the user to `url`\n```\n\n### Directly with billing params\n\nIf you host your own plan metadata JSON:\n\n```ts\nimport { createCheckoutUrl } from '@autopayprotocol/sdk'\n\nconst url = createCheckoutUrl({\n  merchant: '0x2B8b9182c1c3A9bEf4a60951D9B7F49420D12B9B',\n  amount: 9.99,\n  interval: 'monthly',\n  metadataUrl: 'https://mysite.com/plans/pro.json',\n  successUrl: 'https://mysite.com/success',\n  cancelUrl: 'https://mysite.com/cancel',\n  spendingCap: 119.88, // optional, 12 months worth\n})\n```\n\n### Targeting a chain\n\nAutoPay runs on multiple chains. Use the `chain` option to target a specific one:\n\n```ts\nimport { createCheckoutUrl } from '@autopayprotocol/sdk'\n\n// Base (default) — autopayprotocol.com\nconst baseUrl = createCheckoutUrl({ ... })\n\n// Flow EVM — flow.autopayprotocol.com\nconst flowUrl = createCheckoutUrl({\n  ...options,\n  chain: 'flowEvm',\n})\n\n// Base Sepolia (testnet) — staging.autopayprotocol.com\nconst testUrl = createCheckoutUrl({\n  ...options,\n  chain: 'baseSepolia',\n})\n```\n\nAvailable chains:\n\n| Chain | ID | `chain` value | Checkout URL |\n|-------|-----|--------------|-------------|\n| Base | 8453 | `'base'` (default) | `https://autopayprotocol.com` |\n| Flow EVM | 747 | `'flowEvm'` | `https://flow.autopayprotocol.com` |\n| Base Sepolia | 84532 | `'baseSepolia'` | `https://staging.autopayprotocol.com` |\n\n### Intervals\n\nUse preset strings or build custom intervals:\n\n```ts\nimport { createCheckoutUrl, intervals } from '@autopayprotocol/sdk'\n\n// Preset strings: 'daily', 'weekly', 'biweekly', 'monthly', 'quarterly', 'yearly'\ncreateCheckoutUrl({ ..., interval: 'monthly' })\n\n// Custom: 14 days\ncreateCheckoutUrl({ ..., interval: intervals.custom(14, 'days') })\n\n// Raw seconds\ncreateCheckoutUrl({ ..., interval: 604800 })\n```\n\n### Success redirect\n\nAfter subscribing, users are redirected to your `successUrl` with query params:\n\n```ts\nimport { parseSuccessRedirect } from '@autopayprotocol/sdk'\n\n// On your success page:\nconst { policyId, txHash } = parseSuccessRedirect(window.location.search)\n```\n\n## Webhooks\n\nThe relayer sends webhook events to your server when subscriptions change. Each request includes an `x-autopay-signature` header (HMAC-SHA256).\n\n### Next.js (App Router)\n\n```ts\n// app/api/autopay/route.ts\nimport { verifyWebhook } from '@autopayprotocol/sdk'\n\nconst SECRET = process.env.AUTOPAY_WEBHOOK_SECRET!\n\nexport async function POST(request: Request) {\n  const rawBody = await request.text()\n  const signature = request.headers.get('x-autopay-signature') ?? undefined\n\n  try {\n    const event = verifyWebhook(rawBody, signature, SECRET)\n\n    if (event.type === 'charge.succeeded') {\n      // TypeScript knows event.data has amount, protocolFee, txHash\n      await recordPayment(event.data.payer, event.data.amount, event.data.txHash)\n    }\n\n    return Response.json({ received: true })\n  } catch {\n    return Response.json({ error: 'Invalid signature' }, { status: 401 })\n  }\n}\n```\n\n### Express\n\n```ts\nimport express from 'express'\nimport { verifyWebhook } from '@autopayprotocol/sdk'\n\nconst app = express()\nconst SECRET = process.env.AUTOPAY_WEBHOOK_SECRET!\n\n// Important: use express.text() so the raw body is available for signature verification\napp.post('/webhook/autopay', express.text({ type: '*/*' }), (req, res) => {\n  try {\n    const event = verifyWebhook(req.body, req.headers['x-autopay-signature'] as string, SECRET)\n\n    switch (event.type) {\n      case 'policy.created':    /* grant access */     break\n      case 'charge.succeeded':  /* record payment */   break\n      case 'charge.failed':     /* send reminder */    break\n      case 'policy.revoked':    /* revoke access */    break\n      case 'policy.cancelled_by_failure': /* revoke */ break\n    }\n\n    res.json({ received: true })\n  } catch {\n    res.status(401).json({ error: 'Invalid signature' })\n  }\n})\n```\n\n### Event types\n\nAll events include `policyId`, `chainId`, `payer`, and `merchant` in `event.data`.\n\n| Event | Extra fields | When |\n|-------|-------------|------|\n| `policy.created` | `chargeAmount`, `interval`, `spendingCap`, `metadataUrl` | User subscribes |\n| `charge.succeeded` | `amount`, `protocolFee`, `txHash` | Recurring payment collected |\n| `charge.failed` | `reason` | Payment failed (balance/allowance) |\n| `policy.revoked` | `endTime` | User cancelled |\n| `policy.cancelled_by_failure` | `consecutiveFailures`, `endTime` | Auto-cancelled after 3 failures |\n| `policy.completed` | `totalSpent`, `chargeCount` | Spending cap reached |\n\n### Testing webhooks locally\n\n```ts\nimport { signPayload } from '@autopayprotocol/sdk'\n\nconst body = JSON.stringify({ type: 'charge.succeeded', timestamp: new Date().toISOString(), data: { ... } })\nconst signature = signPayload(body, 'your-test-secret')\n\nawait fetch('http://localhost:3000/webhook/autopay', {\n  method: 'POST',\n  headers: { 'Content-Type': 'text/plain', 'x-autopay-signature': signature },\n  body,\n})\n```\n\n## USDC helpers\n\n```ts\nimport { parseUSDC, formatUSDC, calculateFeeBreakdown } from '@autopayprotocol/sdk'\n\n// Human-readable → raw amount (6 decimals)\nparseUSDC(9.99)  // \"9990000\"\n\n// Raw amount → human-readable\nformatUSDC('9990000')  // \"9.99\"\n\n// Fee breakdown (protocol fee is 2.5%)\nconst fees = calculateFeeBreakdown('9990000')\n// { total: \"9.99\", merchantReceives: \"9.74\", protocolFee: \"0.25\", feePercentage: \"2.5%\" }\n```\n\n## Plan metadata\n\nCreate and validate the JSON metadata that describes your plan on the checkout page:\n\n```ts\nimport { createMetadata, validateMetadata } from '@autopayprotocol/sdk'\n\nconst metadata = createMetadata({\n  planName: 'Pro',\n  planDescription: 'All premium features',\n  merchantName: 'Acme Corp',\n  amount: '9.99',\n  interval: 'monthly',\n  cap: '119.88',\n  features: ['Unlimited access', 'Priority support'],\n  website: 'https://acme.com',\n  color: '#6366F1',\n  badge: 'Most Popular',\n})\n\nconst { valid, errors } = validateMetadata(metadata)\n```\n\n## Constants\n\n```ts\nimport { intervals, chains, PROTOCOL_FEE_BPS, USDC_DECIMALS } from '@autopayprotocol/sdk'\n\nintervals.monthly    // 2592000 (seconds)\nintervals.weekly     // 604800\nintervals.custom(3, 'months') // 7776000\n\nchains.base.chainId              // 8453\nchains.base.checkoutBaseUrl      // \"https://autopayprotocol.com\"\nchains.flowEvm.chainId           // 747\nchains.flowEvm.checkoutBaseUrl   // \"https://flow.autopayprotocol.com\"\nchains.baseSepolia.chainId       // 84532\nchains.baseSepolia.checkoutBaseUrl // \"https://staging.autopayprotocol.com\"\n\nPROTOCOL_FEE_BPS   // 250 (2.5%)\nUSDC_DECIMALS      // 6\n```\n\n## Full API reference\n\n### Checkout\n\n| Function | Description |\n|----------|-------------|\n| `createCheckoutUrl(options)` | Build a checkout URL with validation |\n| `createCheckoutUrlFromPlan(options)` | Build from a relayer-hosted plan (fetches billing params, prefers IPFS metadata) |\n| `resolvePlan(options)` | Fetch a plan from the relayer and return structured billing data |\n| `parseSuccessRedirect(queryString)` | Parse `policyId` and `txHash` from the success redirect |\n| `resolveInterval(preset \\| seconds)` | Convert interval preset to seconds |\n\n### Webhooks\n\n| Function | Description |\n|----------|-------------|\n| `verifyWebhook(body, signature, secret)` | Verify + parse webhook into a typed event |\n| `verifySignature(payload, signature, secret)` | Verify HMAC-SHA256 signature only |\n| `signPayload(payload, secret)` | Sign a payload (for testing) |\n\n### Amounts\n\n| Function | Description |\n|----------|-------------|\n| `formatUSDC(rawAmount)` | `\"9990000\"` → `\"9.99\"` |\n| `parseUSDC(amount)` | `9.99` → `\"9990000\"` |\n| `calculateFeeBreakdown(rawAmount)` | Total, merchant receives, protocol fee |\n| `formatInterval(seconds)` | `2592000` → `\"monthly\"` |\n\n### Metadata\n\n| Function | Description |\n|----------|-------------|\n| `validateMetadata(data)` | Validate against the metadata schema |\n| `createMetadata(options)` | Build a valid metadata object |\n\n### Error classes\n\n| Class | Thrown when |\n|-------|-----------|\n| `AutoPayWebhookError` | Webhook signature verification fails |\n| `AutoPayCheckoutError` | Invalid checkout parameters |\n| `AutoPayMetadataError` | Invalid metadata structure |\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}