Payment Processing: Implementing Stripe Payment Gateway in Java Applications

Stripe provides a complete payments platform for internet businesses with powerful APIs for payment processing, subscription management, and financial operations. This guide covers complete Stripe integration in Java applications.

Architecture Overview

Java Application → Stripe Java SDK → Stripe API → Payment Processors
↑
(Payment Methods /
Subscription Management)

Step 1: Dependencies Setup

Maven Dependencies

<!-- pom.xml -->
<dependencies>
<!-- Stripe Java SDK -->
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>24.0.0</version>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Configuration -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- JSON Processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- HTTP Client -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
</dependencies>

Step 2: Configuration Classes

Stripe Configuration

// src/main/java/com/company/stripe/config/StripeConfig.java
package com.company.stripe.config;
import com.stripe.Stripe;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
@ConfigurationProperties(prefix = "stripe")
@Data
@Slf4j
public class StripeConfig {
// API Keys
private String secretKey;
private String publishableKey;
private String webhookSecret;
// API Version
private String apiVersion = "2023-10-16";
// Timeout Configuration
private int connectTimeout = 30000;
private int readTimeout = 80000;
// Max Network Retries
private int maxNetworkRetries = 2;
// Currency Configuration
private String defaultCurrency = "usd";
// Business Information
private String companyName;
private String supportEmail;
private String supportPhone;
// Webhook Configuration
private boolean enableWebhooks = true;
private String successUrl;
private String cancelUrl;
@PostConstruct
public void initialize() {
// Set Stripe API key
Stripe.apiKey = this.secretKey;
// Configure Stripe global settings
Stripe.setConnectTimeout(connectTimeout);
Stripe.setReadTimeout(readTimeout);
Stripe.setMaxNetworkRetries(maxNetworkRetries);
log.info("Stripe SDK initialized successfully");
log.debug("Stripe API Version: {}, Currency: {}", apiVersion, defaultCurrency);
}
public void validateConfiguration() {
if (secretKey == null || secretKey.trim().isEmpty()) {
throw new IllegalStateException("Stripe secret key is not configured");
}
if (publishableKey == null || publishableKey.trim().isEmpty()) {
throw new IllegalStateException("Stripe publishable key is not configured");
}
}
}

Application Properties

# application.yml
stripe:
secret-key: ${STRIPE_SECRET_KEY:sk_test_...}
publishable-key: ${STRIPE_PUBLISHABLE_KEY:pk_test_...}
webhook-secret: ${STRIPE_WEBHOOK_SECRET:whsec_...}
api-version: "2023-10-16"
connect-timeout: 30000
read-timeout: 80000
max-network-retries: 2
default-currency: "usd"
company-name: "Your Company"
support-email: "[email protected]"
support-phone: "+1234567890"
enable-webhooks: true
success-url: "https://yourdomain.com/success"
cancel-url: "https://yourdomain.com/cancel"
server:
port: 8080
logging:
level:
com.company.stripe: DEBUG
com.stripe: INFO

Step 3: Core Payment Service

Payment Service Implementation

// src/main/java/com/company/stripe/service/PaymentService.java
package com.company.stripe.service;
import com.company.stripe.config.StripeConfig;
import com.stripe.exception.StripeException;
import com.stripe.model.*;
import com.stripe.net.RequestOptions;
import com.stripe.param.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
@Service
@Slf4j
public class PaymentService {
private final StripeConfig stripeConfig;
public PaymentService(StripeConfig stripeConfig) {
this.stripeConfig = stripeConfig;
}
/**
* Create a payment intent for one-time payments
*/
public PaymentIntent createPaymentIntent(PaymentRequest request) {
try {
PaymentIntentCreateParams params = PaymentIntentCreateParams.builder()
.setAmount(convertToStripeAmount(request.getAmount()))
.setCurrency(request.getCurrency().toLowerCase())
.setCustomer(request.getCustomerId())
.setDescription(request.getDescription())
.setReceiptEmail(request.getReceiptEmail())
.setConfirmationMethod(PaymentIntentCreateParams.ConfirmationMethod.AUTOMATIC)
.setConfirm(true)
.setReturnUrl(stripeConfig.getSuccessUrl())
.setAutomaticPaymentMethods(
PaymentIntentCreateParams.AutomaticPaymentMethods.builder()
.setEnabled(true)
.build()
)
.putMetadata("order_id", request.getOrderId())
.putMetadata("user_id", request.getUserId())
.build();
PaymentIntent paymentIntent = PaymentIntent.create(params);
log.info("Payment intent created: {}", paymentIntent.getId());
return paymentIntent;
} catch (StripeException e) {
log.error("Failed to create payment intent", e);
throw new RuntimeException("Payment creation failed: " + e.getMessage(), e);
}
}
/**
* Confirm a payment intent
*/
public PaymentIntent confirmPaymentIntent(String paymentIntentId, String paymentMethodId) {
try {
PaymentIntentConfirmParams params = PaymentIntentConfirmParams.builder()
.setPaymentMethod(paymentMethodId)
.setReturnUrl(stripeConfig.getSuccessUrl())
.build();
PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId);
PaymentIntent confirmedIntent = paymentIntent.confirm(params);
log.info("Payment intent confirmed: {}", confirmedIntent.getId());
return confirmedIntent;
} catch (StripeException e) {
log.error("Failed to confirm payment intent: {}", paymentIntentId, e);
throw new RuntimeException("Payment confirmation failed: " + e.getMessage(), e);
}
}
/**
* Capture a payment intent (for authorized payments)
*/
public PaymentIntent capturePaymentIntent(String paymentIntentId) {
try {
PaymentIntentCaptureParams params = PaymentIntentCaptureParams.builder().build();
PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId);
PaymentIntent capturedIntent = paymentIntent.capture(params);
log.info("Payment intent captured: {}", capturedIntent.getId());
return capturedIntent;
} catch (StripeException e) {
log.error("Failed to capture payment intent: {}", paymentIntentId, e);
throw new RuntimeException("Payment capture failed: " + e.getMessage(), e);
}
}
/**
* Cancel a payment intent
*/
public PaymentIntent cancelPaymentIntent(String paymentIntentId) {
try {
PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId);
PaymentIntent canceledIntent = paymentIntent.cancel();
log.info("Payment intent canceled: {}", canceledIntent.getId());
return canceledIntent;
} catch (StripeException e) {
log.error("Failed to cancel payment intent: {}", paymentIntentId, e);
throw new RuntimeException("Payment cancellation failed: " + e.getMessage(), e);
}
}
/**
* Refund a payment
*/
public Refund createRefund(RefundRequest request) {
try {
RefundCreateParams params = RefundCreateParams.builder()
.setPaymentIntent(request.getPaymentIntentId())
.setAmount(convertToStripeAmount(request.getAmount()))
.setReason(convertRefundReason(request.getReason()))
.setMetadata(request.getMetadata())
.build();
Refund refund = Refund.create(params);
log.info("Refund created: {}", refund.getId());
return refund;
} catch (StripeException e) {
log.error("Failed to create refund for payment intent: {}", request.getPaymentIntentId(), e);
throw new RuntimeException("Refund creation failed: " + e.getMessage(), e);
}
}
/**
* Get payment intent by ID
*/
public PaymentIntent getPaymentIntent(String paymentIntentId) {
try {
PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId);
log.debug("Retrieved payment intent: {}", paymentIntentId);
return paymentIntent;
} catch (StripeException e) {
log.error("Failed to retrieve payment intent: {}", paymentIntentId, e);
throw new RuntimeException("Payment intent retrieval failed: " + e.getMessage(), e);
}
}
/**
* List payment intents with filtering
*/
public List<PaymentIntent> listPaymentIntents(PaymentListRequest request) {
try {
PaymentIntentListParams.Builder paramsBuilder = PaymentIntentListParams.builder()
.setLimit(request.getLimit());
if (request.getCustomerId() != null) {
paramsBuilder.setCustomer(request.getCustomerId());
}
if (request.getStatus() != null) {
paramsBuilder.addStatus(PaymentIntentListParams.Status.valueOf(request.getStatus().toUpperCase()));
}
PaymentIntentCollection paymentIntents = PaymentIntent.list(paramsBuilder.build());
return paymentIntents.getData();
} catch (StripeException e) {
log.error("Failed to list payment intents", e);
throw new RuntimeException("Payment intent listing failed: " + e.getMessage(), e);
}
}
/**
* Create a setup intent for saving payment methods
*/
public SetupIntent createSetupIntent(SetupIntentRequest request) {
try {
SetupIntentCreateParams params = SetupIntentCreateParams.builder()
.setCustomer(request.getCustomerId())
.setDescription(request.getDescription())
.setUsage(SetupIntentCreateParams.Usage.ON_SESSION)
.setAutomaticPaymentMethods(
SetupIntentCreateParams.AutomaticPaymentMethods.builder()
.setEnabled(true)
.build()
)
.putMetadata("user_id", request.getUserId())
.build();
SetupIntent setupIntent = SetupIntent.create(params);
log.info("Setup intent created: {}", setupIntent.getId());
return setupIntent;
} catch (StripeException e) {
log.error("Failed to create setup intent", e);
throw new RuntimeException("Setup intent creation failed: " + e.getMessage(), e);
}
}
/**
* Create a payment method
*/
public PaymentMethod createPaymentMethod(PaymentMethodRequest request) {
try {
PaymentMethodCreateParams.CardDetails cardDetails = PaymentMethodCreateParams.CardDetails.builder()
.setNumber(request.getCardNumber())
.setExpMonth(request.getExpMonth())
.setExpYear(request.getExpYear())
.setCvc(request.getCvc())
.build();
PaymentMethodCreateParams.BillingDetails billingDetails = PaymentMethodCreateParams.BillingDetails.builder()
.setName(request.getCardholderName())
.setEmail(request.getEmail())
.setPhone(request.getPhone())
.setAddress(
PaymentMethodCreateParams.BillingDetails.Address.builder()
.setLine1(request.getAddressLine1())
.setLine2(request.getAddressLine2())
.setCity(request.getCity())
.setState(request.getState())
.setPostalCode(request.getPostalCode())
.setCountry(request.getCountry())
.build()
)
.build();
PaymentMethodCreateParams params = PaymentMethodCreateParams.builder()
.setType(PaymentMethodCreateParams.Type.CARD)
.setCard(cardDetails)
.setBillingDetails(billingDetails)
.build();
PaymentMethod paymentMethod = PaymentMethod.create(params);
log.info("Payment method created: {}", paymentMethod.getId());
return paymentMethod;
} catch (StripeException e) {
log.error("Failed to create payment method", e);
throw new RuntimeException("Payment method creation failed: " + e.getMessage(), e);
}
}
/**
* Attach payment method to customer
*/
public PaymentMethod attachPaymentMethodToCustomer(String paymentMethodId, String customerId) {
try {
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodId);
PaymentMethodAttachParams params = PaymentMethodAttachParams.builder()
.setCustomer(customerId)
.build();
PaymentMethod attachedMethod = paymentMethod.attach(params);
log.info("Payment method {} attached to customer {}", paymentMethodId, customerId);
return attachedMethod;
} catch (StripeException e) {
log.error("Failed to attach payment method to customer", e);
throw new RuntimeException("Payment method attachment failed: " + e.getMessage(), e);
}
}
/**
* Detach payment method from customer
*/
public PaymentMethod detachPaymentMethod(String paymentMethodId) {
try {
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodId);
PaymentMethod detachedMethod = paymentMethod.detach();
log.info("Payment method detached: {}", paymentMethodId);
return detachedMethod;
} catch (StripeException e) {
log.error("Failed to detach payment method: {}", paymentMethodId, e);
throw new RuntimeException("Payment method detachment failed: " + e.getMessage(), e);
}
}
/**
* List customer's payment methods
*/
public List<PaymentMethod> listCustomerPaymentMethods(String customerId, String type) {
try {
PaymentMethodListParams params = PaymentMethodListParams.builder()
.setCustomer(customerId)
.setType(PaymentMethodListParams.Type.CARD)
.build();
PaymentMethodCollection paymentMethods = PaymentMethod.list(params);
return paymentMethods.getData();
} catch (StripeException e) {
log.error("Failed to list payment methods for customer: {}", customerId, e);
throw new RuntimeException("Payment method listing failed: " + e.getMessage(), e);
}
}
// Helper methods
private long convertToStripeAmount(BigDecimal amount) {
return amount.multiply(BigDecimal.valueOf(100)).longValue();
}
private BigDecimal convertFromStripeAmount(long stripeAmount) {
return BigDecimal.valueOf(stripeAmount).divide(BigDecimal.valueOf(100));
}
private RefundCreateParams.Reason convertRefundReason(RefundRequest.RefundReason reason) {
switch (reason) {
case DUPLICATE:
return RefundCreateParams.Reason.DUPLICATE;
case FRAUDULENT:
return RefundCreateParams.Reason.FRAUDULENT;
case REQUESTED_BY_CUSTOMER:
return RefundCreateParams.Reason.REQUESTED_BY_CUSTOMER;
default:
return RefundCreateParams.Reason.REQUESTED_BY_CUSTOMER;
}
}
// Request DTOs
@Data
public static class PaymentRequest {
private BigDecimal amount;
private String currency = "usd";
private String customerId;
private String description;
private String receiptEmail;
private String orderId;
private String userId;
private Map<String, String> metadata = new HashMap<>();
}
@Data
public static class RefundRequest {
private String paymentIntentId;
private BigDecimal amount;
private RefundReason reason;
private Map<String, String> metadata = new HashMap<>();
public enum RefundReason {
DUPLICATE, FRAUDULENT, REQUESTED_BY_CUSTOMER
}
}
@Data
public static class PaymentListRequest {
private Integer limit = 10;
private String customerId;
private String status; // requires_payment_method, requires_confirmation, requires_action, processing, requires_capture, canceled, succeeded
}
@Data
public static class SetupIntentRequest {
private String customerId;
private String description;
private String userId;
}
@Data
public static class PaymentMethodRequest {
// Card details
private String cardNumber;
private Long expMonth;
private Long expYear;
private String cvc;
private String cardholderName;
// Billing details
private String email;
private String phone;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String postalCode;
private String country;
}
}

Step 4: Customer Management Service

Customer Service

// src/main/java/com/company/stripe/service/CustomerService.java
package com.company.stripe.service;
import com.stripe.exception.StripeException;
import com.stripe.model.Customer;
import com.stripe.model.PaymentMethod;
import com.stripe.model.PaymentMethodCollection;
import com.stripe.param.CustomerCreateParams;
import com.stripe.param.CustomerListParams;
import com.stripe.param.CustomerUpdateParams;
import com.stripe.param.PaymentMethodListParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class CustomerService {
/**
* Create a new customer in Stripe
*/
public Customer createCustomer(CustomerCreateRequest request) {
try {
CustomerCreateParams.Builder paramsBuilder = CustomerCreateParams.builder()
.setEmail(request.getEmail())
.setName(request.getName())
.setPhone(request.getPhone())
.setDescription(request.getDescription());
// Add address if provided
if (request.getAddress() != null) {
CustomerCreateParams.Address address = CustomerCreateParams.Address.builder()
.setLine1(request.getAddress().getLine1())
.setLine2(request.getAddress().getLine2())
.setCity(request.getAddress().getCity())
.setState(request.getAddress().getState())
.setPostalCode(request.getAddress().getPostalCode())
.setCountry(request.getAddress().getCountry())
.build();
paramsBuilder.setAddress(address);
}
// Add metadata
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
Customer customer = Customer.create(paramsBuilder.build());
log.info("Customer created: {} - {}", customer.getId(), customer.getEmail());
return customer;
} catch (StripeException e) {
log.error("Failed to create customer: {}", request.getEmail(), e);
throw new RuntimeException("Customer creation failed: " + e.getMessage(), e);
}
}
/**
* Retrieve customer by ID
*/
public Customer getCustomer(String customerId) {
try {
Customer customer = Customer.retrieve(customerId);
log.debug("Retrieved customer: {}", customerId);
return customer;
} catch (StripeException e) {
log.error("Failed to retrieve customer: {}", customerId, e);
throw new RuntimeException("Customer retrieval failed: " + e.getMessage(), e);
}
}
/**
* Update customer information
*/
public Customer updateCustomer(String customerId, CustomerUpdateRequest request) {
try {
CustomerUpdateParams.Builder paramsBuilder = CustomerUpdateParams.builder();
if (request.getEmail() != null) {
paramsBuilder.setEmail(request.getEmail());
}
if (request.getName() != null) {
paramsBuilder.setName(request.getName());
}
if (request.getPhone() != null) {
paramsBuilder.setPhone(request.getPhone());
}
if (request.getDescription() != null) {
paramsBuilder.setDescription(request.getDescription());
}
// Update address if provided
if (request.getAddress() != null) {
CustomerUpdateParams.Address address = CustomerUpdateParams.Address.builder()
.setLine1(request.getAddress().getLine1())
.setLine2(request.getAddress().getLine2())
.setCity(request.getAddress().getCity())
.setState(request.getAddress().getState())
.setPostalCode(request.getAddress().getPostalCode())
.setCountry(request.getAddress().getCountry())
.build();
paramsBuilder.setAddress(address);
}
// Update metadata
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
Customer customer = Customer.retrieve(customerId);
Customer updatedCustomer = customer.update(paramsBuilder.build());
log.info("Customer updated: {}", customerId);
return updatedCustomer;
} catch (StripeException e) {
log.error("Failed to update customer: {}", customerId, e);
throw new RuntimeException("Customer update failed: " + e.getMessage(), e);
}
}
/**
* Delete a customer
*/
public Customer deleteCustomer(String customerId) {
try {
Customer customer = Customer.retrieve(customerId);
Customer deletedCustomer = customer.delete();
log.info("Customer deleted: {}", customerId);
return deletedCustomer;
} catch (StripeException e) {
log.error("Failed to delete customer: {}", customerId, e);
throw new RuntimeException("Customer deletion failed: " + e.getMessage(), e);
}
}
/**
* List customers with optional filtering
*/
public List<Customer> listCustomers(CustomerListRequest request) {
try {
CustomerListParams.Builder paramsBuilder = CustomerListParams.builder()
.setLimit(request.getLimit());
if (request.getEmail() != null) {
paramsBuilder.setEmail(request.getEmail());
}
return Customer.list(paramsBuilder.build()).getData();
} catch (StripeException e) {
log.error("Failed to list customers", e);
throw new RuntimeException("Customer listing failed: " + e.getMessage(), e);
}
}
/**
* Set customer's default payment method
*/
public Customer setDefaultPaymentMethod(String customerId, String paymentMethodId) {
try {
CustomerUpdateParams params = CustomerUpdateParams.builder()
.setInvoiceSettings(
CustomerUpdateParams.InvoiceSettings.builder()
.setDefaultPaymentMethod(paymentMethodId)
.build()
)
.build();
Customer customer = Customer.retrieve(customerId);
Customer updatedCustomer = customer.update(params);
log.info("Default payment method set for customer: {}", customerId);
return updatedCustomer;
} catch (StripeException e) {
log.error("Failed to set default payment method for customer: {}", customerId, e);
throw new RuntimeException("Default payment method setting failed: " + e.getMessage(), e);
}
}
/**
* Get customer's payment methods
*/
public List<PaymentMethod> getCustomerPaymentMethods(String customerId, String type) {
try {
PaymentMethodListParams params = PaymentMethodListParams.builder()
.setCustomer(customerId)
.setType(PaymentMethodListParams.Type.valueOf(type.toUpperCase()))
.build();
PaymentMethodCollection paymentMethods = PaymentMethod.list(params);
return paymentMethods.getData();
} catch (StripeException e) {
log.error("Failed to get payment methods for customer: {}", customerId, e);
throw new RuntimeException("Payment method retrieval failed: " + e.getMessage(), e);
}
}
// Request DTOs
@Data
public static class CustomerCreateRequest {
private String email;
private String name;
private String phone;
private String description;
private Address address;
private Map<String, String> metadata = new HashMap<>();
@Data
public static class Address {
private String line1;
private String line2;
private String city;
private String state;
private String postalCode;
private String country;
}
}
@Data
public static class CustomerUpdateRequest {
private String email;
private String name;
private String phone;
private String description;
private CustomerCreateRequest.Address address;
private Map<String, String> metadata = new HashMap<>();
}
@Data
public static class CustomerListRequest {
private Integer limit = 10;
private String email;
}
}

Step 5: Subscription Service

Subscription Management

// src/main/java/com/company/stripe/service/SubscriptionService.java
package com.company.stripe.service;
import com.stripe.exception.StripeException;
import com.stripe.model.*;
import com.stripe.param.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
@Service
@Slf4j
public class SubscriptionService {
private final PriceService priceService;
public SubscriptionService(PriceService priceService) {
this.priceService = priceService;
}
/**
* Create a subscription for a customer
*/
public Subscription createSubscription(SubscriptionRequest request) {
try {
// Build subscription items
List<SubscriptionCreateParams.Item> items = new ArrayList<>();
for (SubscriptionItemRequest item : request.getItems()) {
SubscriptionCreateParams.Item subscriptionItem = SubscriptionCreateParams.Item.builder()
.setPrice(item.getPriceId())
.setQuantity(item.getQuantity())
.build();
items.add(subscriptionItem);
}
SubscriptionCreateParams.Builder paramsBuilder = SubscriptionCreateParams.builder()
.setCustomer(request.getCustomerId())
.addAllItem(items)
.setPaymentBehavior(SubscriptionCreateParams.PaymentBehavior.DEFAULT_INCOMPLETE)
.setPaymentSettings(
SubscriptionCreateParams.PaymentSettings.builder()
.setSaveDefaultPaymentMethod(SubscriptionCreateParams.PaymentSettings.SaveDefaultPaymentMethod.ON_SUBSCRIPTION)
.build()
)
.setExpand(Arrays.asList("latest_invoice.payment_intent"));
// Set trial period if provided
if (request.getTrialPeriodDays() != null) {
paramsBuilder.setTrialPeriodDays(request.getTrialPeriodDays());
}
// Set metadata
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
Subscription subscription = Subscription.create(paramsBuilder.build());
log.info("Subscription created: {} for customer {}", subscription.getId(), request.getCustomerId());
return subscription;
} catch (StripeException e) {
log.error("Failed to create subscription for customer: {}", request.getCustomerId(), e);
throw new RuntimeException("Subscription creation failed: " + e.getMessage(), e);
}
}
/**
* Retrieve subscription by ID
*/
public Subscription getSubscription(String subscriptionId) {
try {
Subscription subscription = Subscription.retrieve(subscriptionId);
log.debug("Retrieved subscription: {}", subscriptionId);
return subscription;
} catch (StripeException e) {
log.error("Failed to retrieve subscription: {}", subscriptionId, e);
throw new RuntimeException("Subscription retrieval failed: " + e.getMessage(), e);
}
}
/**
* Update subscription
*/
public Subscription updateSubscription(String subscriptionId, SubscriptionUpdateRequest request) {
try {
SubscriptionUpdateParams.Builder paramsBuilder = SubscriptionUpdateParams.builder();
// Update items if provided
if (request.getItems() != null && !request.getItems().isEmpty()) {
List<SubscriptionUpdateParams.Item> items = new ArrayList<>();
for (SubscriptionItemRequest item : request.getItems()) {
SubscriptionUpdateParams.Item subscriptionItem = SubscriptionUpdateParams.Item.builder()
.setId(item.getItemId()) // Existing item ID for updates
.setPrice(item.getPriceId())
.setQuantity(item.getQuantity())
.build();
items.add(subscriptionItem);
}
paramsBuilder.addAllItem(items);
}
// Update metadata
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
// Proration behavior
if (request.isProrate()) {
paramsBuilder.setProrationBehavior(SubscriptionUpdateParams.ProrationBehavior.CREATE_PRORATIONS);
}
Subscription subscription = Subscription.retrieve(subscriptionId);
Subscription updatedSubscription = subscription.update(paramsBuilder.build());
log.info("Subscription updated: {}", subscriptionId);
return updatedSubscription;
} catch (StripeException e) {
log.error("Failed to update subscription: {}", subscriptionId, e);
throw new RuntimeException("Subscription update failed: " + e.getMessage(), e);
}
}
/**
* Cancel subscription
*/
public Subscription cancelSubscription(String subscriptionId, CancelSubscriptionRequest request) {
try {
SubscriptionCancelParams.Builder paramsBuilder = SubscriptionCancelParams.builder();
if (request.isCancelAtPeriodEnd()) {
paramsBuilder.setCancelAtPeriodEnd(true);
}
Subscription subscription = Subscription.retrieve(subscriptionId);
Subscription canceledSubscription;
if (request.isCancelAtPeriodEnd()) {
canceledSubscription = subscription.update(
SubscriptionUpdateParams.builder()
.setCancelAtPeriodEnd(true)
.build()
);
} else {
canceledSubscription = subscription.cancel(paramsBuilder.build());
}
log.info("Subscription canceled: {}", subscriptionId);
return canceledSubscription;
} catch (StripeException e) {
log.error("Failed to cancel subscription: {}", subscriptionId, e);
throw new RuntimeException("Subscription cancellation failed: " + e.getMessage(), e);
}
}
/**
* Resume subscription
*/
public Subscription resumeSubscription(String subscriptionId) {
try {
SubscriptionUpdateParams params = SubscriptionUpdateParams.builder()
.setCancelAtPeriodEnd(false)
.build();
Subscription subscription = Subscription.retrieve(subscriptionId);
Subscription resumedSubscription = subscription.update(params);
log.info("Subscription resumed: {}", subscriptionId);
return resumedSubscription;
} catch (StripeException e) {
log.error("Failed to resume subscription: {}", subscriptionId, e);
throw new RuntimeException("Subscription resumption failed: " + e.getMessage(), e);
}
}
/**
* List customer's subscriptions
*/
public List<Subscription> listCustomerSubscriptions(String customerId, SubscriptionListRequest request) {
try {
SubscriptionListParams.Builder paramsBuilder = SubscriptionListParams.builder()
.setCustomer(customerId)
.setLimit(request.getLimit());
if (request.getStatus() != null) {
paramsBuilder.addStatus(SubscriptionListParams.Status.valueOf(request.getStatus().toUpperCase()));
}
SubscriptionCollection subscriptions = Subscription.list(paramsBuilder.build());
return subscriptions.getData();
} catch (StripeException e) {
log.error("Failed to list subscriptions for customer: {}", customerId, e);
throw new RuntimeException("Subscription listing failed: " + e.getMessage(), e);
}
}
/**
* Create invoice for subscription
*/
public Invoice createInvoice(String subscriptionId) {
try {
InvoiceCreateParams params = InvoiceCreateParams.builder()
.setSubscription(subscriptionId)
.build();
Invoice invoice = Invoice.create(params);
log.info("Invoice created: {} for subscription {}", invoice.getId(), subscriptionId);
return invoice;
} catch (StripeException e) {
log.error("Failed to create invoice for subscription: {}", subscriptionId, e);
throw new RuntimeException("Invoice creation failed: " + e.getMessage(), e);
}
}
/**
* Pay invoice immediately
*/
public Invoice payInvoice(String invoiceId) {
try {
Invoice invoice = Invoice.retrieve(invoiceId);
Invoice paidInvoice = invoice.pay();
log.info("Invoice paid: {}", invoiceId);
return paidInvoice;
} catch (StripeException e) {
log.error("Failed to pay invoice: {}", invoiceId, e);
throw new RuntimeException("Invoice payment failed: " + e.getMessage(), e);
}
}
// Request DTOs
@Data
public static class SubscriptionRequest {
private String customerId;
private List<SubscriptionItemRequest> items = new ArrayList<>();
private Integer trialPeriodDays;
private Map<String, String> metadata = new HashMap<>();
}
@Data
public static class SubscriptionItemRequest {
private String itemId; // For updates
private String priceId;
private Long quantity = 1L;
}
@Data
public static class SubscriptionUpdateRequest {
private List<SubscriptionItemRequest> items;
private Map<String, String> metadata = new HashMap<>();
private boolean prorate = true;
}
@Data
public static class CancelSubscriptionRequest {
private boolean cancelAtPeriodEnd = false;
}
@Data
public static class SubscriptionListRequest {
private Integer limit = 10;
private String status; // active, past_due, unpaid, canceled, incomplete, incomplete_expired, trialing, all
}
}

Step 6: Price and Product Service

Price Service

```java
// src/main/java/com/company/stripe/service/PriceService.java
package com.company.stripe.service;

import com.stripe.exception.StripeException;
import com.stripe.model.Price;
import com.stripe.model.Product;
import com.stripe.param.PriceCreateParams;
import com.stripe.param.PriceListParams;
import com.stripe.param.ProductCreateParams;
import com.stripe.param.ProductListParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class PriceService {

/**
* Create a product
*/
public Product createProduct(ProductRequest request) {
try {
ProductCreateParams.Builder paramsBuilder = ProductCreateParams.builder()
.setName(request.getName())
.setDescription(request.getDescription())
.setActive(true);
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
Product product = Product.create(paramsBuilder.build());
log.info("Product created: {} - {}", product.getId(), product.getName());
return product;
} catch (StripeException e) {
log.error("Failed to create product: {}", request.getName(), e);
throw new RuntimeException("Product creation failed: " + e.getMessage(), e);
}
}
/**
* Create a price for a product
*/
public Price createPrice(PriceRequest request) {
try {
PriceCreateParams.Builder paramsBuilder = PriceCreateParams.builder()
.setProduct(request.getProductId())
.setCurrency(request.getCurrency().toLowerCase())
.setUnitAmount(convertToStripeAmount(request.getUnitAmount()));
// Set recurring if subscription
if (request.isRecurring()) {
PriceCreateParams.Recurring recurring = PriceCreateParams.Recurring.builder()
.setInterval(PriceCreateParams.Recurring.Interval.valueOf(
request.getInterval().toUpperCase()))
.build();
paramsBuilder.setRecurring(recurring);
}
if (request.getMetadata() != null) {
paramsBuilder.putAllMetadata(request.getMetadata());
}
Price price = Price.create(paramsBuilder.build());
log.info("Price created: {} for product {}", price.getId(), request.getProductId());
return price;
} catch (StripeException e) {
log.error("Failed to create price for product: {}", request.getProductId(), e);
throw new RuntimeException("Price creation failed: " + e.getMessage(), e);
}
}
/**
* List all active products
*/
public List<Product> listProducts(ProductListRequest request) {
try {
ProductListParams.Builder paramsBuilder = ProductListParams.builder()
.setActive(true)
.setLimit(request.getLimit());
return Product.list(paramsBuilder.build()).getData();
} catch (StripeException e) {
log.error("Failed to list products", e);
throw new RuntimeException("Product

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper