网站-支付宝/微信扫码支付 工厂模式

maven

<!--		微信支付-->
		<dependency>
			<groupId>com.github.wechatpay-apiv3</groupId>
			<artifactId>wechatpay-java</artifactId>
			<version>0.2.15</version>
		</dependency>


<!--		阿里支付-->
		<dependency>
			<groupId>com.alipay.sdk</groupId>
			<artifactId>alipay-sdk-java</artifactId>
			<version>4.40.16.ALL</version>
		</dependency>

接口 PaymentCodeGenerator

public interface PaymentCodeGenerator {

    String generatePaymentCode(String orderNo, BigDecimal totalAmount,
                               String description) throws Exception;
}

支付宝的实现 AliPaymentCodeGenerator

官方:https://opendocs.alipay.com/open/59da99d0_alipay.trade.page.pay?pathHash=e26b497f&scene=22

import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;

import java.math.BigDecimal;

public class AliPaymentCodeGenerator implements PaymentCodeGenerator {

    private PaymentConf paymentConfig;

    public AliPaymentCodeGenerator(PaymentConf paymentConfig) {
        this.paymentConfig = paymentConfig;
    }


    @Override
    public String generatePaymentCode(String orderNo, BigDecimal totalAmount, String description) throws Exception {

        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();

        // 设置商户订单号
        model.setOutTradeNo(orderNo);

        // 设置订单总金额
        model.setTotalAmount(totalAmount.toString());

        // 设置订单标题
        model.setSubject(description);

        // 设置产品码
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(paymentConfig.getCallBack()); 

        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST"); 
        String pageRedirectionData = response.getBody();

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败"); 
        }
        return pageRedirectionData;
    } 
    private AlipayConfig getAlipayConfig() {
        String privateKey = paymentConfig.getPrivateKey();
        String alipayPublicKey = paymentConfig.getAlipayPublicKey();
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId(paymentConfig.getAppId());
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        return alipayConfig;
    } 
    
    public static void main(String[] args) {
        PaymentConf paymentConf = new PaymentConf();
  		paymentConf.setAppId("");// 你的appId;
        paymentConf.setPrivateKey("");//你的应用私钥
        paymentConf.setAlipayPublicKey("");//你的支付宝公钥
        paymentConf.setCallBack("");//你的回调接口

        AliPaymentCodeGenerator generator = new AliPaymentCodeGenerator(
                paymentConf
        );
        try {
            String s = generator.generatePaymentCode(
                    "11111111111",
                    new BigDecimal(0.01),
                    "保证金"
            );
            System.out.println("成功:");
        } catch (Exception e) {
            System.out.println("报错:" + e.getMessage());
        }
    }
}

微信付款码 V2 WechatPaymentCodeV2Generator

官方:https://pay.weixin.qq.com/doc/v2/merchant/4011936530


import org.gin.exceptions.ServiceException;
import org.gin.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

public class WechatPaymentCodeV2Generator implements PaymentCodeGenerator {

    private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    private final PaymentConf paymentConfig;

    public WechatPaymentCodeV2Generator(PaymentConf paymentConfig) {
        this.paymentConfig = paymentConfig;
    }

    @Override
    public String generatePaymentCode(String orderNo, BigDecimal totalAmount, String description) throws Exception {
        InetAddress inetAddress = InetAddress.getLocalHost();
        Integer amount=totalAmount.multiply(new BigDecimal(100)).intValue();

        Map<String, String> params = prepareRequestParams(orderNo, amount.toString(), description, inetAddress);

        // 签名
        String sign = generateSign(params, paymentConfig.getMchKey());
        params.put("sign", sign);

        String xmlParam = XmlUtil.mapToXml(params);
        String responseXml = sendPostRequest(UNIFIEDORDER_URL, xmlParam);

        // 解析返回结果
        Map<String, String> resultMap = convertXMLToMap(responseXml);
        return processResponse(resultMap);
    }

    private Map<String, String> prepareRequestParams(String orderNo, String totalAmount, String description, InetAddress inetAddress) {
        Map<String, String> params = new HashMap<>();
        params.put("appid", paymentConfig.getAppId());
        params.put("mch_id", paymentConfig.getMchId());
        params.put("nonce_str", generateNonceStr());
        params.put("body", description);
        params.put("out_trade_no", orderNo);
        Integer amount = new BigDecimal(totalAmount).multiply(new BigDecimal(100)).intValue();
        params.put("total_fee", amount.toString());
        params.put("spbill_create_ip", inetAddress.getHostAddress());
        params.put("notify_url", paymentConfig.getCallBack());
        params.put("trade_type", "NATIVE"); // 微信扫码支付
        return params;
    }

    private String generateNonceStr() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private String generateSign(Map<String, String> params, String appKey) throws NoSuchAlgorithmException {
        Map<String, String> sortedMap = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        sb.append("key=").append(appKey);
        return md5(sb.toString()).toUpperCase();
    }

    private String md5(String str) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        byte[] hashBytes = messageDigest.digest(str.getBytes(StandardCharsets.UTF_8));
        StringBuilder hexString = new StringBuilder();
        for (byte b : hashBytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append("0");
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    private String sendPostRequest(String url, String xmlParam) throws IOException {
        HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/xml");
        conn.setDoOutput(true);
        try (OutputStream out = conn.getOutputStream()) {
            out.write(xmlParam.getBytes(StandardCharsets.UTF_8));
            out.flush();
        }

        StringBuilder response = new StringBuilder();
        try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = in.readLine()) != null) {
                response.append(line);
            }
        }
        conn.disconnect();
        return response.toString();
    }

    private Map<String, String> convertXMLToMap(String xmlString) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource inputSource = new InputSource(new StringReader(xmlString));
        Document document = builder.parse(inputSource);
        return parseElementToMap(document.getDocumentElement());
    }

    private Map<String, String> parseElementToMap(Element element) {
        Map<String, String> map = new HashMap<>();
        NodeList childNodes = element.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node node = childNodes.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                map.put(node.getNodeName(), node.getTextContent().trim());
            }
        }
        return map;
    }


    private String processResponse(Map<String, String> resultMap) throws ServiceException {
        if ("SUCCESS".equals(resultMap.get("return_code"))) {
            return resultMap.get("code_url");
        } else {
            String returnMsg = resultMap.get("return_msg");
            throw new ServiceException("Error in response: " + returnMsg);
        }
    }
}

微信扫码支付 V3 WechatPaymentCodeGenerator

官方:https://pay.weixin.qq.com/doc/v3/merchant/4012791877

 
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;

import java.math.BigDecimal;
 

public class WechatPaymentCodeGenerator implements PaymentCodeGenerator{

    /** 商户API私钥路径 */
    public static String privateKeyPath = "你自己的私钥路径";
    /** 商户证书序列号 */
    public static String merchantSerialNumber = "商户序列号";



    private PaymentConf paymentConfig;

    public WechatPaymentCodeGenerator(PaymentConf paymentConfig) {
        this.paymentConfig = paymentConfig;
    }

    @Override
    public String generatePaymentCode(String orderNo, BigDecimal totalAmount, String description) throws Exception {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(paymentConfig.getMchId())
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(merchantSerialNumber)
                        .apiV3Key(paymentConfig.getMchKey())
                        .build();
        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数,具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(totalAmount.multiply(new BigDecimal(100)).intValue());
        request.setAmount(amount);
        request.setAppid(paymentConfig.getAppId());
        request.setMchid(paymentConfig.getMchId());
        request.setDescription(description);
        request.setNotifyUrl(paymentConfig.getCallBack());
        request.setOutTradeNo(orderNo);
        // 调用下单方法,得到应答
        PrepayResponse response = service.prepay(request);
        // 使用微信扫描 code_url 对应的二维码,即可体验Native支付
        return response.getCodeUrl();
    }

    public static void main(String[] args) throws Exception {
        PaymentConf paymentConf=new PaymentConf();
        paymentConf.setAppId("你自己的appId");
        paymentConf.setMchId("你自己的商户id");
        paymentConf.setMchKey("你的商户key");

        WechatPaymentCodeGenerator generator=new WechatPaymentCodeGenerator(paymentConf);
        String s=generator.generatePaymentCode(
                "111111",new BigDecimal(1),"保证金"
        );
        System.out.println(s);
    }


}

工厂

package org.gin.paymentcode; 

public class PaymentCodeGeneratorFactory {

    /**
     *
     * @param paymentMethod 支付方式 3支付宝;1微信
    * @param paymentConfig
     * @return PaymentCodeGenerator 
     */
    public static PaymentCodeGenerator getQRCodeGenerator(Integer paymentMethod, PaymentConf paymentConfig) {
        if (paymentMethod==1) {
            return new WechatPaymentCodeV2Generator(paymentConfig);
        }
        if (paymentMethod==3) {
            return new AliPaymentCodeGenerator(paymentConfig);
        }
        throw new IllegalArgumentException("Unsupported payment method: " + paymentMethod);
    }
}

实际使用

 String paymentPath = PaymentCodeGeneratorFactory.getQRCodeGenerator(
                    businessType, paymentConf
            ).generatePaymentCode(

                    orderNo, deposit,
                    "保证金"
            );

工具类

XmlUtil

 

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.Map;

 
public class XmlUtil {

    public static String mapToXml(Map<String, String> map) throws Exception {
        DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
        Document document = documentBuilder.newDocument();

        Element root = document.createElement("parameters");
        document.appendChild(root);

        for (Map.Entry<String, String> entry : map.entrySet()) {
            Element element = document.createElement(entry.getKey());
            element.appendChild(document.createTextNode(entry.getValue()));
            root.appendChild(element);
        }

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        DOMSource source = new DOMSource(document);
        transformer.transform(source, result);
        return writer.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值