@playcamp/node-sdk
v0.0.4
Published
TypeScript-first Node.js SDK for PlayCamp API
Readme
PlayCamp SDK
TypeScript-first Node.js SDK for the PlayCamp API.
Installation
npm install @playcamp/node-sdkRequirements: Node.js >= 18.0.0
Quick Start
Client SDK (Read-only)
Use PlayCampClient with a CLIENT API key for read-only operations:
import { PlayCampClient } from '@playcamp/node-sdk';
const client = new PlayCampClient('your_client_key:your_secret');
// List campaigns
const { data: campaigns, pagination } = await client.campaigns.listCampaigns();
// Get a specific campaign
const campaign = await client.campaigns.getCampaign('campaign_id');
// Get campaign creators
const creators = await client.campaigns.getCreators('campaign_id');
// Search creators
const results = await client.creators.search({ keyword: 'gaming' });
// Get a creator by key
const creator = await client.creators.getCreator('ABCDE');
// Validate a coupon
const validation = await client.coupons.validate({ couponCode: 'CODE123' });
// Check sponsor status
const sponsor = await client.sponsors.getSponsor({ userId: 'user_123' });Server SDK (Read/Write)
Use PlayCampServer with a SERVER API key for full read/write access:
import { PlayCampServer } from '@playcamp/node-sdk';
const server = new PlayCampServer('your_server_key:your_secret');
// Redeem a coupon
const result = await server.coupons.redeem({
couponCode: 'CODE123',
userId: 'user_abc',
});
// Create a sponsor relationship
const sponsor = await server.sponsors.create({
userId: 'user_abc',
creatorKey: 'ABCDE',
});
// Record a payment
const payment = await server.payments.create({
userId: 'user_abc',
transactionId: 'txn_123',
productId: 'product_abc',
amount: 9.99,
currency: 'USD',
platform: 'iOS',
purchasedAt: new Date().toISOString(),
});
// Configure webhooks
const webhook = await server.webhooks.create({
eventType: 'coupon.redeemed',
url: 'https://your-server.com/webhooks/playcamp',
});Configuration
const client = new PlayCampClient('key:secret', {
environment: 'sandbox', // 'sandbox' | 'live' (default: 'live')
timeout: 30000, // Request timeout in ms (default: 30000)
isTest: false, // Enable test mode (default: false)
maxRetries: 3, // Max retry attempts (default: 3)
debug: true, // Enable debug logging (default: false)
});Environments
| Environment | URL | Purpose |
|-------------|-----|---------|
| sandbox | https://sandbox-sdk-api.playcamp.io | Development/Testing |
| live | https://sdk-api.playcamp.io | Production (default) |
You can also specify a custom URL directly:
const client = new PlayCampClient('key:secret', {
baseUrl: 'http://localhost:3003', // Overrides environment setting
});Pagination
List endpoints return paginated results:
// Get a single page
const { data, pagination, hasNextPage } = await client.campaigns.listCampaigns({
page: 1,
limit: 20,
});
// Iterate through all items
for await (const campaign of client.campaigns.listAllCampaigns()) {
console.log(campaign.campaignId);
}Error Handling
The SDK throws typed errors for different scenarios:
import {
PlayCampApiError,
PlayCampAuthError,
PlayCampNotFoundError,
PlayCampRateLimitError,
PlayCampNetworkError,
} from '@playcamp/node-sdk';
try {
await client.campaigns.getCampaign('invalid_id');
} catch (error) {
if (error instanceof PlayCampNotFoundError) {
console.log('Campaign not found');
} else if (error instanceof PlayCampAuthError) {
console.log('Invalid API key');
} else if (error instanceof PlayCampRateLimitError) {
console.log('Rate limited, retry after:', error.retryAfter);
} else if (error instanceof PlayCampNetworkError) {
console.log('Network error:', error.message);
} else if (error instanceof PlayCampApiError) {
console.log('API error:', error.code, error.message);
}
}Webhook Verification
Verify incoming webhook signatures:
import { verifyWebhook } from '@playcamp/node-sdk';
// In your webhook handler
app.post('/webhooks/playcamp', (req, res) => {
const result = verifyWebhook({
payload: req.rawBody, // Raw request body (string or Buffer)
signature: req.headers['x-webhook-signature'],
secret: 'your_webhook_secret',
tolerance: 300, // Optional: max age in seconds (default: 300)
});
if (!result.valid) {
return res.status(401).json({ error: result.error });
}
// Webhooks contain batched events
for (const event of result.payload.events) {
switch (event.event) {
case 'coupon.redeemed':
console.log('Coupon redeemed:', event.data.couponCode);
break;
case 'payment.created':
console.log('Payment created:', event.data.transactionId);
break;
case 'sponsor.created':
console.log('Sponsor created:', event.data.userId);
break;
}
}
res.status(200).json({ received: true });
});Testing Webhooks
Generate test signatures for local development:
import { constructWebhookSignature } from '@playcamp/node-sdk';
const payload = JSON.stringify({
events: [{
event: 'coupon.redeemed',
timestamp: new Date().toISOString(),
data: { couponCode: 'TEST', userId: 'user_123', usageId: 1, reward: [] },
}]
});
const signature = constructWebhookSignature(payload, 'your_webhook_secret');API Reference
Client Resources
| Resource | Methods |
|----------|---------|
| campaigns | listCampaigns(), listAllCampaigns(), getCampaign(), getCreators(), getPackages() |
| creators | getCreator(), search() |
| coupons | validate() |
| sponsors | getSponsor() |
Server Resources
| Resource | Methods |
|----------|---------|
| campaigns | listCampaigns(), listAllCampaigns(), getCampaign(), getCreators() |
| creators | getCreator(), search(), getCoupons() |
| coupons | validate(), redeem(), getUserHistory(), listAllUserHistory() |
| sponsors | create(), getByUser(), update(), remove(), getHistory(), listAllHistory() |
| payments | create(), getByTransactionId(), listByUser(), listAllByUser(), refund() |
| webhooks | listWebhooks(), create(), update(), remove(), getLogs(), test() |
TypeScript
The SDK is written in TypeScript and exports all types:
import type {
Campaign,
Creator,
CouponValidation,
RedeemResult,
Sponsor,
Payment,
Webhook,
WebhookPayload,
} from '@playcamp/node-sdk';Development
npm run build # Build SDK
npm run dev # Watch mode build
npm test # Run tests
npm run lint # Run ESLint
npm run typecheck # TypeScript checkLicense
MIT
