{"_id":"@bazileros/payfast","_rev":"5-61c600e60ad93b75115bbff8dfeb45a9","name":"@bazileros/payfast","dist-tags":{"latest":"0.2.5"},"versions":{"0.1.0":{"name":"@bazileros/payfast","version":"0.1.0","license":"Apache-2.0","_id":"@bazileros/payfast@0.1.0","maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"homepage":"https://github.com/bazileros/payfastt#readme","bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"dist":{"shasum":"2228c95cd768c13002ad2a0f751f36ac8eadc41e","tarball":"https://registry.npmjs.org/@bazileros/payfast/-/payfast-0.1.0.tgz","fileCount":59,"integrity":"sha512-Y3wTGqOkseL8wd0u4DtSnAlgNdF//74Ca5cHu/uJlev4oP7CcV6DCMakRcOWIjIF+yzUY9A05VeKg4fQJfEkZQ==","signatures":[{"sig":"MEUCIQCrFlZ6H61ZlSezIHb+Hjxr/W6dJl8yamsGDK4r4jAOHgIgB7HJQ1uAH1lANlc4rdr+uuwoXMI+9Vb17nMUwysmIGs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187165},"type":"module","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./http":{"types":"./dist/component/http.d.ts","default":"./dist/component/http.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"}},"gitHead":"209978651802aab2399f7cdd0dae823c71ffafea","scripts":{"dev":"bun run build:codegen","test":"vitest run","build":"tsc --project tsconfig.build.json","test:watch":"vitest","check-types":"tsc --noEmit","build:codegen":"convex codegen --component-dir ./src/component && bun run build"},"_npmUser":{"name":"bazileros","email":"zalisilesithule@gmail.com"},"repository":{"url":"git+https://github.com/bazileros/payfastt.git","type":"git","directory":"packages/payfast"},"_npmVersion":"11.13.0","description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","directories":{},"_nodeVersion":"24.16.0","dependencies":{"convex":"^1.36.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","convex":"^1.36.1","vitest":"^4.1.4","react-dom":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.9.3","convex-test":"^0.0.53","@types/react":"^19.2.15","@edge-runtime/vm":"^5.0.0","@payfastt/config":"workspace:*","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":"^18.3.1 || ^19.0.0","convex":"^1.36.1"},"_npmOperationalInternal":{"tmp":"tmp/payfast_0.1.0_1781819805175_0.7902666942383898","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bazileros/payfast","version":"0.2.0","license":"Apache-2.0","_id":"@bazileros/payfast@0.2.0","maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"homepage":"https://github.com/bazileros/payfastt#readme","bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"dist":{"shasum":"e83290e9d7f68366cf31f98995d8ed6c72cf1db3","tarball":"https://registry.npmjs.org/@bazileros/payfast/-/payfast-0.2.0.tgz","fileCount":72,"integrity":"sha512-BpxxqsICNDJvpruh1z+JXdehtebg3DYxizj/q2LKIgRbRq9CNuReJ79AquTWO0U37EXrbY4J2smEnOLovzY64A==","signatures":[{"sig":"MEUCIQCVQs+oACXyutWL5fNXpJhCC7hSSVEGSG3lQcU6J/XaoAIgFxxRxLJtMpj5k777bX5Yr/JiaGm9E3YBPa5dPNtY1Pk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bazileros%2fpayfast@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":256010},"type":"module","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./http":{"types":"./dist/component/http.d.ts","default":"./dist/component/http.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"}},"gitHead":"34ba12f0e0065fdd63a0aadb364a942ec1f232d8","private":false,"scripts":{"test":"vitest run","build":"tsc --project tsconfig.build.json","test:watch":"vitest","check-types":"tsc --noEmit","build:codegen":"convex codegen --component-dir ./src/component && bun run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2806bb51-5472-4929-b222-2eca6a77e0b9"}},"repository":{"url":"git+https://github.com/bazileros/payfastt.git","type":"git","directory":"packages/payfast"},"_npmVersion":"11.13.0","description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","directories":{},"_nodeVersion":"24.16.0","dependencies":{"convex":"^1.36.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","convex":"^1.36.1","vitest":"^4.1.4","react-dom":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.9.3","convex-test":"^0.0.53","@types/react":"^19.2.15","@edge-runtime/vm":"^5.0.0","@payfastt/config":"workspace:*","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":"^18.3.1 || ^19.0.0","convex":"^1.36.1"},"_npmOperationalInternal":{"tmp":"tmp/payfast_0.2.0_1782079041823_0.6901333248356705","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@bazileros/payfast","version":"0.2.3","license":"Apache-2.0","_id":"@bazileros/payfast@0.2.3","maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"homepage":"https://github.com/bazileros/payfastt#readme","bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"dist":{"shasum":"cdb9bf98d45aced52977c3a144a7f815e38997be","tarball":"https://registry.npmjs.org/@bazileros/payfast/-/payfast-0.2.3.tgz","fileCount":76,"integrity":"sha512-4/JbhpTmII7htsZxF5A2FJ6qN0EeGkaSi2fZe1kAwFlFUkdhSzkPWQ4I/Hva3Bjs1u4TQkA0VMUo1FEwg3jUjw==","signatures":[{"sig":"MEQCICC9/jJuEqYIIRZnOCl/NBsgW9qeouiCLswhgsGLofm9AiAIFPNoPQMpFn3HwpCUNIjjLWKyGNi7CDmVmRJn7b7TnQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bazileros%2fpayfast@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":249378},"type":"module","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./http":{"types":"./dist/component/http.d.ts","default":"./dist/component/http.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./component/types":{"types":"./dist/component/types.d.ts","default":"./dist/component/types.js"}},"gitHead":"b5ef81baea2b8ebdf2c44f29e93948f2051f3aad","private":false,"scripts":{"test":"vitest run","build":"tsc --project tsconfig.build.json","clean":"rm -rf dist tsconfig.build.tsbuildinfo tsconfig.tsbuildinfo","codegen":"convex codegen --component-dir ./src/component","prebuild":"bun run clean && if [ -n \"$CONVEX_DEPLOYMENT\" ]; then bun run codegen; else echo 'Skipping codegen (no CONVEX_DEPLOYMENT)'; fi","dev:watch":"tsc --build tsconfig.build.json -w","postbuild":"mkdir -p dist/component/functions && cp -r src/component/functions/_generated dist/component/functions/_generated","test:watch":"vitest","check-types":"tsc --noEmit"},"_npmUser":{"name":"bazileros","email":"zalisilesithule@gmail.com"},"repository":{"url":"git+https://github.com/bazileros/payfastt.git","type":"git","directory":"packages/payfast"},"_npmVersion":"11.13.0","description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","directories":{},"_nodeVersion":"24.16.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","convex":"^1.36.1","vitest":"^4.1.4","react-dom":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.9.3","convex-test":"^0.0.53","@types/react":"^19.2.15","@edge-runtime/vm":"^5.0.0","@payfastt/config":"workspace:*","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":"^18.3.1 || ^19.0.0","convex":"^1.36.1"},"_npmOperationalInternal":{"tmp":"tmp/payfast_0.2.3_1782216989869_0.4420723327684746","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@bazileros/payfast","version":"0.2.4","license":"Apache-2.0","_id":"@bazileros/payfast@0.2.4","maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"homepage":"https://github.com/bazileros/payfastt#readme","bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"dist":{"shasum":"8b832398f9b04898aa04fc2c35c2fe88fd938d5e","tarball":"https://registry.npmjs.org/@bazileros/payfast/-/payfast-0.2.4.tgz","fileCount":71,"integrity":"sha512-N2ThlgpRS1K2eWzL4nAszJ7EdKvrB4eUH9pjkLSg2+9zHj2dA2/nRXWjJkee3cvPah76fFvCpKR1ypZAz9A/Tg==","signatures":[{"sig":"MEYCIQDXm8oAzUxjCaanTjXQAC01l1O8IEOvgiOruHUz1lsD/wIhALm5zCPSehY494Hc0WRZli4hMN+zejgdKpNxmnfgDcZU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bazileros%2fpayfast@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":224997},"type":"module","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./http":{"types":"./dist/component/http.d.ts","default":"./dist/component/http.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./component/types":{"types":"./dist/component/types.d.ts","default":"./dist/component/types.js"},"./_generated/component":{"types":"./dist/component/_generated/component.d.ts","default":"./dist/component/_generated/component.js"}},"gitHead":"8a9c1e1b734db5aed29f605099e635d2a0fea1e0","private":false,"scripts":{"test":"vitest run","build":"tsc --project tsconfig.build.json","clean":"rm -rf dist tsconfig.build.tsbuildinfo tsconfig.tsbuildinfo","codegen":"convex codegen --component-dir ./src/component","prebuild":"bun run clean && if [ -n \"$CONVEX_DEPLOYMENT\" ]; then bun run codegen; else echo 'Skipping codegen (no CONVEX_DEPLOYMENT)'; fi","dev:watch":"tsc --build tsconfig.build.json -w","postbuild":"true","test:watch":"vitest","check-types":"tsc --noEmit"},"_npmUser":{"name":"bazileros","email":"zalisilesithule@gmail.com"},"repository":{"url":"git+https://github.com/bazileros/payfastt.git","type":"git","directory":"packages/payfast"},"_npmVersion":"11.16.0","description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","directories":{},"_nodeVersion":"24.18.0","dependencies":{"spark-md5":"^3.0.2","@types/spark-md5":"^3.0.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","convex":"^1.36.1","vitest":"^4.1.4","react-dom":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.9.3","convex-test":"^0.0.53","@types/react":"^19.2.15","@edge-runtime/vm":"^5.0.0","@payfastt/config":"workspace:*","@types/react-dom":"^19.2.3"},"peerDependencies":{"react":"^18.3.1 || ^19.0.0","convex":"^1.36.1"},"_npmOperationalInternal":{"tmp":"tmp/payfast_0.2.4_1783053500530_0.08021673017322994","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@bazileros/payfast","version":"0.2.5","private":false,"type":"module","description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/bazileros/payfastt.git","directory":"packages/payfast"},"scripts":{"clean":"rm -rf dist tsconfig.build.tsbuildinfo tsconfig.tsbuildinfo","codegen":"convex codegen --component-dir ./src/component","prebuild":"bun run clean && if [ -n \"$CONVEX_DEPLOYMENT\" ]; then bun run codegen; else echo 'Skipping codegen (no CONVEX_DEPLOYMENT)'; fi","build":"tsc --project tsconfig.build.json","postbuild":"true","dev:watch":"tsc --build tsconfig.build.json -w","check-types":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"exports":{"./package.json":"./package.json",".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./test":"./src/test.ts","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./http":{"types":"./dist/component/http.d.ts","default":"./dist/component/http.js"},"./component/types":{"types":"./dist/component/types.d.ts","default":"./dist/component/types.js"},"./_generated/component":{"types":"./dist/component/_generated/component.d.ts","default":"./dist/component/_generated/component.js"}},"publishConfig":{"access":"public"},"peerDependencies":{"convex":"^1.36.1","react":"^18.3.1 || ^19.0.0"},"dependencies":{"@types/spark-md5":"^3.0.5","spark-md5":"^3.0.2"},"devDependencies":{"@edge-runtime/vm":"^5.0.0","@payfastt/config":"workspace:*","@types/node":"^25.9.3","@types/react":"^19.2.15","@types/react-dom":"^19.2.3","convex":"^1.36.1","convex-test":"^0.0.53","react":"^19.2.6","react-dom":"^19.2.6","typescript":"^6.0.3","vitest":"^4.1.4"},"gitHead":"a7a030ec73ea698ac0bb9b8498edc36b8711285d","_id":"@bazileros/payfast@0.2.5","bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"homepage":"https://github.com/bazileros/payfastt#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-3E89T1QHv7QlSvXBfevVT/thEZDYUJ5yV0+6TT0enP3SOJQW8wfB9NtGjdblCyJ3dXdgsCgLTaK74Fp92A2Q/w==","shasum":"b7a3473d91f0a665085134b16d8d3b3bfc78ba67","tarball":"https://registry.npmjs.org/@bazileros/payfast/-/payfast-0.2.5.tgz","fileCount":71,"unpackedSize":224997,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bazileros%2fpayfast@0.2.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIH7+EEz09frWfnWqjieFhYst2AWg1tzbtvk6gJBnZ6oXAiEA0uf/Q4VrpGho9y/DRsUlP69qZEMM18ccQf39Cd1QmJU="}]},"_npmUser":{"name":"bazileros","email":"zalisilesithule@gmail.com"},"directories":{},"maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/payfast_0.2.5_1783055226383_0.6760825131832167"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-18T21:56:44.965Z","modified":"2026-07-03T05:07:06.889Z","0.1.0":"2026-06-18T21:56:45.323Z","0.2.0":"2026-06-21T21:57:21.968Z","0.2.3":"2026-06-23T12:16:30.051Z","0.2.4":"2026-07-03T04:38:20.669Z","0.2.5":"2026-07-03T05:07:06.577Z"},"bugs":{"url":"https://github.com/bazileros/payfastt/issues"},"license":"Apache-2.0","homepage":"https://github.com/bazileros/payfastt#readme","repository":{"type":"git","url":"git+https://github.com/bazileros/payfastt.git","directory":"packages/payfast"},"description":"PayFast payment gateway Convex component — one-time payments, subscriptions, tokenized charges, refunds, and ITN webhooks","maintainers":[{"name":"bazileros","email":"zalisilesithule@gmail.com"}],"readme":"![PayFast](Payfast-logo.svg)\n\n# @bazileros/payfast — PayFast Convex Component\n\nPayFast payment gateway integration for Convex apps. One-time payments (Custom Integration form redirect), recurring billing, tokenized charges, refunds, and ITN webhook processing.\n\n## Setup\n\n```bash\nnpm install @bazileros/payfast\n```\n\n### 1. Register the component\n\n`convex/convex.config.ts`:\n\n```ts\nimport { defineApp } from \"convex/server\";\nimport payfast from \"@bazileros/payfast/convex.config\";\nimport { v } from \"convex/values\";\n\nconst app = defineApp({\n  env: {\n    PAYFAST_MERCHANT_ID: v.string(),\n    PAYFAST_MERCHANT_KEY: v.string(),\n    PAYFAST_PASSPHRASE: v.string(),\n    PAYFAST_SANDBOX: v.optional(v.string()),\n  },\n});\n\napp.use(payfast, {\n  env: {\n    PAYFAST_MERCHANT_ID: app.env.PAYFAST_MERCHANT_ID,\n    PAYFAST_MERCHANT_KEY: app.env.PAYFAST_MERCHANT_KEY,\n    PAYFAST_PASSPHRASE: app.env.PAYFAST_PASSPHRASE,\n    PAYFAST_SANDBOX: app.env.PAYFAST_SANDBOX,\n  },\n});\n\nexport default app;\n```\n\n| Variable | Required | Description |\n|---|---|---|\n| `PAYFAST_MERCHANT_ID` | Yes | PayFast merchant ID |\n| `PAYFAST_MERCHANT_KEY` | Yes | PayFast merchant key |\n| `PAYFAST_PASSPHRASE` | Yes | PayFast passphrase |\n| `PAYFAST_SANDBOX` | No | Set `\"true\"` for sandbox |\n\n### 2. Mount ITN webhook\n\n`convex/http.ts`:\n\n```ts\nimport { registerRoutes } from \"@bazileros/payfast\";\nimport { httpRouter } from \"convex/server\";\nimport { components } from \"./_generated/api\";\n\nconst http = httpRouter();\nregisterRoutes(http, components.payfast, {\n  events: {\n    onPaymentComplete: (ctx, pfData) => {\n      // grant access, send email, etc.\n    },\n    onPaymentCancelled: (ctx, pfData) => {\n      // handle cancellation\n    },\n  },\n});\nexport default http;\n```\n\nConfigure PayFast to send ITNs to `https://<your-deployment>.convex.cloud/http/payfast/itn`.\n\n### 3. Use React hooks\n\nWrap your app with `PayfastProvider` for context-based hooks:\n\n```tsx\nimport { PayfastProvider, usePayfastCheckout } from \"@bazileros/payfast/react\";\nimport { components } from \"../convex/_generated/api\";\n\nfunction App() {\n  return (\n    <PayfastProvider component={components.payfast}>\n      <DonateButton />\n    </PayfastProvider>\n  );\n}\n\nfunction DonateButton() {\n  // No need to pass component — it comes from context\n  const { generateCheckout, formActionUrl, formFields, loading } = usePayfastCheckout({\n    amount: 100,\n    itemName: \"Donation\",\n  });\n  return (\n    <form action={formActionUrl} method=\"POST\">\n      {formFields && Object.entries(formFields).map(([k, v]) => (\n        <input key={k} type=\"hidden\" name={k} value={v} />\n      ))}\n      <button type=\"submit\" disabled={loading}>Donate R100</button>\n    </form>\n  );\n}\n```\n\nYou can also pass the component explicitly if not using the provider:\n\n```tsx\nconst { generateCheckout, formActionUrl, formFields } = usePayfastCheckout(components.payfast, {\n  amount: 100,\n  itemName: \"Donation\",\n});\n```\n\n## Features\n\n### Payment method\n\nRestrict which payment methods the buyer sees:\n\n```tsx\nusePayfastCheckout({\n  amount: 100,\n  itemName: \"Widget\",\n  paymentMethod: \"cc\",    // credit card only\n});\n```\n\nAvailable values:\n\n| Code | Method |\n|---|---|\n| `ef` | EFT |\n| `cc` | Credit Card |\n| `dc` | Debit Card |\n| `mp` | Masterpass |\n| `mc` | Mobicred |\n| `sc` | SCode |\n| `ss` | SnapScan |\n| `zp` | Zapper |\n| `mt` | MoreTyme |\n| `rc` | Store Card |\n| `mu` | Mukuru |\n| `ap` | Apple Pay |\n| `sp` | Samsung Pay |\n| `cp` | Capitec Pay |\n| `ab` | Absa Pay |\n| `gp` | Google Pay |\n| `nd` | Nedbank Direct EFT |\n| `pf` | Payflex (Buy Now, Pay Later) |\n\n### Split payments\n\nSplit a transaction across multiple receivers:\n\n```tsx\nusePayfastCheckout({\n  amount: 100,\n  itemName: \"Marketplace sale\",\n  setup: JSON.stringify({\n    split_payments: [\n      { merchant_id: \"10000123\", percentage: 90 },\n      { merchant_id: \"10000456\", percentage: 10 },\n    ],\n  }),\n});\n```\n\n### One-time payment (Custom Integration)\n\n```tsx\nconst { generateCheckout, formActionUrl, formFields, loading, error } = usePayfastCheckout({\n  amount: 100,\n  itemName: \"Donation\",\n  returnUrl: \"https://mysite.com/success\",\n  cancelUrl: \"https://mysite.com/cancel\",\n  notifyUrl: \"https://mydeployment.convex.cloud/http/payfast/itn\",\n  mPaymentId: \"order-123\",\n});\n```\n\n### Onsite payments (hosted iframe)\n\n**Not available in sandbox mode.**\n\n```tsx\nimport { usePayfastOnsite } from \"@bazileros/payfast/react\";\n\nconst { generateOnsite, paymentIdentifier, loading } = usePayfastOnsite({\n  amount: 100,\n  itemName: \"Widget\",\n  returnUrl: \"https://mysite.com/success\",\n  cancelUrl: \"https://mysite.com/cancel\",\n});\n// Pass paymentIdentifier to PayFast engine.js\n```\n\n### List transactions\n\n```tsx\nimport { useTransactions } from \"@bazileros/payfast/react\";\n\nfunction TransactionList() {\n  const transactions = useTransactions({ userId: \"user_1\", limit: 10 });\n  return <pre>{JSON.stringify(transactions, null, 2)}</pre>;\n}\n```\n\n### Subscription management\n\n```tsx\nimport { useSubscriptionActions } from \"@bazileros/payfast/react\";\n\nfunction SubscriptionControls({ token }: { token: string }) {\n  const { pause, unpause, cancel, update } = useSubscriptionActions(token);\n  return (\n    <>\n      <button onClick={pause}>Pause</button>\n      <button onClick={unpause}>Resume</button>\n      <button onClick={cancel}>Cancel</button>\n      <button onClick={() => update({ amount: 200 })}>Change to R200</button>\n    </>\n  );\n}\n```\n\n### Adhoc charges\n\nCharge a subscription outside its billing cycle.\n\n**Not available in sandbox mode.**\n\n```tsx\nimport { useAdhocCharge } from \"@bazileros/payfast/react\";\n\nconst { charge, loading, error } = useAdhocCharge();\nawait charge({ token: \"tok_abc\", amount: 50, itemName: \"One-off delivery\" });\n```\n\n### Refunds\n\n**Not available in sandbox mode.**\n\n```tsx\nimport { useRefund } from \"@bazileros/payfast/react\";\n\nconst { refund, loading, error } = useRefund();\nawait refund({ ptxId: \"1701500\", amount: 100 });\n```\n\n### Server-side class\n\n```ts\nimport { Payfast } from \"@bazileros/payfast\";\nimport { components } from \"../_generated/api\";\n\nconst pf = new Payfast(components.payfast, {\n  sandbox: true,\n  getUserInfo: async (ctx) => ({ userId: \"user_1\" }),\n});\n\n// Auto-resolves userId from getUserInfo\nawait pf.createCheckoutSession(ctx, { amount: 100, itemName: \"Widget\" });\nawait pf.pauseSubscription(ctx, { token: \"tok_abc\" });\nawait pf.listTransactions(ctx, { status: \"COMPLETE\" });\n\n// Card update URL for subscriptions\nconst url = pf.getCardUpdateUrl(\"tok_abc\", \"https://mysite.com/cards\");\n```\n\n## Architecture\n\n- `src/component/lib.ts` — Convex functions: checkout, ITN persistence, subscriptions, refunds\n- `src/component/http.ts` — ITN webhook with echo-back + signature validation\n- `src/component/itn.ts` — Shared ITN validation (IP, echo-back, signature)\n- `src/client/index.ts` — `Payfast` class, `registerRoutes` helper, `ItnEventHandlers`\n- `src/react/index.ts` — React hooks over `useQuery`/`useMutation`/`useAction`\n- `src/react/context.tsx` — `PayfastProvider` for context-based hook usage\n","readmeFilename":"README.md"}