Manage recurring billing subscriptions for PayPal.
The PayPal Subscriptions API allows you to create and manage subscriptions, handle subscriber lifecycles (suspend, cancel, activate, revise), capture outstanding balances, and list subscription transactions.
Official PayPal API Documentation: PayPal Subscriptions API v1
Subscription Lifecycle
stateDiagram-v2
[*] --> APPROVAL_PENDING
APPROVAL_PENDING --> APPROVED
APPROVAL_PENDING --> CANCELLED
APPROVED --> ACTIVE
APPROVED --> CANCELLED
ACTIVE --> SUSPENDED
SUSPENDED --> ACTIVE
ACTIVE --> CANCELLED
ACTIVE --> EXPIRED
SUSPENDED --> CANCELLED
SUSPENDED --> EXPIRED
CANCELLED --> [*]
EXPIRED --> [*]Modules
Paypal.Subscription.Product- Catalog Products management.Paypal.Subscription.Plan- Billing Plans management.
Summary
Functions
Activate a subscription by ID.
Cancel a subscription by ID.
Capture an authorized payment on a subscription.
Create a subscription.
Revise plan or quantity for a subscription.
Show subscription details by ID.
Returns the list of valid subscription statuses
Suspend a subscription by ID.
List transactions for a subscription within a date range.
Update a subscription by ID using JSON Patch operations.
Functions
@spec activate(String.t(), String.t()) :: :ok | {:error, Paypal.Common.Error.t() | term()}
Activate a subscription by ID.
Official documentation: Activate Subscription
@spec cancel(String.t(), String.t()) :: :ok | {:error, Paypal.Common.Error.t() | term()}
Cancel a subscription by ID.
Official documentation: Cancel Subscription
@spec capture(String.t(), map()) :: {:ok, Paypal.Subscription.Capture.t()} | {:error, Paypal.Common.Error.t() | term()}
Capture an authorized payment on a subscription.
Official documentation: Capture Authorized Payment
Examples
iex> Paypal.Subscription.capture("I-BW452GLLEP1G", %{
...> note: "Charging outstanding balance",
...> capture_type: "OUTSTANDING_BALANCE",
...> amount: %{currency_code: "USD", value: "10.00"}
...> })
{:ok, %Paypal.Subscription.Capture{id: "CAP-123", ...}}
@spec create(map()) :: {:ok, Paypal.Subscription.Info.t()} | {:error, Paypal.Common.Error.t() | term()}
Create a subscription.
Official documentation: Create Subscription
Examples
iex> Paypal.Subscription.create(%{
...> plan_id: "P-5ML4271244454362WXNWU5NQ",
...> start_time: "2026-09-01T00:00:00Z",
...> subscriber: %{
...> name: %{given_name: "John", surname: "Doe"},
...> email_address: "buyer@example.com"
...> },
...> application_context: %{
...> brand_name: "My SaaS",
...> locale: "en-US",
...> return_url: "https://example.com/return",
...> cancel_url: "https://example.com/cancel"
...> }
...> })
{:ok, %Paypal.Subscription.Info{id: "I-BW452GLLEP1G", ...}}
@spec revise(String.t(), map()) :: {:ok, Paypal.Subscription.ReviseResponse.t()} | {:error, Paypal.Common.Error.t() | term()}
Revise plan or quantity for a subscription.
Official documentation: Revise Subscription
@spec show(String.t(), keyword() | map()) :: {:ok, Paypal.Subscription.Info.t()} | {:error, Paypal.Common.Error.t() | term()}
Show subscription details by ID.
Official documentation: Show Subscription Details
Options
:fields- Pass"plan"to include plan details in response.
@spec statuses() :: [ approval_pending: String.t(), approved: String.t(), active: String.t(), suspended: String.t(), cancelled: String.t(), expired: String.t() ]
Returns the list of valid subscription statuses:
:approval_pending- Subscription created, awaiting buyer approval.:approved- Buyer approved subscription.:active- Subscription is active and billing.:suspended- Subscription is suspended.:cancelled- Subscription has been cancelled.:expired- Subscription reached its end date.
@spec suspend(String.t(), String.t()) :: :ok | {:error, Paypal.Common.Error.t() | term()}
Suspend a subscription by ID.
Official documentation: Suspend Subscription
@spec transactions(String.t(), String.t(), String.t()) :: {:ok, Paypal.Subscription.Transactions.t()} | {:error, Paypal.Common.Error.t() | term()}
List transactions for a subscription within a date range.
Official documentation: List Transactions for Subscription
Parameters
id- The subscription ID.start_time- Start date-time filter (ISO 8601 string, e.g. "2026-01-01T00:00:00Z").end_time- End date-time filter (ISO 8601 string, e.g. "2026-08-01T00:00:00Z").
@spec update(String.t(), [map()]) :: :ok | {:error, Paypal.Common.Error.t() | term()}
Update a subscription by ID using JSON Patch operations.
Official documentation: Update Subscription