Simplify Multi-Payment Integration in Java with the Strategy Pattern

This article explains how to replace cumbersome if/else payment handling code with a clean Strategy pattern implementation in Java, showing both the problem scenario and a complete example including enums, interfaces, and concrete payment classes for Alipay and WeChat Pay.

Programmer DD
Programmer DD
Programmer DD
Simplify Multi-Payment Integration in Java with the Strategy Pattern

Payment Case

When developing an application, you often need to support multiple payment methods such as Alipay, WeChat Pay, and bank card payments. Each method has a different API and parameters, leading developers to write long chains of if/else statements that become hard to maintain as business logic grows.

The Strategy pattern treats each payment method as a separate strategy, similar to choosing a travel method from Guangzhou to Beijing. Regardless of the chosen strategy, the final result—successful payment—remains the same.

1. Conventional Code (if/else)

Typical code mixes many parameters and business logic, resulting in hundreds of lines for a single payment method and making the codebase difficult to extend.

@PostMapping("/makeOrder")
public ResultData makeOrder(@RequestBody Order order){
    // generate order and set expiration, schedule rollback
    // ... omitted
    // handle payment method
    if(order.getType=="alipay"){ // Alipay
        this.payService.alipay(order);
    }else if(order.getType=="weixin"){ // WeChat
        this.payService.weixinpay(order);
    }else if(order.getType=="jd"){ // JD Pay
        this.payService.jtpay(order);
    }else if(order.getType=="yunshanfu"){ // UnionPay
        this.payService.yunshanfupay(order);
    }
    // send to MQ for broadcasting
    return this.ok(order);
}

Such code quickly becomes messy and hard to maintain when more payment channels are added.

2. Introducing the Strategy Pattern

By defining a common payment interface and using an enum to select the appropriate strategy, the code becomes more modular and extensible.

private OrderService orderService;

@PostMapping("/makeOrder")
// product id, payment type
public ResultData makeOrder(Long goodsId, String type){
    // generate local order
    Order order = this.orderService.makeOrder(goodsId);
    // select payment strategy
    PayType payType = PayType.getByCode(type);
    // execute payment
    payType.get().pay(order.getId(), order.getAmount());
    return this.ok();
}

The PayType enum holds the mapping between a code and a concrete Payment implementation:

public enum PayType {
    // Alipay implementation
    ALI_PAY("1", new AliPay()),
    // WeChat implementation
    WECHAT_PAY("2", new WechatPay());

    private String payType;
    private Payment payment;
    PayType(String payType, Payment payment){
        this.payment = payment;
        this.payType = payType;
    }
    public Payment get(){ return this.payment; }
    public static PayType getByCode(String payType){
        for(PayType e : PayType.values()){
            if(e.payType.equals(payType)){
                return e;
            }
        }
        return null;
    }
}

The common Payment interface defines a single method:

public interface Payment {
    void pay(Long order, double amount);
}

Concrete implementations provide the actual payment logic:

public class AliPay implements Payment {
    @Override
    public void pay(Long order, double amount){
        System.out.println("----支付宝支付----");
        System.out.println("支付宝支付111元");
    }
}
public class WechatPay implements Payment {
    @Override
    public void pay(Long orderId, double amount){
        System.out.println("---微信支付---");
        System.out.println("支付222元");
    }
}

Using the Strategy pattern reduces duplicated if/else logic, makes the codebase easier to extend with new payment methods, and aligns with object‑oriented principles. However, for very simple scenarios the additional classes may seem excessive; the pattern shines when payment logic becomes complex and needs frequent extension.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendDesign PatternsJavaStrategy PatternPayment Integration
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

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.