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
typescript
import { registerLocaleData } from '@angular/common'; import localeFr from '@angular/common/locales/fr'; import localeFrExtra from '@angular/common/locales/extra/fr'; import localeDe from '@angular/common/locales/de';
Locale-aware bootstrapping in Angular
i18n
localization
dependency-injection
Intermediate
8 steps
rust
use serde::Deserialize; #[derive(Debug, Deserialize)] #[serde(untagged)]
Parsing flexible JSON shapes with serde
deserialization
enums
json
Intermediate
6 steps
ruby
require "shellwords" require "open3" module Backup
Building safe shell commands in Ruby
shell-out
subprocess
command-injection
Intermediate
7 steps
typescript
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import * as Joi from 'joi';
Validating env config at boot in NestJS
configuration
schema-validation
environment-variables
Intermediate
8 steps
java
@Component @Converter public class EncryptedStringConverter implements AttributeConverter<String, String> {
Transparent column encryption in Spring & JPA
encryption
aes-gcm
jpa-converter
Advanced
10 steps
typescript
import { Inject, Injectable, Logger } from '@nestjs/common'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { Cache } from 'cache-manager'; import { InjectRepository } from '@nestjs/typeorm';
A cache-aside country lookup in NestJS
cache-aside
dependency-injection
batch-lookup
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.