java
41 lines · 7 steps
Configuring a Stripe RestClient in Spring
A Spring @Configuration bean assembles a pre-wired RestClient for the Stripe API with timeouts, auth headers, and error handling.
Explained by
highlit
1package com.example.payments.config;
2
3import org.springframework.beans.factory.annotation.Value;
4import org.springframework.context.annotation.Bean;
5import org.springframework.context.annotation.Configuration;
6import org.springframework.http.HttpHeaders;
7import org.springframework.http.MediaType;
8import org.springframework.http.client.SimpleClientHttpRequestFactory;
9import org.springframework.web.client.RestClient;
10
11import java.time.Duration;
12
13@Configuration
14public class StripeClientConfig {
15
16 @Bean
17 RestClient stripeRestClient(
18 RestClient.Builder builder,
19 @Value("${stripe.base-url}") String baseUrl,
20 @Value("${stripe.secret-key}") String secretKey) {
21
22 var requestFactory = new SimpleClientHttpRequestFactory();
23 requestFactory.setConnectTimeout(Duration.ofSeconds(5));
24 requestFactory.setReadTimeout(Duration.ofSeconds(15));
25
26 return builder
27 .baseUrl(baseUrl)
28 .requestFactory(requestFactory)
29 .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + secretKey)
30 .defaultHeader("Stripe-Version", "2024-06-20")
31 .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
32 .defaultStatusHandler(
33 status -> status.is4xxClientError() || status.is5xxServerError(),
34 (request, response) -> {
35 throw new StripeApiException(
36 response.getStatusCode(),
37 new String(response.getBody().readAllBytes()));
38 })
39 .build();
40 }
41}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Centralizing an HTTP client's defaults in one bean keeps auth and versioning consistent across every call site.
- 2Injecting secrets and URLs via @Value keeps environment-specific config out of the code.
- 3A default status handler turns HTTP error responses into typed exceptions so callers fail loudly.
Related explainers
ruby
class Order class InvalidTransition < StandardError; end TRANSITIONS = {
A state machine for order transitions in Ruby
state-machine
data-driven
error-handling
Intermediate
8 steps
java
public class SlidingLogRateLimiter { private final int maxRequests; private final long windowMillis;
How a sliding-log rate limiter works
rate-limiting
concurrency
sliding-window
Advanced
8 steps
typescript
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { ConfigService } from '@nestjs/config';
How a JWT strategy authenticates in NestJS
authentication
jwt
passport
Intermediate
7 steps
java
public final class Slugifier { private static final Pattern NON_LATIN = Pattern.compile("[^\\w-]"); private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
Building a URL slugifier in Java
regex
unicode-normalization
string-processing
Intermediate
8 steps
rust
use std::cmp::Ordering; use std::str::FromStr; #[derive(Debug, Clone, PartialEq, Eq)]
Parsing and ordering semantic versions in Rust
parsing
trait-implementation
ordering
Intermediate
8 steps
javascript
'use client'; import { useEffect } from 'react'; import * as Sentry from '@sentry/nextjs';
How a Next.js error boundary recovers
error-boundary
error-handling
observability
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/configuring-a-stripe-restclient-in-spring-explained-java-dfce/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.