diff --git a/src/main/java/com/ycwl/basic/pay/PayFactory.java b/src/main/java/com/ycwl/basic/pay/PayFactory.java
new file mode 100644
index 0000000..404af4e
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/PayFactory.java
@@ -0,0 +1,58 @@
+package com.ycwl.basic.pay;
+
+import com.ycwl.basic.pay.adapter.IPayAdapter;
+import com.ycwl.basic.pay.adapter.WxMpPayAdapter;
+import com.ycwl.basic.pay.enums.PayAdapterType;
+import com.ycwl.basic.pay.exceptions.PayUndefinedException;
+import com.ycwl.basic.pay.exceptions.PayUnsupportedException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PayFactory {
+
+    public static IPayAdapter getAdapter(String typeName) {
+        PayAdapterType adapterEnum;
+        try {
+            adapterEnum = PayAdapterType.valueOf(typeName);
+        } catch (IllegalArgumentException e) {
+            throw new PayUnsupportedException("不支持的Adapter类型");
+        }
+        return getAdapter(adapterEnum);
+    }
+
+    public static IPayAdapter getAdapter(PayAdapterType type) {
+        switch (type) {
+            case WX_MP_PAY:
+                return new WxMpPayAdapter();
+            default:
+                throw new PayUnsupportedException("不支持的Adapter类型");
+        }
+    }
+
+    protected static Map<String, IPayAdapter> namedAdapter = new HashMap<>();
+    protected static IPayAdapter defaultAdapter = null;
+
+    public static void register(String name, IPayAdapter adapter) {
+        namedAdapter.put(name, adapter);
+    }
+
+    public static IPayAdapter use(String name) {
+        IPayAdapter adapter = namedAdapter.get(name);
+        if (adapter == null) {
+            throw new PayUndefinedException("未定义的支付方式:"+name);
+        }
+        return adapter;
+    }
+
+    public static IPayAdapter use() {
+        if (defaultAdapter == null) {
+            throw new PayUndefinedException("未定义默认的支付方式");
+        }
+        return defaultAdapter;
+    }
+
+    public static void setDefault(String defaultName) {
+        PayFactory.defaultAdapter = use(defaultName);
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/adapter/IPayAdapter.java b/src/main/java/com/ycwl/basic/pay/adapter/IPayAdapter.java
new file mode 100644
index 0000000..ce6758c
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/adapter/IPayAdapter.java
@@ -0,0 +1,42 @@
+package com.ycwl.basic.pay.adapter;
+
+// 假设request对象所在的包,可根据实际情况修改
+import com.ycwl.basic.pay.entity.CancelOrderRequest;
+import com.ycwl.basic.pay.entity.CreateOrderRequest;
+import com.ycwl.basic.pay.entity.CreateOrderResponse;
+import com.ycwl.basic.pay.entity.PayResponse;
+import com.ycwl.basic.pay.entity.RefundResponse;
+import com.ycwl.basic.pay.entity.RefundOrderRequest;
+import com.ycwl.basic.pay.entity.RefundOrderResponse;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.Map;
+
+// 将接口改为抽象类
+public interface IPayAdapter {
+    // 下单方法
+    CreateOrderResponse createOrder(CreateOrderRequest request);
+
+    // 获取支付参数方法
+    Map<String, Object> getPaymentParams(CreateOrderResponse response);
+
+    // 处理回调信息方法
+    PayResponse handleCallback(HttpServletRequest request) throws IOException;
+
+    // 查询订单状态方法
+    PayResponse queryOrder(String orderNo);
+
+    // 退款方法
+    RefundOrderResponse refund(RefundOrderRequest request);
+
+    // 处理退款回调方法
+    RefundResponse handleRefundCallback(HttpServletRequest request) throws IOException;
+
+    // 查询退款订单状态方法
+    RefundResponse checkRefundStatus(String refundNo);
+
+    void loadConfig(Map<String, String> config);
+
+    void cancelOrder(CancelOrderRequest request);
+}
diff --git a/src/main/java/com/ycwl/basic/pay/adapter/WxMpPayAdapter.java b/src/main/java/com/ycwl/basic/pay/adapter/WxMpPayAdapter.java
new file mode 100644
index 0000000..ca57307
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/adapter/WxMpPayAdapter.java
@@ -0,0 +1,353 @@
+package com.ycwl.basic.pay.adapter;
+
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.notification.NotificationConfig;
+import com.wechat.pay.java.core.notification.NotificationParser;
+import com.wechat.pay.java.core.notification.RequestParam;
+import com.wechat.pay.java.core.util.PemUtil;
+import com.wechat.pay.java.service.payments.jsapi.JsapiService;
+import com.wechat.pay.java.service.payments.jsapi.model.Amount;
+import com.wechat.pay.java.service.payments.jsapi.model.CloseOrderRequest;
+import com.wechat.pay.java.service.payments.jsapi.model.Payer;
+import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
+import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
+import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
+import com.wechat.pay.java.service.payments.model.Transaction;
+import com.wechat.pay.java.service.refund.RefundService;
+import com.wechat.pay.java.service.refund.model.AmountReq;
+import com.wechat.pay.java.service.refund.model.CreateRequest;
+import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest;
+import com.wechat.pay.java.service.refund.model.Refund;
+import com.wechat.pay.java.service.refund.model.RefundNotification;
+import com.ycwl.basic.constant.NumberConstant;
+import com.ycwl.basic.pay.entity.CancelOrderRequest;
+import com.ycwl.basic.pay.entity.CreateOrderRequest;
+import com.ycwl.basic.pay.entity.CreateOrderResponse;
+import com.ycwl.basic.pay.entity.PayResponse;
+import com.ycwl.basic.pay.entity.RefundResponse;
+import com.ycwl.basic.pay.entity.RefundOrderRequest;
+import com.ycwl.basic.pay.entity.RefundOrderResponse;
+import com.ycwl.basic.pay.entity.WxMpPayConfig;
+import com.ycwl.basic.pay.exceptions.PayWrongConfigException;
+import org.springframework.util.Base64Utils;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_NONCE;
+import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SERIAL;
+import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SIGNATURE;
+import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_TIMESTAMP;
+import static com.wechat.pay.java.service.refund.model.Status.SUCCESS;
+
+public class WxMpPayAdapter implements IPayAdapter {
+    private WxMpPayConfig config;
+    public static final String WECHAT_PAY_SIGNATURE_TYPE = "Wechatpay-Signature-Type";
+    public WxMpPayAdapter() {
+
+    }
+    public WxMpPayAdapter(WxMpPayConfig config) {
+        this.config = config;
+    }
+    @Override
+    public void loadConfig(Map<String, String> _config) {
+        this.config = new WxMpPayConfig();
+        if (_config != null) {
+            this.config.setMerchantId(_config.get("merchantId"));
+            this.config.setAppId(_config.get("appId"));
+            this.config.setPrivateKey(_config.get("privateKey"));
+            this.config.setSerialNumber(_config.get("serialNumber"));
+            this.config.setApiV3Key(_config.get("apiV3Key"));
+        }
+    }
+
+    private Config clientConfig;
+
+    private Config getConfig() {
+        if (clientConfig == null) {
+            clientConfig = new RSAAutoCertificateConfig.Builder()
+                    .merchantId(config.getMerchantId())
+                    .privateKey(config.getPrivateKey())
+                    .merchantSerialNumber(config.getSerialNumber())
+                    .apiV3Key(config.getApiV3Key())
+                    .build();
+        }
+        return clientConfig;
+    }
+
+    @Override
+    public CreateOrderResponse createOrder(CreateOrderRequest request) {
+        CreateOrderResponse resp = new CreateOrderResponse();
+        if (request.getPrice() <= 0) {
+            resp.setSkipPay(true);
+            return resp;
+        }
+        Config wxConfig = getConfig();
+        JsapiService service = new JsapiService.Builder().config(wxConfig).build();
+        PrepayRequest prepayRequest = new PrepayRequest();
+        Amount amount = new Amount();
+        amount.setTotal(request.getPrice());
+        prepayRequest.setAmount(amount);
+        prepayRequest.setAppid(config.getAppId());
+        prepayRequest.setMchid(config.getMerchantId());
+        prepayRequest.setDescription(request.getDescription());
+        prepayRequest.setNotifyUrl(request.getNotifyUrl());
+        prepayRequest.setOutTradeNo(request.getOrderNo());
+        Payer payer = new Payer();
+        payer.setOpenid(request.getUserIdentify());
+        prepayRequest.setPayer(payer);
+        PrepayResponse response = service.prepay(prepayRequest);
+        resp.setSuccess(true);
+        resp.setSkipPay(false);
+        resp.setOrderNo(response.getPrepayId());
+        return resp;
+    }
+
+    @Override
+    public Map<String, Object> getPaymentParams(CreateOrderResponse response) {
+        Map<String, Object> params = new HashMap<>();
+        if (response.isSkipPay()) {
+            return params;
+        }
+        Long timeStamp = System.currentTimeMillis() / NumberConstant.THOUSAND;
+        params.put("appId", config.getAppId());
+        params.put("timeStamp", timeStamp);
+        String nonce = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+        params.put("nonceStr", nonce);
+        String signStr = Stream.of(config.getAppId(), String.valueOf(timeStamp), nonce, "prepay_id=" + response.getOrderNo())
+                .collect(Collectors.joining("\n", "", "\n"));
+        String sign;
+        try {
+            sign = getSign(signStr, config.getPrivateKey());
+        } catch (InvalidKeyException | SignatureException | NoSuchAlgorithmException e) {
+            throw new PayWrongConfigException("配置错误");
+        }
+        params.put("paySign", sign);
+        params.put("signType", "RSA-SHA256");
+        params.put("prepayId", "prepay_id=" + response.getOrderNo());
+        return params;
+    }
+
+    @Override
+    public PayResponse handleCallback(HttpServletRequest request) throws IOException {
+        ServletInputStream inputStream = request.getInputStream();
+        StringBuffer body = new StringBuffer();
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+        String s;
+        // 读取回调请求体
+        while ((s = bufferedReader.readLine()) != null) {
+            body.append(s);
+        }
+        PayResponse resp = new PayResponse();
+
+        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
+        String nonce = request.getHeader(WECHAT_PAY_NONCE);
+        String signType = request.getHeader(WECHAT_PAY_SIGNATURE_TYPE);
+        String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
+        String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
+        NotificationConfig config = (NotificationConfig) getConfig();
+        NotificationParser parser = new NotificationParser(config);
+        RequestParam requestParam = new RequestParam.Builder()
+                .serialNumber(serialNo)
+                .nonce(nonce)
+                .signature(signature)
+                .timestamp(timestamp)
+                // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
+                .signType(signType)
+                .body(body.toString())
+                .build();
+        Transaction parse = parser.parse(requestParam, Transaction.class);
+        resp.setValid(true);
+        resp.setOrderNo(parse.getOutTradeNo());
+        if (parse.getAmount() != null) {
+            resp.setOrderPrice(parse.getAmount().getTotal());
+            resp.setPayPrice(parse.getAmount().getPayerTotal());
+        }
+        switch (parse.getTradeState()) {
+            case SUCCESS:
+                resp.setState(PayResponse.PAY_STATE.SUCCESS);
+                break;
+            case NOTPAY:
+            case CLOSED:
+            case REVOKED:
+                resp.setState(PayResponse.PAY_STATE.FAIL);
+                break;
+            case REFUND:
+                resp.setState(PayResponse.PAY_STATE.REFUND);
+                break;
+            default:
+                resp.setState(PayResponse.PAY_STATE.CANCEL);
+                break;
+        }
+        resp.setPayTime(parse.getSuccessTime());
+        resp.setOriginalResponse(parse);
+        return resp;
+    }
+
+    @Override
+    public PayResponse queryOrder(String orderNo) {
+        Config wxConfig = getConfig();
+        JsapiService service = new JsapiService.Builder().config(wxConfig).build();
+        QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
+        queryRequest.setMchid(config.getMerchantId());
+        queryRequest.setOutTradeNo(orderNo);
+        PayResponse resp = new PayResponse();
+        Transaction result = service.queryOrderByOutTradeNo(queryRequest);
+        resp.setValid(true);
+        resp.setOrderNo(result.getOutTradeNo());
+        if (result.getAmount() != null) {
+            resp.setOrderPrice(result.getAmount().getTotal());
+            resp.setPayPrice(result.getAmount().getPayerTotal());
+        }
+        switch (result.getTradeState()) {
+            case SUCCESS:
+                resp.setState(PayResponse.PAY_STATE.SUCCESS);
+                break;
+            case NOTPAY:
+            case CLOSED:
+            case REVOKED:
+                resp.setState(PayResponse.PAY_STATE.FAIL);
+                break;
+            case REFUND:
+                resp.setState(PayResponse.PAY_STATE.REFUND);
+                break;
+            default:
+                resp.setState(PayResponse.PAY_STATE.CANCEL);
+                break;
+        }
+        resp.setPayTime(result.getSuccessTime());
+        resp.setOriginalResponse(result);
+        return resp;
+    }
+
+    @Override
+    public RefundOrderResponse refund(RefundOrderRequest request) {
+        RefundOrderResponse resp = new RefundOrderResponse();
+        Config wxConfig = getConfig();
+        RefundService service = new RefundService.Builder().config(wxConfig).build();
+        CreateRequest createRequest = new CreateRequest();
+        createRequest.setOutTradeNo(request.getOrderNo());
+        createRequest.setOutRefundNo(request.getRefundNo());
+        AmountReq amountReq = new AmountReq();
+        amountReq.setTotal(Long.valueOf(request.getPrice()));
+        amountReq.setRefund(Long.valueOf(request.getRefundPrice()));
+        amountReq.setCurrency("CNY");
+        createRequest.setAmount(amountReq);
+        createRequest.setNotifyUrl(request.getNotifyUrl());
+        Refund refund = service.create(createRequest);
+        if (refund.getStatus() == SUCCESS) {
+            resp.setSuccess(true);
+            resp.setRefundNo(refund.getOutRefundNo());
+        } else {
+            resp.setSuccess(false);
+        }
+        return resp;
+    }
+
+    @Override
+    public RefundResponse handleRefundCallback(HttpServletRequest request) throws IOException {
+        ServletInputStream inputStream = request.getInputStream();
+        StringBuffer body = new StringBuffer();
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+        String s;
+        // 读取回调请求体
+        while ((s = bufferedReader.readLine()) != null) {
+            body.append(s);
+        }
+        RefundResponse resp = new RefundResponse();
+        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
+        String nonce = request.getHeader(WECHAT_PAY_NONCE);
+        String signType = request.getHeader(WECHAT_PAY_SIGNATURE_TYPE);
+        String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
+        String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
+        NotificationConfig config = (NotificationConfig) getConfig();
+        NotificationParser parser = new NotificationParser(config);RequestParam requestParam = new RequestParam.Builder()
+                .serialNumber(serialNo)
+                .nonce(nonce)
+                .signature(signature)
+                .timestamp(timestamp)
+                // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
+                .signType(signType)
+                .body(body.toString())
+                .build();
+        RefundNotification parse = parser.parse(requestParam, RefundNotification.class);
+        resp.setValid(true);
+        resp.setOriginalResponse(parse);
+        if (parse.getRefundStatus() == SUCCESS) {
+            //退款成功
+            resp.setSuccess();
+            resp.setRefundTime(parse.getSuccessTime());
+            resp.setOrderNo(parse.getOutTradeNo());
+            resp.setRefundNo(parse.getRefundId());
+            if (parse.getAmount() != null) {
+                resp.setRefundPrice(Math.toIntExact(parse.getAmount().getPayerRefund()));
+                resp.setOrderPrice(Math.toIntExact(parse.getAmount().getTotal()));
+            }
+        } else {
+            //退款失败
+            resp.setFail();
+        }
+        return resp;
+    }
+
+    @Override
+    public RefundResponse checkRefundStatus(String refundNo) {
+        Config wxConfig = getConfig();
+        RefundService service = new RefundService.Builder().config(wxConfig).build();
+        QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest();
+        request.setOutRefundNo(refundNo);
+        RefundResponse resp = new RefundResponse();
+        Refund result = service.queryByOutRefundNo(request);
+        resp.setValid(true);
+        resp.setOriginalResponse(result);
+        if (result.getStatus() == SUCCESS) {
+            //退款成功
+            resp.setSuccess();
+            resp.setRefundTime(result.getSuccessTime());
+            resp.setOrderNo(result.getOutTradeNo());
+            resp.setRefundNo(result.getRefundId());
+            if (result.getAmount() != null) {
+                resp.setRefundPrice(Math.toIntExact(result.getAmount().getPayerRefund()));
+                resp.setOrderPrice(Math.toIntExact(result.getAmount().getTotal()));
+            }
+        } else {
+            //退款失败
+            resp.setFail();
+        }
+        return resp;
+    }
+
+    @Override
+    public void cancelOrder(CancelOrderRequest request) {
+        CloseOrderRequest closeOrderRequest = new CloseOrderRequest();
+        closeOrderRequest.setOutTradeNo(request.getOrderNo());
+        closeOrderRequest.setMchid(config.getMerchantId());
+        Config config = getConfig();
+        JsapiService service = new JsapiService.Builder().config(config).build();
+        service.closeOrder(closeOrderRequest);
+    }
+
+    public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException {
+        String replace = privateKey.replace("\\n", "\n");
+        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromString(replace);
+        Signature sign = Signature.getInstance("SHA256withRSA");
+        sign.initSign(merchantPrivateKey);
+        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
+        return Base64Utils.encodeToString(sign.sign());
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/CancelOrderRequest.java b/src/main/java/com/ycwl/basic/pay/entity/CancelOrderRequest.java
new file mode 100644
index 0000000..63594ec
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/CancelOrderRequest.java
@@ -0,0 +1,10 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class CancelOrderRequest {
+    private String orderNo;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/CreateOrderRequest.java b/src/main/java/com/ycwl/basic/pay/entity/CreateOrderRequest.java
new file mode 100644
index 0000000..b286147
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/CreateOrderRequest.java
@@ -0,0 +1,35 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+@Data
+@Accessors(chain = true)
+public class CreateOrderRequest {
+    /**
+     * 价格,单位为分
+     */
+    private Integer price;
+    private String goodsName;
+    private String orderNo;
+    private String description;
+    private String userIdentify;
+    private String notifyUrl;
+
+
+    public BigDecimal getPriceInYuan() {
+        return new BigDecimal(BigInteger.valueOf(price), 2);
+    }
+    public CreateOrderRequest setPriceInCents(Integer priceInCents) {
+        this.price = priceInCents;
+        return this;
+    }
+
+    public CreateOrderRequest setPriceInYuan(BigDecimal priceInYuan) {
+        this.price = priceInYuan.multiply(new BigDecimal(100)).intValue();
+        return this;
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/CreateOrderResponse.java b/src/main/java/com/ycwl/basic/pay/entity/CreateOrderResponse.java
new file mode 100644
index 0000000..8decdb9
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/CreateOrderResponse.java
@@ -0,0 +1,10 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+
+@Data
+public class CreateOrderResponse {
+    private boolean success;
+    private boolean skipPay;
+    private String orderNo;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/PayResponse.java b/src/main/java/com/ycwl/basic/pay/entity/PayResponse.java
new file mode 100644
index 0000000..307454a
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/PayResponse.java
@@ -0,0 +1,34 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+
+@Data
+public class PayResponse {
+    private boolean valid;
+    private String orderNo;
+    private Object originalResponse;
+    private Integer orderPrice;
+    private Integer payPrice;
+    private PAY_STATE state;
+    private String payTime;
+
+    public boolean isPay() {
+        return state == PAY_STATE.SUCCESS;
+    }
+
+    public boolean isCancel() {
+        return state == PAY_STATE.CANCEL;
+    }
+
+    public boolean isRefund() {
+        return state == PAY_STATE.REFUND;
+    }
+
+    public enum PAY_STATE {
+        SUCCESS,
+        CANCEL,
+        REFUND,
+        FAIL,
+        UNKNOWN;
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/RefundOrderRequest.java b/src/main/java/com/ycwl/basic/pay/entity/RefundOrderRequest.java
new file mode 100644
index 0000000..c7ddd5f
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/RefundOrderRequest.java
@@ -0,0 +1,14 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class RefundOrderRequest {
+    private Integer price;
+    private Integer refundPrice;
+    private String orderNo;
+    private String refundNo;
+    private String notifyUrl;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/RefundOrderResponse.java b/src/main/java/com/ycwl/basic/pay/entity/RefundOrderResponse.java
new file mode 100644
index 0000000..0424fe3
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/RefundOrderResponse.java
@@ -0,0 +1,9 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+
+@Data
+public class RefundOrderResponse {
+    private boolean success;
+    private String refundNo;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/RefundResponse.java b/src/main/java/com/ycwl/basic/pay/entity/RefundResponse.java
new file mode 100644
index 0000000..15aac74
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/RefundResponse.java
@@ -0,0 +1,28 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+
+@Data
+public class RefundResponse {
+    private boolean valid;
+    private String orderNo;
+    private String refundNo;
+    private Object originalResponse;
+    private Integer orderPrice;
+    private Integer refundPrice;
+    private PAY_STATE state;
+    private String refundTime;
+
+    public void setSuccess() {
+        state = PAY_STATE.SUCCESS;
+    }
+
+    public void setFail() {
+        state = PAY_STATE.FAIL;
+    }
+
+    public enum PAY_STATE {
+        SUCCESS,
+        FAIL
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/entity/WxMpPayConfig.java b/src/main/java/com/ycwl/basic/pay/entity/WxMpPayConfig.java
new file mode 100644
index 0000000..6d2ade4
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/entity/WxMpPayConfig.java
@@ -0,0 +1,12 @@
+package com.ycwl.basic.pay.entity;
+
+import lombok.Data;
+
+@Data
+public class WxMpPayConfig {
+    private String merchantId;
+    private String appId;
+    private String privateKey;
+    private String serialNumber;
+    private String apiV3Key;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/enums/PayAdapterType.java b/src/main/java/com/ycwl/basic/pay/enums/PayAdapterType.java
new file mode 100644
index 0000000..dacbb8f
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/enums/PayAdapterType.java
@@ -0,0 +1,20 @@
+package com.ycwl.basic.pay.enums;
+
+public enum PayAdapterType {
+    WX_MP_PAY("WX_MP_PAY"),
+    ;
+
+    private String type;
+
+    PayAdapterType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/exceptions/PayException.java b/src/main/java/com/ycwl/basic/pay/exceptions/PayException.java
new file mode 100644
index 0000000..9f8cf16
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/exceptions/PayException.java
@@ -0,0 +1,7 @@
+package com.ycwl.basic.pay.exceptions;
+
+public class PayException extends RuntimeException {
+    public PayException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/exceptions/PayUndefinedException.java b/src/main/java/com/ycwl/basic/pay/exceptions/PayUndefinedException.java
new file mode 100644
index 0000000..7342b5d
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/exceptions/PayUndefinedException.java
@@ -0,0 +1,7 @@
+package com.ycwl.basic.pay.exceptions;
+
+public class PayUndefinedException extends RuntimeException {
+    public PayUndefinedException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/exceptions/PayUnsupportedException.java b/src/main/java/com/ycwl/basic/pay/exceptions/PayUnsupportedException.java
new file mode 100644
index 0000000..058fdbc
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/exceptions/PayUnsupportedException.java
@@ -0,0 +1,7 @@
+package com.ycwl.basic.pay.exceptions;
+
+public class PayUnsupportedException extends PayException {
+    public PayUnsupportedException(String message) {
+        super(message);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ycwl/basic/pay/exceptions/PayWrongConfigException.java b/src/main/java/com/ycwl/basic/pay/exceptions/PayWrongConfigException.java
new file mode 100644
index 0000000..5eb7622
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/exceptions/PayWrongConfigException.java
@@ -0,0 +1,7 @@
+package com.ycwl.basic.pay.exceptions;
+
+public class PayWrongConfigException extends PayException {
+    public PayWrongConfigException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/starter/PayAutoConfiguration.java b/src/main/java/com/ycwl/basic/pay/starter/PayAutoConfiguration.java
new file mode 100644
index 0000000..b5d82c5
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/starter/PayAutoConfiguration.java
@@ -0,0 +1,32 @@
+package com.ycwl.basic.pay.starter;
+
+import com.ycwl.basic.pay.PayFactory;
+import com.ycwl.basic.pay.adapter.IPayAdapter;
+import com.ycwl.basic.pay.starter.config.OverallPayConfig;
+import com.ycwl.basic.pay.starter.config.PayConfigItem;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class PayAutoConfiguration {
+    private final OverallPayConfig config;
+    public PayAutoConfiguration(OverallPayConfig config) {
+        this.config = config;
+        if (config != null) {
+            if (config.getConfigs() != null) {
+                loadConfig();
+            }
+            if (StringUtils.isNotBlank(config.getDefaultUse())) {
+                PayFactory.setDefault(config.getDefaultUse());
+            }
+        }
+    }
+
+    private void loadConfig() {
+        for (PayConfigItem item : config.getConfigs()) {
+            IPayAdapter adapter = PayFactory.getAdapter(item.getType());
+            adapter.loadConfig(item.getConfig());
+            PayFactory.register(item.getName(), adapter);
+        }
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/pay/starter/config/OverallPayConfig.java b/src/main/java/com/ycwl/basic/pay/starter/config/OverallPayConfig.java
new file mode 100644
index 0000000..bf260e8
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/starter/config/OverallPayConfig.java
@@ -0,0 +1,15 @@
+package com.ycwl.basic.pay.starter.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@ConfigurationProperties(prefix = "pay")
+@Data
+public class OverallPayConfig {
+    private String defaultUse;
+    private List<PayConfigItem> configs;
+}
diff --git a/src/main/java/com/ycwl/basic/pay/starter/config/PayConfigItem.java b/src/main/java/com/ycwl/basic/pay/starter/config/PayConfigItem.java
new file mode 100644
index 0000000..2f1fb56
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/pay/starter/config/PayConfigItem.java
@@ -0,0 +1,13 @@
+package com.ycwl.basic.pay.starter.config;
+
+import com.ycwl.basic.pay.enums.PayAdapterType;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+public class PayConfigItem {
+    private String name;
+    private PayAdapterType type;
+    private Map<String, String> config;
+}
diff --git a/src/main/java/com/ycwl/basic/utils/WXPayUtil.java b/src/main/java/com/ycwl/basic/utils/WXPayUtil.java
deleted file mode 100644
index 56bdfe2..0000000
--- a/src/main/java/com/ycwl/basic/utils/WXPayUtil.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.ycwl.basic.utils;
-
-
-import cn.hutool.core.util.XmlUtil;
-import com.wechat.pay.java.core.util.PemUtil;
-import org.springframework.util.Base64Utils;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.security.*;
-import java.util.Map;
-import java.util.Random;
-
-/**
- * @Author: songmingsong
- * @CreateTime: 2024-12-05
- * @Description: 微信支付
- * @Version: 1.0
- */
-public class WXPayUtil {
-
-    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-    private static final Random RANDOM = new SecureRandom();
-
-
-    public static  String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
-        //replace 根据实际情况,不一定都需要
-        String replace = privateKey.replace("\\n", "\n");
-        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromString(replace);
-        Signature sign = Signature.getInstance("SHA256withRSA");
-        sign.initSign(merchantPrivateKey);
-        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
-        return Base64Utils.encodeToString(sign.sign());
-    }
-
-    /**
-     * 获取随机字符串 Nonce Str
-     *
-     * @return String 随机字符串
-     */
-    public static String generateNonceStr() {
-        char[] nonceChars = new char[32];
-        for (int index = 0; index < nonceChars.length; ++index) {
-            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
-        }
-        return new String(nonceChars);
-    }
-
-    public static Map<String, Object> xmlToMap(String xmlData) {
-        return XmlUtil.xmlToMap(xmlData);
-    }
-}