Added all
This commit is contained in:
parent
2db7ea5ef6
commit
c54091917e
53
README.md
53
README.md
@ -1,3 +1,52 @@
|
|||||||
# PayForPress-Server-SDK
|
# PayForPress Node.js SDK
|
||||||
|
|
||||||
Official Server side SDK for PayForPress
|
Official Node.js SDK for PayForPress API - An onboarding, paywall and payment solution for online media.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install payforpress-node-sdk
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { PayForPress } from 'payforpress-node-sdk';
|
||||||
|
|
||||||
|
// Initialize the SDK with your API key
|
||||||
|
const pfp = new PayForPress({
|
||||||
|
apiKey: 'your-api-key-here'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Example: Get user information
|
||||||
|
async function getUser() {
|
||||||
|
try {
|
||||||
|
const user = await pfp.users.get({ email: 'user@example.com' });
|
||||||
|
console.log('User:', user);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- User Management
|
||||||
|
- Article Management
|
||||||
|
- Payment Processing
|
||||||
|
- Analytics
|
||||||
|
- Appearance Settings
|
||||||
|
- Targeting Rules
|
||||||
|
- Organization Settings
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
For detailed API documentation, please visit our [API Documentation](https://payforpress.gitbook.io/payforpress/api-pfp-connect/api-pfp-connect).
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
This SDK is designed to be used on the server-side only. Never expose your API key in client-side code.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
47
package.json
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "payforpress-node-sdk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Official Node.js Server SDK for PayForPress API - An onboarding, paywall and payment solution for online media",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"test": "jest",
|
||||||
|
"lint": "eslint src/**/*.ts",
|
||||||
|
"format": "prettier --write \"src/**/*.ts\"",
|
||||||
|
"prepare": "npm run build"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"payforpress",
|
||||||
|
"paywall",
|
||||||
|
"onboarding",
|
||||||
|
"payment",
|
||||||
|
"micropayment",
|
||||||
|
"applepay",
|
||||||
|
"googlepay",
|
||||||
|
"paypal",
|
||||||
|
"stripe",
|
||||||
|
"media",
|
||||||
|
"api",
|
||||||
|
"sdk"
|
||||||
|
],
|
||||||
|
"author": "PayForPress",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://gitea.reduav.eu/PayForPress/PayForPress-Server-SDK"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.7"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.11.19",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.0.1",
|
||||||
|
"@typescript-eslint/parser": "^7.0.1",
|
||||||
|
"eslint": "^8.56.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"prettier": "^3.2.5",
|
||||||
|
"ts-jest": "^29.1.2",
|
||||||
|
"typescript": "^5.3.3"
|
||||||
|
}
|
||||||
|
}
|
48
src/client.ts
Normal file
48
src/client.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||||
|
import { PayForPressConfig, Error } from './types';
|
||||||
|
|
||||||
|
export class PayForPressClient {
|
||||||
|
private client: AxiosInstance;
|
||||||
|
private config: PayForPressConfig;
|
||||||
|
|
||||||
|
constructor(config: PayForPressConfig) {
|
||||||
|
this.config = config;
|
||||||
|
this.client = axios.create({
|
||||||
|
baseURL: config.baseUrl || 'https://payfor.press/api/v3',
|
||||||
|
headers: {
|
||||||
|
'pfp-api-key': config.apiKey,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add response interceptor for error handling
|
||||||
|
this.client.interceptors.response.use(
|
||||||
|
(response) => response.data,
|
||||||
|
(error) => {
|
||||||
|
if (error.response) {
|
||||||
|
throw error.response.data;
|
||||||
|
}
|
||||||
|
throw {
|
||||||
|
success: false,
|
||||||
|
message: error.message || 'An unexpected error occurred'
|
||||||
|
} as Error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async post<T>(endpoint: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return this.client.post(endpoint, data, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async get<T>(endpoint: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return this.client.get(endpoint, { ...config, params });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async put<T>(endpoint: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return this.client.put(endpoint, data, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async delete<T>(endpoint: string, config?: AxiosRequestConfig): Promise<T> {
|
||||||
|
return this.client.delete(endpoint, config);
|
||||||
|
}
|
||||||
|
}
|
122
src/index.ts
Normal file
122
src/index.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import {
|
||||||
|
PayForPressConfig,
|
||||||
|
UserResponse,
|
||||||
|
UserUpdate,
|
||||||
|
SearchParams,
|
||||||
|
ArticleResponse,
|
||||||
|
ArticlesResponse,
|
||||||
|
ArticleFilters,
|
||||||
|
AppearanceSchema,
|
||||||
|
TargetingSchema,
|
||||||
|
SettingsResponse,
|
||||||
|
OrganizationDetails,
|
||||||
|
PaymentResponse,
|
||||||
|
PaymentCreateParams,
|
||||||
|
PaymentSearchParams,
|
||||||
|
PaymentsResponse,
|
||||||
|
Article
|
||||||
|
} from './types';
|
||||||
|
import { PayForPressClient } from './client';
|
||||||
|
|
||||||
|
export class PayForPress extends PayForPressClient {
|
||||||
|
constructor(config: PayForPressConfig) {
|
||||||
|
super(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// User Management
|
||||||
|
async getUser(params: { email?: string; id?: string }): Promise<UserResponse> {
|
||||||
|
return this.post('/users/get', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createUser(user: UserUpdate): Promise<UserResponse> {
|
||||||
|
return this.post('/users/create', user);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateUser(id: string, user: UserUpdate): Promise<UserResponse> {
|
||||||
|
return this.post('/users/update', { id, newProps: user });
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteUser(id: string): Promise<{ success: boolean; message: string }> {
|
||||||
|
return this.post('/users/delete', { id });
|
||||||
|
}
|
||||||
|
|
||||||
|
async searchUsers(
|
||||||
|
params: SearchParams
|
||||||
|
): Promise<{ success: boolean; users: any[]; total: number }> {
|
||||||
|
return this.post('/users/search', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Article Management
|
||||||
|
async getArticle(
|
||||||
|
params: { id?: string; url?: string } | ArticleFilters
|
||||||
|
): Promise<ArticleResponse | ArticlesResponse> {
|
||||||
|
return this.post('/articles/get', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createArticle(url: string): Promise<ArticleResponse> {
|
||||||
|
return this.post('/articles/create', { url });
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateArticle(id: string, article: Partial<Article>): Promise<ArticleResponse> {
|
||||||
|
return this.post('/articles/update', { id, ...article });
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteArticle(id: string): Promise<{ success: boolean }> {
|
||||||
|
return this.post('/articles/delete', { id });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appearance Settings
|
||||||
|
async getAppearance(): Promise<{ success: boolean; appearance: AppearanceSchema }> {
|
||||||
|
return this.post('/appearance/get');
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAppearance(
|
||||||
|
appearance: AppearanceSchema
|
||||||
|
): Promise<{ success: boolean; appearance: AppearanceSchema }> {
|
||||||
|
return this.post('/appearance/update', appearance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Targeting Settings
|
||||||
|
async getTargeting(): Promise<{ targeting: TargetingSchema }> {
|
||||||
|
return this.post('/targeting/get');
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateTargeting(
|
||||||
|
targeting: TargetingSchema
|
||||||
|
): Promise<{ message: string; targeting: TargetingSchema }> {
|
||||||
|
return this.post('/targeting/update', { targeting });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Organization Settings
|
||||||
|
async getSettings(): Promise<SettingsResponse> {
|
||||||
|
return this.post('/settings/get');
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateSettings(settings: OrganizationDetails): Promise<SettingsResponse> {
|
||||||
|
return this.post('/settings/update', settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payment Management
|
||||||
|
async createPayment(params: PaymentCreateParams): Promise<PaymentResponse> {
|
||||||
|
return this.post('/payments/create', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPayment(id: string): Promise<PaymentResponse> {
|
||||||
|
return this.post('/payments/get', { id });
|
||||||
|
}
|
||||||
|
|
||||||
|
async searchPayments(params: PaymentSearchParams): Promise<PaymentsResponse> {
|
||||||
|
return this.post('/payments/search', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analytics
|
||||||
|
async getAnalytics(params: {
|
||||||
|
type: 'get' | 'search';
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
|
}): Promise<{ success: boolean; data: any }> {
|
||||||
|
return this.post('/analytics', params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export * from './types';
|
223
src/types.ts
Normal file
223
src/types.ts
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
export interface PayForPressConfig {
|
||||||
|
apiKey: string;
|
||||||
|
baseUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Error {
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
email: string;
|
||||||
|
phone?: string;
|
||||||
|
id: string;
|
||||||
|
metadata?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserUpdate {
|
||||||
|
email?: string;
|
||||||
|
phone?: string;
|
||||||
|
name?: string;
|
||||||
|
metadata?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserResponse {
|
||||||
|
success: boolean;
|
||||||
|
user: User;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchParams {
|
||||||
|
skip?: number;
|
||||||
|
limit?: number;
|
||||||
|
value?: string;
|
||||||
|
field?: string;
|
||||||
|
operator?: '==' | '!=' | '>' | '<' | '>=' | '<=' | '~' | '!~';
|
||||||
|
order?: 'asc' | 'desc';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Article {
|
||||||
|
id: string;
|
||||||
|
url: string;
|
||||||
|
title?: string;
|
||||||
|
author_name?: string;
|
||||||
|
price?: number;
|
||||||
|
high_value?: boolean;
|
||||||
|
org?: string;
|
||||||
|
created_at?: string;
|
||||||
|
updated_at?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArticleResponse {
|
||||||
|
success: boolean;
|
||||||
|
article: Article;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArticlesResponse {
|
||||||
|
success: boolean;
|
||||||
|
articles: Article[];
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ArticleFilters {
|
||||||
|
skip?: number;
|
||||||
|
limit?: number;
|
||||||
|
search?: string;
|
||||||
|
sort?: 'created_at' | 'updated_at' | 'title' | 'price';
|
||||||
|
order?: 'asc' | 'desc';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppearanceSchema {
|
||||||
|
primaryColor?: string;
|
||||||
|
theme?: 'dark' | 'light' | 'system';
|
||||||
|
large?: boolean;
|
||||||
|
borderRadius?: number;
|
||||||
|
margin?: number;
|
||||||
|
horizontalAlignment?: 'left' | 'center' | 'right';
|
||||||
|
verticalAlignment?: 'top' | 'center' | 'bottom';
|
||||||
|
inject?: boolean;
|
||||||
|
injectSelector?: string;
|
||||||
|
injectStyle?: string;
|
||||||
|
prepend?: boolean;
|
||||||
|
injectDelay?: number;
|
||||||
|
backgroundColor?: string;
|
||||||
|
paywallMode?: boolean;
|
||||||
|
deleteSelector?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GraphNode {
|
||||||
|
variable:
|
||||||
|
| 'time'
|
||||||
|
| 'device'
|
||||||
|
| 'url'
|
||||||
|
| 'referrer'
|
||||||
|
| 'country'
|
||||||
|
| 'browser'
|
||||||
|
| 'loggedIn'
|
||||||
|
| 'firstTimeSessions'
|
||||||
|
| 'recurringLoadOfArticle'
|
||||||
|
| 'visitedUrls'
|
||||||
|
| 'highValue'
|
||||||
|
| 'elementPresent'
|
||||||
|
| 'alreadyPayforPress'
|
||||||
|
| 'mobileConnection'
|
||||||
|
| 'isp'
|
||||||
|
| 'proxy'
|
||||||
|
| 'hosting'
|
||||||
|
| 'continent';
|
||||||
|
matchingType:
|
||||||
|
| '='
|
||||||
|
| 'startsWith'
|
||||||
|
| 'endsWith'
|
||||||
|
| 'contains'
|
||||||
|
| 'notContains'
|
||||||
|
| '!='
|
||||||
|
| 'in'
|
||||||
|
| 'notIn'
|
||||||
|
| '>'
|
||||||
|
| '<'
|
||||||
|
| '>='
|
||||||
|
| '<='
|
||||||
|
| 'between'
|
||||||
|
| 'notBetween'
|
||||||
|
| 'selectorMatches'
|
||||||
|
| 'selectorNotMatches'
|
||||||
|
| 'regex';
|
||||||
|
value:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| string[]
|
||||||
|
| {
|
||||||
|
hourStart: number;
|
||||||
|
minuteStart: number;
|
||||||
|
hourEnd: number;
|
||||||
|
minuteEnd: number;
|
||||||
|
};
|
||||||
|
true: 'showPayForPress' | 'hidePayForPress' | 'excludeUser' | 'default' | 'addCondition';
|
||||||
|
false: 'showPayForPress' | 'hidePayForPress' | 'excludeUser' | 'default' | 'addCondition';
|
||||||
|
trueNode?: GraphNode;
|
||||||
|
falseNode?: GraphNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TargetingVariable {
|
||||||
|
key: string;
|
||||||
|
keep?: boolean;
|
||||||
|
type?: 'string' | 'number' | 'boolean' | 'array';
|
||||||
|
value: any;
|
||||||
|
id?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TargetingSchema {
|
||||||
|
showForAll?: boolean;
|
||||||
|
defaultShow?: boolean;
|
||||||
|
variables?: TargetingVariable[];
|
||||||
|
graph?: GraphNode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OrganizationDetails {
|
||||||
|
allowBuyArticle?: boolean;
|
||||||
|
allowHighValueArticlesInPass?: boolean;
|
||||||
|
allowHighValueArticlesInSubscription?: boolean;
|
||||||
|
allowMonthlyPass?: boolean;
|
||||||
|
allowSubscription?: boolean;
|
||||||
|
allowTimePass?: boolean;
|
||||||
|
blockAds?: boolean;
|
||||||
|
discountAfterOne?: number;
|
||||||
|
icon?: string;
|
||||||
|
keepOriginalNavBar?: boolean;
|
||||||
|
logoUrl?: string;
|
||||||
|
monthlyPassPrice?: number;
|
||||||
|
onboardingStep?: string;
|
||||||
|
postPayment?: boolean;
|
||||||
|
priceForHighValueArticles?: number;
|
||||||
|
pricePerArticle?: number;
|
||||||
|
removeSelectors?: string;
|
||||||
|
subscriptionPrice?: number;
|
||||||
|
timePassLength?: string;
|
||||||
|
timePassPrice?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SettingsResponse {
|
||||||
|
details: OrganizationDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Payment {
|
||||||
|
id: string;
|
||||||
|
amountCents: number;
|
||||||
|
article?: string;
|
||||||
|
buyer: string;
|
||||||
|
expires_at: string;
|
||||||
|
renews: boolean;
|
||||||
|
transaction_date: string;
|
||||||
|
type: 'article' | 'pass' | 'subscription';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentResponse {
|
||||||
|
success: boolean;
|
||||||
|
purchase: Payment;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentsResponse {
|
||||||
|
success: boolean;
|
||||||
|
purchases: Payment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentCreateParams {
|
||||||
|
user_id: string;
|
||||||
|
purchase_type: 'article' | 'pass' | 'subscription';
|
||||||
|
amountCents: number;
|
||||||
|
currency?: 'eur';
|
||||||
|
expires_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentSearchParams {
|
||||||
|
user_id?: string;
|
||||||
|
type?: 'article' | 'pass' | 'subscription';
|
||||||
|
before?: string;
|
||||||
|
after?: string;
|
||||||
|
limit?: number;
|
||||||
|
skip?: number;
|
||||||
|
}
|
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2020",
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user