Payment Processor

Payment Processor example using Strategy Pattern

Flexibility and extensibility are often key objectives when designing systems that handle varied business requirements. Payment processing system often requires the ability to support multiple payment types while accommodating future additions or modifications with ease.

Strategy pattern: Encapsulate various payment processing algorithms (such as Cash processing, Local Transfer processing, etc.) into separate classes (strategies) that implement a common interface (PaymentProcessor). This allows the system to dynamically select and execute the appropriate algorithm based on the transaction type, promoting flexibility and maintainability in the payment processing logic.

Let's start by creating an enum with supported payment types.

PaymentType.java

@Getter
public enum PaymentType {
    ACCOUNT_TO_ACCOUNT(Constant.ACCOUNT_TO_ACCOUNT),
    ACCOUNT_TO_WALLET(Constant.ACCOUNT_TO_WALLET),
    WALLET_TO_WALLET(Constant.WALLET_TO_WALLET),
    LOCAL_TRANSFER(Constant.LOCAL_TRANSFER),
    INTERNATIONAL_TRANSFER(Constant.INTERNATIONAL_TRANSFER),
    CASH(Constant.CASH),
    INTERNAL_TRANSFER(Constant.INTERNAL_TRANSFER);

    private final String value;
    
    private PaymentType(String type) {
        this.value = type;
    }
    
    public class Constant {
        public static final String ACCOUNT_TO_ACCOUNT = "ACCOUNT_TO_ACCOUNT";
        public static final String ACCOUNT_TO_WALLET = "ACCOUNT_TO_WALLET";
        public static final String WALLET_TO_WALLET = "WALLET_TO_WALLET";
        public static final String LOCAL_TRANSFER = "LOCAL_TRANSFER";
        public static final String INTERNATIONAL_TRANSFER = "INTERNATIONAL_TRANSFER";
        public static final String CASH = "CASH";
        public static final String INTERNAL_TRANSFER = "INTERNAL_TRANSFER";
    }
}

Now, create an interface.

PaymentProcessor.java

Create different payment processors.

  • For e.g. Cash payment processor

CashProcessor.java

  • For e.g. Internal payment processor

InternalTransferProcessor.java

  • And others

Now, in the service class, inject all the processor implementation and fetch and trigger appropriate processor logic based on Transaction/Payment Type.

We can create Controller class and define the sample endpoint.

PaymentApi.java

Run the application and call the endpoint.

Log Output

Last updated