Backend Development 8 min read

Implementing Automatic Order Cancellation After 30 Minutes in Spring Boot

This article explains three Spring Boot approaches—using @Scheduled tasks, RabbitMQ delayed queues, and Redis key‑expiration events—to automatically cancel orders that remain unpaid for 30 minutes, complete with code samples and configuration guidance.

Top Architect
Top Architect
Top Architect
Implementing Automatic Order Cancellation After 30 Minutes in Spring Boot

Introduction

In e‑commerce and other online‑payment applications, it is common to automatically cancel an order if the user does not complete payment within a certain time window.

Solution 1: Scheduled Task

Leverage Spring Boot's @Scheduled annotation to run a periodic job that scans the database for unpaid orders older than 30 minutes and cancels them.

@Component
public class OrderCancelSchedule {
    @Autowired
    private OrderService orderService;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void cancelUnpaidOrders() {
        List<Order> unpaidOrders = orderService.getUnpaidOrders();
        unpaidOrders.forEach(order -> {
            if (order.getCreationTime().plusMinutes(30).isBefore(LocalDateTime.now())) {
                orderService.cancelOrder(order.getId());
            }
        });
    }
}

Solution 2: Delayed Queue

Use a message broker such as RabbitMQ with delayed‑queue support. When an order is created, push its ID to a delayed queue set to expire after 30 minutes; the consumer processes the message and cancels the order.

@Service
public class OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void createOrder(Order order) {
        // save order to DB
        saveOrderToDB(order);
        // push order ID to delayed queue
        rabbitTemplate.convertAndSend("orderDelayExchange", "orderDelayKey", order.getId(), message -> {
            message.getMessageProperties().setDelay(30 * 60 * 1000); // 30 minutes
            return message;
        });
    }
}

@Component
@RabbitListener(queues = "orderDelayQueue")
public class OrderDelayConsumer {
    @Autowired
    private OrderService orderService;

    @RabbitHandler
    public void process(String orderId) {
        // cancel order
        orderService.cancelOrder(orderId);
    }
}

Solution 3: Redis Expiration Event

Store a temporary key in Redis when the order is created, set to expire after 30 minutes. Configure Redis key‑space notifications and a listener to handle the expiration event and cancel the order.

@Service
public class OrderService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    public void createOrder(Order order) {
        // save order to DB
        saveOrderToDB(order);
        // store a key with 30‑minute TTL
        redisTemplate.opsForValue().set("order:" + order.getId(), order.getId(), 30, TimeUnit.MINUTES);
    }

    // Called when the Redis key expires (requires notification config)
    public void onOrderKeyExpired(String orderId) {
        cancelOrder(orderId);
    }
}

To enable Redis key‑space notifications, add notify-keyspace-events "Ex" to redis.conf and configure a RedisMessageListenerContainer in Spring Boot to listen for __keyevent@*__:expired events.

Conclusion

All three solutions achieve the requirement of automatically canceling unpaid orders after 30 minutes. Choose the most suitable implementation based on business needs, system load, and operational considerations, as each approach has its own trade‑offs.

backendRedisSpring BootRabbitMQScheduled TaskOrder Cancellation
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.