Subscriptions API
The Subscriptions API v1 enables you to create products, billing plans, and manage recurring subscriptions.
Official Documentation: PayPal Subscriptions API v1
Installation
Add the Subscriptions API dependency to your project:
Creating the Client
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
public class Example {
public static void main(String[] args) {
// Create client (uses environment variables for credentials)
var client = SubscriptionsApiClient.create();
// Access various APIs
var productsApi = client.products();
var billingPlansApi = client.billingPlans();
var subscriptionsApi = client.subscriptions();
}
}
Common Operations
Create a Product
Create a product that can be associated with billing plans:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.*;
public class CreateProductExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Build the product request
var productRequest = ProductRequest.builder()
.name("Premium Membership")
.description("Access to premium features and content")
.type(Product.Type.SERVICE)
.category(Product.Category.SOFTWARE)
.imageUrl("https://example.com/premium.jpg")
.homeUrl("https://example.com")
.build();
// Create the product
var product = client.products()
.create()
.withBody(productRequest)
.retrieve()
.toEntity();
System.out.println("Product ID: " + product.id());
System.out.println("Product Name: " + product.name());
}
}
Expected Output:
Create a Billing Plan
Create a billing plan with pricing and billing cycles:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.*;
import java.util.List;
public class CreateBillingPlanExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Build the billing plan
var planRequest = PlanRequest.builder()
.productId("PROD-6XB24663H4094933M")
.name("Premium Membership Plan")
.description("Monthly subscription to premium features")
.billingCycles(List.of(
BillingCycle.builder()
.frequency(Frequency.builder()
.intervalUnit(Frequency.IntervalUnit.MONTH)
.intervalCount(1)
.build())
.tenureType(BillingCycle.TenureType.REGULAR)
.sequence(1)
.totalCycles(0) // 0 means infinite
.pricingScheme(PricingScheme.builder()
.fixedPrice(Money.builder()
.currencyCode("USD")
.value("19.99")
.build())
.build())
.build()
))
.paymentPreferences(PaymentPreferences.builder()
.autoBillOutstanding(true)
.setupFeeFailureAction(PaymentPreferences.SetupFeeFailureAction.CONTINUE)
.paymentFailureThreshold(3)
.build())
.build();
// Create the plan
var plan = client.billingPlans()
.create()
.withBody(planRequest)
.retrieve()
.toEntity();
System.out.println("Plan ID: " + plan.id());
System.out.println("Plan Name: " + plan.name());
System.out.println("Status: " + plan.status());
}
}
Create a Subscription
Create a subscription for a customer:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.*;
import java.time.ZonedDateTime;
public class CreateSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Build the subscription request
var subscriptionRequest = SubscriptionRequest.builder()
.planId("P-5ML4271244454362WXNWU5NQ")
.startTime(ZonedDateTime.now().plusDays(1).toString())
.subscriber(Subscriber.builder()
.name(Name.builder()
.givenName("John")
.surname("Doe")
.build())
.emailAddress("john.doe@example.com")
.build())
.applicationContext(ApplicationContext.builder()
.brandName("Example Store")
.locale("en-US")
.shippingPreference(ApplicationContext.ShippingPreference.NO_SHIPPING)
.userAction(ApplicationContext.UserAction.SUBSCRIBE_NOW)
.returnUrl("https://example.com/return")
.cancelUrl("https://example.com/cancel")
.build())
.build();
// Create the subscription
var subscription = client.subscriptions()
.create()
.withBody(subscriptionRequest)
.retrieve()
.toEntity();
System.out.println("Subscription ID: " + subscription.id());
System.out.println("Status: " + subscription.status());
// Get approval URL
var approvalUrl = subscription.links().stream()
.filter(link -> "approve".equals(link.rel()))
.findFirst()
.map(LinkDescription::href)
.orElse("N/A");
System.out.println("Approval URL: " + approvalUrl);
}
}
Get Subscription Details
Retrieve details of an existing subscription:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
public class GetSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Get subscription by ID
var subscription = client.subscriptions()
.get()
.withId("I-BW452GLLEP1G")
.retrieve()
.toEntity();
System.out.println("Subscription ID: " + subscription.id());
System.out.println("Status: " + subscription.status());
System.out.println("Plan ID: " + subscription.planId());
// Get subscriber info
var subscriber = subscription.subscriber();
System.out.println("Subscriber: " +
subscriber.name().givenName() + " " +
subscriber.name().surname());
}
}
Suspend a Subscription
Temporarily suspend a subscription:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.SuspendRequest;
public class SuspendSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Suspend subscription
var suspendRequest = SuspendRequest.builder()
.reason("Customer requested suspension")
.build();
client.subscriptions()
.suspend()
.withId("I-BW452GLLEP1G")
.withBody(suspendRequest)
.retrieve()
.toVoid();
System.out.println("Subscription suspended successfully");
}
}
Activate a Subscription
Reactivate a suspended subscription:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.ActivateRequest;
public class ActivateSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Activate subscription
var activateRequest = ActivateRequest.builder()
.reason("Customer requested reactivation")
.build();
client.subscriptions()
.activate()
.withId("I-BW452GLLEP1G")
.withBody(activateRequest)
.retrieve()
.toVoid();
System.out.println("Subscription activated successfully");
}
}
Cancel a Subscription
Cancel a subscription:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.CancelRequest;
public class CancelSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Cancel subscription
var cancelRequest = CancelRequest.builder()
.reason("Customer requested cancellation")
.build();
client.subscriptions()
.cancel()
.withId("I-BW452GLLEP1G")
.withBody(cancelRequest)
.retrieve()
.toVoid();
System.out.println("Subscription cancelled successfully");
}
}
Async Operations
All operations support asynchronous execution:
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.subscriptions.v1.model.*;
import java.util.concurrent.CompletableFuture;
public class AsyncSubscriptionExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
// Create product, plan, and subscription asynchronously
CompletableFuture<Subscription> subscriptionFuture =
createProductAsync(client)
.thenCompose(product -> createPlanAsync(client, product.id()))
.thenCompose(plan -> createSubscriptionAsync(client, plan.id()));
// Handle result
subscriptionFuture.thenAccept(subscription -> {
System.out.println("Subscription created: " + subscription.id());
}).exceptionally(ex -> {
System.err.println("Error: " + ex.getMessage());
return null;
});
subscriptionFuture.join();
}
private static CompletableFuture<Product> createProductAsync(
SubscriptionsApiClient client) {
return client.products()
.create()
.withBody(ProductRequest.builder()
.name("Premium Membership")
.type(Product.Type.SERVICE)
.build())
.retrieve()
.toFuture()
.thenApply(response -> response.toEntity());
}
private static CompletableFuture<Plan> createPlanAsync(
SubscriptionsApiClient client, String productId) {
// Implementation similar to above
return CompletableFuture.completedFuture(null); // Placeholder
}
private static CompletableFuture<Subscription> createSubscriptionAsync(
SubscriptionsApiClient client, String planId) {
// Implementation similar to above
return CompletableFuture.completedFuture(null); // Placeholder
}
}
Error Handling
import io.github.eealba.payper.subscriptions.v1.api.SubscriptionsApiClient;
import io.github.eealba.payper.core.PayperException;
public class ErrorHandlingExample {
public static void main(String[] args) {
var client = SubscriptionsApiClient.create();
var response = client.billingSubscriptions()
.get()
.withId("INVALID_ID")
.retrieve()
.toResponse();
if (response.isSuccessful()) {
var subscription = response.toEntity();
System.out.println("Subscription: " + subscription.id());
System.out.println("Status: " + subscription.status());
} else {
System.err.println("API Error - Status: " + response.statusCode());
// Access error details
var errorEntity = response.toErrorEntity();
System.err.println("Error: " + errorEntity.message());
}
}
}
Related Resources
- Official PayPal Subscriptions API Documentation
- Subscriptions Example - Complete subscription workflow
- Authentication Guide - Configure credentials
- Async Operations - Learn more about async patterns