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