nusii/nusii-php
Composer 安装命令:
composer require nusii/nusii-php
包简介
PHP client library for the Nusii proposal software API
关键字:
README 文档
README
A PHP client library for the Nusii proposal software API.
Requires PHP 8.3+ and uses Guzzle for HTTP requests.
Installation
Install via Composer:
composer require nusii/nusii-php
Quick Start
use Nusii\Nusii; $nusii = new Nusii('your-api-key'); // List your clients $clients = $nusii->clients()->list(); foreach ($clients as $client) { echo $client['name'] . "\n"; }
Custom Base URL
For self-hosted or development environments:
$nusii = new Nusii('your-api-key', baseUrl: 'http://localhost:3000');
Resources
Account
// Get current account $account = $nusii->accounts()->me(); echo $account['name']; // "Acme Corp" echo $account['email']; // "owner@acme.com" echo $account['currency']; // "USD" echo $account['subdomain']; // "acme"
Clients
// List clients (paginated) $clients = $nusii->clients()->list(page: 1, perPage: 10); echo $clients->totalCount; // 42 echo $clients->currentPage; // 1 echo $clients->totalPages; // 5 foreach ($clients as $client) { echo $client['name']; } // Get a single client $client = $nusii->clients()->get(id: 123); // Create a client $client = $nusii->clients()->create([ 'name' => 'John', 'surname' => 'Doe', 'email' => 'john@example.com', 'business' => 'Acme Inc', 'telephone' => '555-1234', 'address' => '123 Main St', 'city' => 'New York', 'postcode' => '10001', 'country' => 'US', 'state' => 'NY', 'web' => 'https://acme.com', 'currency' => 'USD', 'locale' => 'en', ]); // Update a client $client = $nusii->clients()->update(123, [ 'name' => 'Jane', 'business' => 'Updated Corp', ]); // Delete a client $nusii->clients()->delete(123);
Proposals
// List proposals $proposals = $nusii->proposals()->list(); // Filter by status: draft, pending, accepted, rejected $drafts = $nusii->proposals()->list(status: 'draft'); // Filter archived proposals $archived = $nusii->proposals()->list(archived: true); // Get a single proposal $proposal = $nusii->proposals()->get(456); // Create a proposal $proposal = $nusii->proposals()->create([ 'title' => 'Website Redesign', 'client_id' => 123, 'expires_at' => '2025-12-31', 'currency' => 'EUR', 'theme' => 'clean', ]); // Update a proposal $proposal = $nusii->proposals()->update(456, [ 'title' => 'Updated Proposal Title', ]); // Send a proposal $result = $nusii->proposals()->send( id: 456, email: 'client@example.com', subject: 'Your Proposal', // optional message: 'Please review attached.', // optional cc: 'manager@example.com', // optional bcc: 'archive@example.com', // optional ); // Archive a proposal $proposal = $nusii->proposals()->archive(456); // Delete a proposal $nusii->proposals()->delete(456);
Sections
// List all sections $sections = $nusii->sections()->list(); // List sections for a specific proposal $sections = $nusii->sections()->list(proposalId: 456); // List sections for a specific template $sections = $nusii->sections()->list(templateId: 789); // Include line items in the response $sections = $nusii->sections()->list(proposalId: 456, includeLineItems: true); // Get a single section $section = $nusii->sections()->get(10); // Create a section $section = $nusii->sections()->create([ 'proposal_id' => 456, 'title' => 'Project Scope', 'body' => '<p>Detailed project scope description.</p>', 'position' => 1, 'section_type' => 'cost', // "cost" or "text" 'optional' => false, 'include_total' => true, 'page_break' => false, ]); // Update a section $section = $nusii->sections()->update(10, [ 'title' => 'Updated Section Title', 'body' => '<p>Updated content.</p>', ]); // Delete a section $nusii->sections()->delete(10);
Line Items
Line items belong to sections. They must be created under a section.
// List line items for a section $items = $nusii->lineItems()->listBySection(sectionId: 10); // Get a single line item $item = $nusii->lineItems()->get(50); // Create a line item for a section $item = $nusii->lineItems()->createForSection(sectionId: 10, attributes: [ 'name' => 'Design Work', 'quantity' => 10, 'amount' => 7500, // in cents 'cost_type' => 'per', // "fixed", "recurring", "per" or "range" 'per_type' => 'hour', 'position' => 1, ]); // Create a price range line item ("$5,000 – $8,000"). // "amount" is the low end and "maximum_amount" the high end, both in cents. // Requires the price ranges feature to be enabled for your account. $item = $nusii->lineItems()->createForSection(sectionId: 10, attributes: [ 'name' => 'Discovery & UX research', 'cost_type' => 'range', 'amount' => 500000, 'maximum_amount' => 800000, ]); echo $item['maximum_amount_in_cents']; // 800000 echo $item['maximum_amount_formatted']; // "$8,000.00" // Update a line item $item = $nusii->lineItems()->update(50, [ 'name' => 'Updated Design Work', 'quantity' => 20, ]); // Delete a line item $nusii->lineItems()->delete(50);
Templates
Templates are read-only.
// List templates $templates = $nusii->templates()->list(); // Get a single template $template = $nusii->templates()->get(5); echo $template['name']; // "Web Project Template"
Proposal Activities
Proposal activities are read-only and track events like views, accepts, and rejections.
// List all activities $activities = $nusii->proposalActivities()->list(); // Filter by proposal $activities = $nusii->proposalActivities()->list(proposalId: 456); // Filter by client $activities = $nusii->proposalActivities()->list(clientId: 123); // Get a single activity $activity = $nusii->proposalActivities()->get(1); echo $activity['activity_type']; // "viewed", "accepted", "rejected" echo $activity['proposal_title']; // "Website Redesign" echo $activity['client_email']; // "john@example.com"
Users
Users are read-only.
// List users on the account $users = $nusii->users()->list(); foreach ($users as $user) { echo $user['email']; echo $user['name']; }
Themes
Themes are read-only. Note: this endpoint returns a plain array, not a paginated response.
// List available themes $themes = $nusii->themes()->list(); foreach ($themes as $theme) { echo $theme['id']; echo $theme['name']; // "Classic", "Modern", etc. }
Webhook Endpoints
// List webhook endpoints $webhooks = $nusii->webhookEndpoints()->list(); // Get a single webhook endpoint $webhook = $nusii->webhookEndpoints()->get(1); // Create a webhook endpoint $webhook = $nusii->webhookEndpoints()->create([ 'target_url' => 'https://example.com/webhooks/nusii', 'events' => [ 'proposal_created', 'proposal_accepted', 'proposal_rejected', 'proposal_sent', ], ]); // Delete a webhook endpoint $nusii->webhookEndpoints()->delete(1);
Available webhook events:
| Event | Description |
|---|---|
proposal_created |
A proposal was created |
proposal_updated |
A proposal was updated |
proposal_destroyed |
A proposal was deleted |
proposal_accepted |
A proposal was accepted by the client |
proposal_rejected |
A proposal was rejected by the client |
proposal_sent |
A proposal was sent to the client |
client_created |
A client was created |
client_updated |
A client was updated |
client_destroyed |
A client was deleted |
proposal_activity_client_viewed |
A client viewed something |
proposal_activity_client_viewed_proposal |
A client viewed a proposal |
Pagination
All list endpoints return a PaginatedResponse object that is both countable and iterable:
$response = $nusii->clients()->list(page: 1, perPage: 10); // Pagination metadata $response->currentPage; // 1 $response->nextPage; // 2 (or null) $response->prevPage; // null (or int) $response->totalPages; // 5 $response->totalCount; // 42 // Navigation helpers $response->hasNextPage(); // true $response->hasPrevPage(); // false // Iterate directly foreach ($response as $item) { echo $item['name']; } // Count echo count($response); // items on current page // Access raw data array $response->data; // array of items
Paginating Through All Results
$page = 1; do { $response = $nusii->clients()->list(page: $page, perPage: 50); foreach ($response as $client) { // Process each client } $page++; } while ($response->hasNextPage());
Error Handling
The library throws specific exceptions for different HTTP error codes:
use Nusii\Exceptions\AuthenticationException; use Nusii\Exceptions\NotFoundException; use Nusii\Exceptions\ValidationException; use Nusii\Exceptions\RateLimitException; use Nusii\Exceptions\ServerException; use Nusii\Exceptions\NusiiException; try { $client = $nusii->clients()->get(99999); } catch (AuthenticationException $e) { // 401 - Invalid API key echo $e->getMessage(); } catch (NotFoundException $e) { // 404 - Resource not found echo $e->getMessage(); } catch (ValidationException $e) { // 400, 403, 422 - Validation or permission errors echo $e->getMessage(); echo $e->getCode(); // HTTP status code print_r($e->responseBody); // Raw response body } catch (RateLimitException $e) { // 429 - Rate limit exceeded (100 requests per 30 seconds) echo $e->retryAfter; // Seconds to wait before retrying } catch (ServerException $e) { // 500, 503 - Server errors echo $e->getMessage(); } catch (NusiiException $e) { // Catch-all for any other API errors echo $e->getMessage(); }
All exceptions extend NusiiException, so you can catch that to handle any API error.
Rate Limiting
The Nusii API allows 100 requests per 30 seconds. Rate limit information is tracked on the client instance:
$nusii->clients()->list(); echo $nusii->rateLimitRemaining; // 99 echo $nusii->rateLimitRetryAfter; // null (or seconds to wait)
Testing
Run the unit tests:
composer test
Or with Pest directly:
./vendor/bin/pest
Integration Tests
Integration tests run against a live API server. Set the environment variables and run:
NUSII_API_KEY=your-key NUSII_API_URL=http://localhost:3000 ./vendor/bin/pest tests/IntegrationTest.php
Integration tests are automatically skipped when NUSII_API_KEY is not set.
Authentication
The library uses token authentication. Include your API key when creating the client:
$nusii = new Nusii('your-api-key');
All requests include the header:
Authorization: Token token=your-api-key
You can find your API key in your Nusii account settings under Integrations.
Requirements
- PHP 8.3 or higher
- Guzzle 7.0 or higher
License
MIT
nusii/nusii-php 适用场景与选型建议
nusii/nusii-php 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 10 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「api」 「client」 「proposals」 「nusii」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 nusii/nusii-php 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 nusii/nusii-php 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 nusii/nusii-php 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A PSR-7 compatible library for making CRUD API endpoints
Mock PSR-18 HTTP client
Asynchronous MQTT client built on React
Client for Google Directions API to add interpolated points to a route consisting of given coordinates.
A Flickr wrapper to allow you to call the Flickr api with Guzzle as the backend.Goal is to have 100% Flickr api coverage rather than just upload/display photos (currently at 23%).
Official PHP client library for the Enlivy API
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 25
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-10