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