@playflixtv/paypal-sdk
v0.0.4
Published
PayPal SDK for PlayflixTV
Readme
@playflixtv/paypal-sdk
Typed TypeScript SDK for PayPal Billing APIs used by Playflix.
It builds on PayPal’s official @paypal/paypal-server-sdk for OAuth and billing plans, and keeps the same public types and method names as before.
This package wraps common PayPal operations for:
- products
- billing plans
- subscriptions
- webhook signature verification
It is designed for backend/server use only.
Installation
npm install @playflixtv/paypal-sdkRequirements
- Node.js 18+ (uses the global
fetchAPI) - PayPal REST credentials:
PAYPAL_CLIENT_IDPAYPAL_CLIENT_SECRET
By default, the client uses PayPal Sandbox (https://api-m.sandbox.paypal.com). Pass { environment: PayPalEnvironment.Production } for live.
Quick start
import { PayPal, PayPalEnvironment } from "@playflixtv/paypal-sdk";
const paypal = new PayPal(
process.env.PAYPAL_CLIENT_ID!,
process.env.PAYPAL_CLIENT_SECRET!,
// { environment: PayPalEnvironment.Production },
);Typed imports
The SDK exports request/response types and enums for safer integrations.
import {
PayPal,
CreatePlanPayload,
CreateSubscriptionPayload,
VerifyWebhookSignaturePayload,
PayPalSubscriptionResponse,
PayPalPlanResponse,
PayPalPlansListResponse,
PayPalProductResponse,
} from "@playflixtv/paypal-sdk";API reference
new PayPal(clientId, clientSecret, options?)
Creates a PayPal API client (backed by @paypal/paypal-server-sdk).
const paypal = new PayPal(clientId, clientSecret);
// Live:
// const paypal = new PayPal(clientId, clientSecret, {
// environment: PayPalEnvironment.Production,
// });paypal.Client
Read-only access to the underlying PayPal Client from @paypal/paypal-server-sdk (OAuth, environment, advanced configuration).
request<TResponse, TPayload>(method, path, data?)
Low-level typed request helper. Useful for endpoints not yet wrapped by first-class methods.
const response = await paypal.request<{ id: string }>("GET", "/v1/billing/plans/P-123");Products
createProduct(payload)
Creates a PayPal catalog product.
const product = await paypal.createProduct({
name: "Playflix Premium",
type: "SERVICE",
description: "Premium streaming subscription",
category: "SOFTWARE",
image_url: "https://example.com/logo.png",
home_url: "https://playflix.tv",
});Returns: PayPalProductResponse
Billing plans
createBillingPlan(payload)
Creates a billing plan associated with a PayPal product.
const planPayload: CreatePlanPayload = {
product_id: "PROD-XXXX",
name: "Premium Monthly",
status: "ACTIVE",
description: "Monthly premium plan",
billing_cycles: [
{
tenure_type: "REGULAR",
sequence: 1,
total_cycles: 0,
frequency: { interval_unit: "MONTH", interval_count: 1 },
pricing_scheme: {
fixed_price: { value: "19.90", currency_code: "USD" },
},
},
],
payment_preferences: {
auto_bill_outstanding: true,
setup_fee_failure_action: "CONTINUE",
payment_failure_threshold: 3,
},
};
const plan = await paypal.createBillingPlan(planPayload);Returns: PayPalPlanResponse
getBillingPlans()
Lists billing plans.
const plans = await paypal.getBillingPlans();Returns: PayPalPlansListResponse
getBillingPlan(planId)
Gets a specific billing plan.
const plan = await paypal.getBillingPlan("P-XXXX");Returns: PayPalPlanResponse
deactivateBillingPlan(planId)
Deactivates a billing plan.
await paypal.deactivateBillingPlan("P-XXXX");Returns: empty object response from PayPal.
Subscriptions
createSubscription(payload)
Creates a subscription for a billing plan.
application_context defaults are applied automatically:
brand_name: "PlayFlix"locale: "en-US"shipping_preference: "NO_SHIPPING"user_action: "SUBSCRIBE_NOW"
You can override defaults and add return_url / cancel_url.
const payload: CreateSubscriptionPayload = {
plan_id: "P-XXXX",
custom_id: "internal-customer-id",
subscriber: {
email_address: "[email protected]",
name: {
given_name: "Jane",
surname: "Doe",
},
},
application_context: {
return_url: "https://api.example.com/paypal/return",
cancel_url: "https://api.example.com/paypal/cancel",
},
};
const subscription = await paypal.createSubscription(payload);Returns: PayPalSubscriptionResponse
getSubscription(subscriptionId)
const subscription = await paypal.getSubscription("I-XXXX");Returns: PayPalSubscriptionResponse
activateSubscription(subscriptionId, reason?)
const subscription = await paypal.activateSubscription(
"I-XXXX",
"Reactivated by support",
);Returns: latest PayPalSubscriptionResponse
reviseSubscription(subscriptionId, planId)
Switches an existing subscription to another plan.
const subscription = await paypal.reviseSubscription("I-XXXX", "P-NEWPLAN");Returns: latest PayPalSubscriptionResponse
cancelSubscription(subscriptionId, reason?)
const subscription = await paypal.cancelSubscription(
"I-XXXX",
"User requested cancellation",
);Returns: latest PayPalSubscriptionResponse
Webhooks
verifyWebhookSignature(payload)
Validates incoming webhook signatures using PayPal API.
const verifyPayload: VerifyWebhookSignaturePayload = {
auth_algo: headers["paypal-auth-algo"] as string,
cert_url: headers["paypal-cert-url"] as string,
transmission_id: headers["paypal-transmission-id"] as string,
transmission_sig: headers["paypal-transmission-sig"] as string,
transmission_time: headers["paypal-transmission-time"] as string,
webhook_id: process.env.PAYPAL_WEBHOOK_ID!,
webhook_event: body,
};
const verification = await paypal.verifyWebhookSignature(verifyPayload);
if (verification.verification_status !== "SUCCESS") {
throw new Error("Invalid PayPal webhook signature");
}Returns: VerifyWebhookSignatureResponse
Error handling
SDK methods throw Error with a contextual message when PayPal request/auth fails.
try {
const plans = await paypal.getBillingPlans();
} catch (error) {
console.error("PayPal call failed:", error);
}Build
npm run buildNotes
- Keep credentials server-side only.
- This SDK uses sandbox API base URL by default.
- Catalog products and webhook verification use the same OAuth token as the official SDK (the PayPal TypeScript server SDK does not yet expose controllers for those APIs).
- For unsupported endpoints, prefer
request<TResponse, TPayload>()and contribute a typed wrapper method back to the SDK.
