PaymentGatewayConfig.java
package com.rbctcsworld.ecommerce.payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import java.time.Duration;
import java.util.Arrays;
/**
* app.payment.provider = mock (default) | stripe. Fails the start for a typo, a missing key, or a LIVE
* Stripe key outside the 'prod' profile (a test run must never be able to move real money).
*/
@Configuration
class PaymentGatewayConfig {
@Bean
PaymentGateway paymentGateway(@Value("${app.payment.provider:mock}") String provider,
@Value("${app.payment.stripe.api-base:https://api.stripe.com}") String apiBase,
@Value("${app.payment.stripe.secret-key:}") String secretKey,
@Value("${app.payment.stripe.currency:usd}") String currency,
@Value("${app.payment.stripe.timeout-seconds:10}") long timeoutSeconds,
Environment env) {
boolean prod = Arrays.asList(env.getActiveProfiles()).contains("prod");
return create(provider, apiBase, secretKey, currency, Duration.ofSeconds(timeoutSeconds), prod);
}
static PaymentGateway create(String provider, String apiBase, String secretKey, String currency,
Duration timeout, boolean prod) {
return switch (provider.trim().toLowerCase()) {
case "mock" -> new MockPaymentGateway();
case "stripe" -> {
if (secretKey == null || !secretKey.startsWith("sk_")) {
throw new IllegalStateException("app.payment.provider=stripe needs STRIPE_SECRET_KEY (sk_test_...)");
}
if (secretKey.startsWith("sk_live_") && !prod) {
throw new IllegalStateException("Refusing a LIVE Stripe key outside the 'prod' profile");
}
yield new StripePaymentGateway(new StripeClient(apiBase, secretKey, timeout), currency);
}
default -> throw new IllegalStateException(
"app.payment.provider must be 'mock' or 'stripe', not '" + provider + "'");
};
}
}