{"_id":"@clink-ai/clink-typescript-sdk","_rev":"3-7617e6b1b0530e0d5663be8a12d879ff","name":"@clink-ai/clink-typescript-sdk","dist-tags":{"latest":"1.0.1"},"versions":{"0.0.3":{"name":"@clink-ai/clink-typescript-sdk","version":"0.0.3","keywords":["clinkbill","clinkpay"],"author":{"url":"https://www.clinkbill.com/","name":"Clink","email":"support@clinkbill.com"},"license":"MIT","_id":"@clink-ai/clink-typescript-sdk@0.0.3","maintainers":[{"name":"clink-official","email":"patrick@clinkbill.com"}],"dist":{"shasum":"9f602d8f9096199b7580f4e3696f79b2b334456a","tarball":"https://registry.npmjs.org/@clink-ai/clink-typescript-sdk/-/clink-typescript-sdk-0.0.3.tgz","fileCount":16,"integrity":"sha512-DS23l2anI/Hpnb8OLHBWztTehiAns5aeHUNXmSGMM7e6ZOCjuG9sz6NyZQfVPuSqK9xrqWKmFZ8xcDk5PDk0/g==","signatures":[{"sig":"MEQCIBSNGtuSfAzLnJo517nC4krXNS4e5suff/RKb74zrHFlAiB/YsvdqR7/KlgGr6OumjDKx70BsVwWCkGc6OUuP/6Vjg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33539},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"fc0c0df409f89112685476d69cbd33be9e28c21d","scripts":{"test":"vitest */*.test.ts","build":"tsc","test:api":"vitest test/api.test.ts","clean-dist":"rm -rf ./dist","test:webhook":"vitest test/webhook.test.ts"},"_npmUser":{"name":"clink-official","email":"patrick@clinkbill.com"},"_npmVersion":"11.5.1","description":"npm package for clinkbill","directories":{},"_nodeVersion":"24.5.0","dependencies":{"alova":"3.3.4","crypto-js":"4.2.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.0.13","prettier":"3.6.2","typescript":"^5","@types/node":"24.10.1","@types/crypto-js":"^4.2.2"},"_npmOperationalInternal":{"tmp":"tmp/clink-typescript-sdk_0.0.3_1777533792742_0.26872142287363054","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@clink-ai/clink-typescript-sdk","version":"1.0.0","keywords":["clinkbill","clinkpay"],"author":{"url":"https://www.clinkbill.com/","name":"Clink","email":"support@clinkbill.com"},"license":"MIT","_id":"@clink-ai/clink-typescript-sdk@1.0.0","maintainers":[{"name":"clink-official","email":"patrick@clinkbill.com"}],"dist":{"shasum":"0892b570955d83255717a00631fd81844123e940","tarball":"https://registry.npmjs.org/@clink-ai/clink-typescript-sdk/-/clink-typescript-sdk-1.0.0.tgz","fileCount":16,"integrity":"sha512-RFAHfNH0KbxcUecU3U9c7X75xUI/15VoCggwVPxICNtE6OXxyNePSFIof5/TR0IEknyBy+/uCMJwTdh+4BO1DA==","signatures":[{"sig":"MEUCIQDsBsbQ/YnRTXjDbwzX8bqRFMX8IrGP8CGfL3Drw7/B9gIgd3DKvYWTGfQNOEZ5sUDkkEdTI5em0dfjZLqLOsRoaE4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73723},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"a371b7b9781508be964655120716fad2af369da0","scripts":{"test":"vitest */*.test.ts","build":"tsc","test:api":"vitest test/api.test.ts","clean-dist":"rm -rf ./dist","test:webhook":"vitest test/webhook.test.ts"},"_npmUser":{"name":"clink-official","email":"patrick@clinkbill.com"},"_npmVersion":"11.5.1","description":"npm package for clinkbill","directories":{},"_nodeVersion":"24.5.0","dependencies":{"alova":"3.3.4","crypto-js":"4.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.0.13","prettier":"3.6.2","typescript":"^5","@types/node":"24.10.1","@types/crypto-js":"^4.2.2"},"_npmOperationalInternal":{"tmp":"tmp/clink-typescript-sdk_1.0.0_1781237786021_0.5642224812815286","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@clink-ai/clink-typescript-sdk","version":"1.0.1","author":{"name":"Clink","email":"support@clinkbill.com","url":"https://www.clinkbill.com/"},"description":"npm package for clinkbill","keywords":["clinkbill","clinkpay"],"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","test:api":"vitest test/api.test.ts","test:webhook":"vitest test/webhook.test.ts","test":"vitest */*.test.ts","clean-dist":"rm -rf ./dist"},"license":"MIT","dependencies":{"alova":"3.3.4","crypto-js":"4.2.0"},"devDependencies":{"@types/crypto-js":"^4.2.2","@types/node":"24.10.1","prettier":"3.6.2","typescript":"^5","vite":"7.3.6","vitest":"4.1.10"},"engines":{"node":">=18"},"_id":"@clink-ai/clink-typescript-sdk@1.0.1","gitHead":"789edb32a93e0f3e8d534ef3c2b4bc89ec900646","_nodeVersion":"24.5.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-4crnc/2cs8U0CSkf0nGpbPSzMyHXT+fezM7UilKRmB9nv6oVT0zM9InqRkJI3vuE8WPRn723JHqxZAbUV5v8+Q==","shasum":"32ce6bc2bd934db8ac0666b268118066e61b29d7","tarball":"https://registry.npmjs.org/@clink-ai/clink-typescript-sdk/-/clink-typescript-sdk-1.0.1.tgz","fileCount":16,"unpackedSize":87689,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC26udoNyLOA1MVq0yuYxw+mPtcNsWvrhbSbqIWyoYtowIhAIvMFpamjoa6mML6iEhAh4bOgQK/PTkPbTulkdWVb+mR"}]},"_npmUser":{"name":"clink-official","email":"patrick@clinkbill.com"},"directories":{},"maintainers":[{"name":"clink-official","email":"patrick@clinkbill.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/clink-typescript-sdk_1.0.1_1785297557603_0.698725791290089"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-30T07:23:12.668Z","modified":"2026-07-29T03:59:17.935Z","0.0.3":"2026-04-30T07:23:12.886Z","1.0.0":"2026-06-12T04:16:26.169Z","1.0.1":"2026-07-29T03:59:17.770Z"},"author":{"name":"Clink","email":"support@clinkbill.com","url":"https://www.clinkbill.com/"},"license":"MIT","keywords":["clinkbill","clinkpay"],"description":"npm package for clinkbill","maintainers":[{"name":"clink-official","email":"patrick@clinkbill.com"}],"readme":"# ClinkPay Client SDK Guide\n\nLightweight client for Clink billing APIs, It supports `production` and `sandbox` environments and handles authentication and errors for you.\n\nFor detailed API reference, see https://docs.clinkbill.com/api-reference/introduction.\n\n## Requirements\n- Runtime with `fetch` support (e.g., Node.js 18+).\n- Only `env` values `production` and `sandbox` are supported; any other value throws. the default value is `production`.\n\n## Import\nChoose your package management tool (such as npm, yarn, or pnpm) and import it according to your project configuration.\n\n```sh\nnpm install @clink-ai/@clink-ai/clink-typescript-sdk\n```\n\n## Quick Start\n```ts\nimport { ClinkPayClient } from '@clink-ai/@clink-ai/clink-typescript-sdk';\n\nconst client = new ClinkPayClient({\n  apiKey: 'YOUR_API_KEY',\n  env: 'sandbox',\n});\n\nasync function main() {\n  const session = await client.createCheckoutSession({\n    originalAmount: 1999,\n    originalCurrency: 'USD',\n    successUrl: 'https://merchant.example.com/success',\n    cancelUrl: 'https://merchant.example.com/cancel',\n    allowPromotionCodes: true,\n  });\n\n  console.log(session.sessionId);\n  console.log(session.url);\n}\n\nmain();\n```\n\n## API Overview\n- `createCheckoutSession(options)`: Create a checkout session and get the redirect `url`.\n- `getCheckoutSession(sessionId)`: Retrieve checkout session details.\n- `createOneTimePayment(options)`: Create a one-time payment with an existing payment instrument.\n- `createPaymentInstrument(options)`: Create a wallet payment instrument for a customer.\n- `refreshWalletQrCode(orderId)`: Refresh the wallet QR code for an existing order.\n- `getOrder(orderId)`: Retrieve order details.\n- `listOrders(params)`: List orders with optional filters.\n- `createAgentPaymentSession(options)`: Create an agent payment session.\n- `getAgentPaymentSession(sessionId)`: Retrieve an agent payment session.\n- `getRefund(refundId)`: Retrieve refund details.\n- `createRefund(options)`: Create a refund for an order.\n- `getSubscription(subscriptionId)`: Retrieve subscription details.\n- `createSubscription(options)`: Create a subscription and initiate the first payment.\n- `cancelSubscription(options)`: Cancel a subscription.\n- `getInvoice(invoiceId)`: Retrieve subscription invoice details.\n- `listTestClocks()`: List subscription test clocks.\n- `createTestClock(options)`: Create a subscription test clock.\n- `getTestClock(clockId)`: Retrieve a subscription test clock.\n- `advanceTestClock(clockId, options)`: Advance a subscription test clock.\n- `completeTestClock(clockId, options)`: Complete a subscription test clock.\n- `customerPortalSession(options)`: Create a customer portal session and get the access link.\n- `getProduct(productId)`: Retrieve product details.\n- `getProductList(params)`: List products.\n- `createProduct(options)`: Create a product.\n- `uploadProductImage(options)`: Upload a product image.\n- `getPrice(priceId)`: Retrieve price details.\n- `getPriceList(params)`: List prices.\n- `createPrice(options)`: Create a price.\n- `updatePrice(priceId, options)`: Update a price.\n- `createCoupon(options)`: Create a coupon.\n- `listCoupons(params)`: List coupons.\n- `getCoupon(couponId)`: Retrieve coupon details.\n- `renameCoupon(couponId, options)`: Rename a coupon.\n- `listPromotionCodesByCoupon(couponId)`: List promotion codes for a coupon.\n- `createPromotionCode(couponId, options)`: Create a promotion code for a coupon.\n- `getPromotionCode(promotionCodeId)`: Retrieve promotion code details.\n- `activatePromotionCode(promotionCodeId)`: Activate a promotion code.\n- `deactivatePromotionCode(promotionCodeId)`: Deactivate a promotion code.\n- `listWebhookEvents()`: List supported webhook events.\n- `listWebhookEndpoints(params)`: List webhook endpoints.\n- `createWebhookEndpoint(options)`: Create a webhook endpoint.\n- `ensureWebhookEndpoint(options)`: Create or reconcile a webhook endpoint by URL.\n- `getWebhookEndpoint(endpointId)`: Retrieve a webhook endpoint.\n- `updateWebhookEndpoint(endpointId, options)`: Update a webhook endpoint.\n- `deleteWebhookEndpoint(endpointId)`: Delete a webhook endpoint.\n- `enableWebhookEndpoint(endpointId)`: Enable a webhook endpoint.\n- `disableWebhookEndpoint(endpointId)`: Disable a webhook endpoint.\n- `rotateWebhookEndpointSecret(endpointId)`: Rotate a webhook signing secret.\n\nAll methods are asynchronous and throw on errors.\n\n## Error Handling\nOn non-successful responses or network errors, methods throw exceptions:\n- Business errors throw `ClinkApiError`.\n- Non-business errors throw standard `Error`.\n\nExample:\n```ts\nimport { ClinkPayClient } from '@clink-ai/clink-typescript-sdk';\n\nconst client = new ClinkPayClient({ apiKey: 'YOUR_API_KEY', env: 'sandbox' });\n\nasync function demo() {\n  try {\n    const order = await client.getOrder('ord_123');\n    console.log(order.status);\n  } catch (e) {\n    if (e instanceof ClinkApiError) {\n      const { code, message } = e;\n      // your code here\n    }\n    // handle other errors\n  }\n}\n\ndemo();\n```\n\n## Detailed Examples\n\n### Create a Checkout Session\n```ts\nconst client = new ClinkPayClient({ apiKey: 'YOUR_API_KEY', env: 'sandbox' });\nconst session = await client.createCheckoutSession({\n  originalAmount: 4999,\n  originalCurrency: 'USD',\n  successUrl: 'https://merchant.example.com/success',\n  cancelUrl: 'https://merchant.example.com/cancel',\n});\nconsole.log(session.sessionId);\nconsole.log(session.url);\n```\n\n### Get Checkout Session\n```ts\nconst info = await client.getCheckoutSession('sess_123');\nconsole.log(info.status);\n```\n\n### Get Order\n```ts\nconst order = await client.getOrder('ord_123');\nconsole.log(order.amountTotal);\n```\n\n### List Orders\n```ts\nconst orders = await client.listOrders({\n  customerId: 'cus_123',\n  pageNum: 1,\n  pageSize: 20,\n});\nconsole.log(orders.rows);\n```\n\n### Create One-Time Payment\n```ts\nconst payment = await client.createOneTimePayment({\n  customerId: 'cus_123',\n  paymentInstrumentId: 'pi_123',\n  paymentMethodType: 'CARD',\n  amount: 19.99,\n  currency: 'USD',\n  returnUrl: 'https://merchant.example.com/payment/return',\n  priceDataList: [\n    {\n      name: 'One-time service',\n      quantity: 1,\n      unitAmount: 19.99,\n      currency: 'USD',\n    },\n  ],\n});\nconsole.log(payment.orderId);\n```\n\n### Create Payment Instrument\n```ts\nconst instrument = await client.createPaymentInstrument({\n  customerId: 'cus_123',\n  paymentInstrumentType: 'CASHAPP',\n  customerName: 'Customer Name',\n  metadata: {\n    source: 'checkout',\n  },\n});\nconsole.log(instrument.id);\n```\n\n### Get Refund\n```ts\nconst refund = await client.getRefund('rfd_123');\nconsole.log(refund.status);\n```\n\n### Create Refund\n```ts\nconst refund = await client.createRefund({\n  orderId: 'order_123',\n  refundMerchantOrderId: 'merchant_refund_123',\n  refundAmount: 9.99,\n  refundReasonType: 2,\n  remark: 'Customer requested refund',\n});\nconsole.log(refund.refundId);\n```\n\n### Get Subscription\n```ts\nconst sub = await client.getSubscription('sub_123');\nconsole.log(sub.status);\n```\n\n### Create Subscription\n```ts\nconst subscription = await client.createSubscription({\n  customerId: 'cus_123',\n  productId: 'prd_123',\n  priceId: 'price_123',\n  paymentInstrumentId: 'pi_123',\n  paymentMethodType: 'CARD',\n  paymentCurrency: 'USD',\n  returnUrl: 'https://merchant.example.com/subscription/return',\n});\nconsole.log(subscription.subscriptionId);\n```\n\n### Cancel Subscription\n```ts\nconst canceled = await client.cancelSubscription({\n  subscriptionId: 'sub_123',\n  reason: 'No longer needed',\n  cancelReasonCode: 'no_longer_needed',\n});\nconsole.log(canceled.status);\n```\n\n### Get Invoice\n```ts\nconst invoice = await client.getInvoice('inv_123');\nconsole.log(invoice.status);\n```\n\n### Customer Portal Session\n```ts\nconst portal = await client.customerPortalSession({\n  customerId: 'cus_123',\n  returnUrl: 'https://merchant.example.com/return',\n});\nconsole.log(portal.url);\n```\n\n### Get Product Info\n\n```ts\nconst product = await client.getProduct('prod_123');\nconsole.log(product);\n```\n\n### Get Product List\n```ts\nconst products = await client.getProductList({\n  pageNum: 1,\n  pageSize: 10,\n});\nconsole.log(products);\n```\n\n### Create Product\n```ts\nconst product = await client.createProduct({\n  name: 'Pro Plan',\n  image: 'oss_123',\n  taxCategory: 'software_service',\n  description: 'Access to Pro features',\n});\nconsole.log(product.productId);\n```\n\n### Upload Product Image\n```ts\nconst uploaded = await client.uploadProductImage({\n  file: imageFile,\n});\nconsole.log(uploaded.ossId);\n```\n\n### Get Price Info\n```ts\nconst price = await client.getPrice('price_123');\nconsole.log(price);\n```\n### Get Price List\n```ts\nconst prices = await client.getPriceList({\n  productId: 'prd_123',\n  active: true,\n  pageNum: 1,\n  pageSize: 10,\n});\nconsole.log(prices);\n```\n\n### Create Price\n```ts\nconst price = await client.createPrice({\n  productId: 'prd_123',\n  currency: 'USD',\n  unitAmount: 19.99,\n  priceType: 'one_time',\n});\nconsole.log(price.priceId);\n```\n\n### Update Price\n```ts\nconst price = await client.updatePrice('price_123', {\n  unitAmount: 29.99,\n  isDefaultPrice: true,\n});\nconsole.log(price.priceId);\n```\n\n### Test Clocks\n```ts\nconst clocks = await client.listTestClocks();\nconst clock = await client.createTestClock({\n  name: 'April renewal simulation',\n  subscriptionId: 'sub_123',\n});\nawait client.advanceTestClock(clock.clockId!, {\n  targetFrozenTime: Date.now() + 30 * 24 * 60 * 60 * 1000,\n});\nawait client.completeTestClock(clock.clockId!, {\n  reason: 'Simulation complete',\n});\n```\n\n### Agent Payment Session\n```ts\nconst session = await client.createAgentPaymentSession({\n  customerEmail: 'customer@example.com',\n  amount: 19.99,\n  currency: 'USD',\n});\nconst sessionInfo = await client.getAgentPaymentSession(session.sessionId!);\nconsole.log(sessionInfo.expireTime);\n```\n\n### Coupons\n```ts\nconst coupon = await client.createCoupon({\n  couponName: 'Spring Sale',\n  discountType: 'percentage',\n  percentage: 20,\n  applyType: 'none',\n  durationType: 'once',\n});\n\nconst coupons = await client.listCoupons({\n  pageNum: 1,\n  pageSize: 20,\n});\n\nconst detail = await client.getCoupon(coupon.couponId!);\nawait client.renameCoupon(detail.couponId!, {\n  newName: 'Spring Sale 2026',\n});\n```\n\n### Promotion Codes\n```ts\nconst promotionCode = await client.createPromotionCode('coupon_123', {\n  code: 'SPRING20',\n  maxRedemptionLimit: 100,\n});\n\nconst codes = await client.listPromotionCodesByCoupon('coupon_123');\nconst detail = await client.getPromotionCode(promotionCode.promotionCodeId!);\n\nawait client.activatePromotionCode(detail.promotionCodeId!);\nawait client.deactivatePromotionCode(detail.promotionCodeId!);\nconsole.log(codes);\n```\n\n### Refresh Wallet QR Code\n```ts\nconst refreshed = await client.refreshWalletQrCode('order_123');\nconsole.log(refreshed.action?.walletHandleRedirectOrDisplayQrCode);\n```\n\n### Webhook Endpoints\n```ts\nconst events = await client.listWebhookEvents();\n\nconst ensured = await client.ensureWebhookEndpoint({\n  url: 'https://merchant.example.com/webhooks/clink',\n  events: ['session.complete', 'order.succeeded', 'invoice.paid'],\n  enabled: true,\n  returnSigningSecret: true,\n  rotateSecretIfUnavailable: true,\n});\n\nconsole.log(events.aliases?.core);\nconsole.log(ensured.endpoint?.id);\nconsole.log(ensured.endpoint?.signingSecret);\n```\n\nThe plaintext webhook signing secret is only returned when it is newly created\nor rotated. Store it securely when it is available.\n\n\n## webhook\n\n### Verify and Get Webhook Event\n```ts\nimport { ClinkWebhook } from '@clink-ai/clink-typescript-sdk';\n\nconst clinkWebhook = new ClinkWebhook({ signatureKey: 'YOUR_SIGNATURE_KEY' });\n// if verify error, the verifyAndGet method will throw error\nconst event = clinkWebhook.verifyAndGet({\n  timestamp: 'timestamp from request header',\n  body: 'body(jsonString) from request body',\n  headerSignature: 'signature from request header',\n});\nconsole.log(event);\n```\n","readmeFilename":"README.md"}