AliPay.java 7.7 KB
package com.aigeo.util.pay;

import com.aigeo.entity.ApiConfig;
import com.aigeo.entity.PayDto;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.diagnosis.DiagnosisUtils;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class AliPay implements PaymentStrategy{

    // 环境切换开关,"sandbox" 或 "prod",根据实际环境设置
    private static final String environment = "sandbox";
    // 定义环境配置
    public static Map<String, Map<String, String>> CONFIG_MAG = new HashMap<String, Map<String, String>>();

    static {
        // 沙箱环境配置
        Map<String, String> sandbox = new HashMap<String, String>();
        // AppId,对应配置项为“应用信息”。
        sandbox.put("appId", "9021000123615361");
        // 支付宝沙箱网关地址(sandboxAlipayGateway),对应配置项为“支付宝网关”。
        sandbox.put("gatewayUrl", "https://openapi-sandbox.dl.alipaydev.com/gateway.do");
        // 支付宝沙箱公钥(sandboxAlipayPublicKey),对应配置项为“密钥配置”。
        sandbox.put("alipayPublicKey", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkksZzpOGWoGMz9lz7y79DtaXuvsOs4d4ChdYir3/FSRHbYn/4G25LYw+7h00s8JCXIPhLoozWi9ZFN3hEMUHreT0/UPk0LgX7AS43VQHmR0cLhOOf2o5zxpzN9SjU/zK3ZQT0rEuNyoikPaY/UK4fqHvySBc7OfeKefDqdS/v/BchwzlzefEqXg4imz0uUMhn8micUuAeT7iF72NxlqCBmRXzOBx/CaUCOA2BMn2b3KDUix2qiy8FzkPQRj5dXQbDu8JFsHDAU/T9as8JY1ZRDI3wPgHverb5SuyFydeQsIEHSmC89k+TySa4bqbQRZ5+LOFzbkyrCXXQ9y1V/4jgQIDAQAB");
        // 应用沙箱私钥(sandboxAppPrivateKey),对应配置项为“密钥配置”。
        sandbox.put("appPrivateKey", "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCl7rLc1vU1YMij5nGna2Tiqw08TgCEoaviLgHaenBJi8JfUDndm01XAZ6Vfia53F4yvj8woPkiOzn/HYEfqs3+SAPbdQF/KyZ6GocAxwZBAhXTLD+c/D3pRX9lrOo+krw6H8JoJeVrDD2v4N1fWJBfh8U4x+pMcysYnDZbS9xquGNaPIpEnGZ7FHCvQo5Uq2xDv4iApwmiWdwNcgN9xatCy5deM9ot08cd+rL9NcnFnuWdxeQVBLvYS6w28kJUKKOIIUXKhWkpVTspZksUJRqKevlgw+wL2ORFB0CiAV9l7wugdt0V2KqLeroUNuOYkh9fBTwXTEv/NHZ+mUjmECETAgMBAAECggEAFdmm5/nOdGb4RMz1rmwv7sFDjutemhiH/9K7H7/7xVOIFvEDjbEDsC9gaKMiCluAdAIlZAvugpl1+6gw9rCRS6jECUQRHGPcPzv7BxkuM6VIpnQvNEbrCCrEqejpN7Au5SCFgx1qZnxIKz7bJ9ELweipCd8ZdVO9GxKG/eKxdcP3ZntujxkcSsgaYLKp7KozWmFYTFphGTsRjrJYofg6KpIONxDIigQfNWpyBHCre13lAsP+nxccOCw1Lx2/m1Xda0U7XWDeRePiutrsOV2KPZa59qv15tezjsIs0yhQnTPmDLMRQ2a5oJLRuPRreLLJwDGsG0FZXNUEQK6mWnD4gQKBgQDqXsNwmgTEPW/jcq2Myh4iLlY4Ag3kR7iVOsFn4PbZrqf+B52wSepp4uT9+10z6nuKADMWyUMS+jwPAeoWlhygUkhdB8L50KDcXztsz9NGQ+4LX9OGJncp616Lw3pdIFMkptPuCvjUISi/xy/24VbkgLzosfr2a1rIf7QwHpwI8wKBgQC1PwXaw1eEstzwK/+ov0ptIRQKQlw7frJHx3rRPFCu94G6pbNOLN2FhzZ5D0sIAHlQFhkUR34qOTw/bgS1WduUHWKH+pSGhW7g/hb2G6/gKsGgTUvdW8/jVQoTdS++iKJkI6q08lAdZG769c+PH1gb/RdArhHk979OTwUpmIuPYQKBgQC3/jE8ow1+6iR+0TbCQqKpfusdCS/SuSOFtBzF6mygtGcaHOyEy2KGQiQ36DBhY4Ic8s8o4lQP//dKaNxXYv2SN0asEj3VVR4UI4dJg1Z/4TBuKYqr1GLUu/z7iDj2Bzx+l6HlTSPPlUCiXkOfc4R92ztzCtbUwa8BnI/e/wjMVQKBgE1J+conIOwShgrZCGXCZQ+SWoRhdglc5tObKjGNoe5q12RrgsHkefaWCVGohtt7sD/JnJo8Pn3s+FcoKFPZZLyNp1XLMokG35iMYehDOEXEldsw+xgDLeyIeAqCH4EFrRI872/IIQfXq0fTiNZEjIMq8z5+vFzClU7kfZQWW/UhAoGBANjKR0NJKOMBTGJhSuSL4mL96ayoUoiYDXkQMVvP0oGAt6jdq34lyl+e4n02yhd5IHIDOXrIdx2xnd+HAOBI1YPAYMJ4gHC8WQM9dbjxtqyyNGSQnpVLCAdxvVInCrJdYR82+26oPIUbMtOHVkjtCr47wXlSHb82Ax9UgL5Bhl7N");
        // 线上环境配置
        Map<String, String> prod = new HashMap<String, String>();
        // AppId,对应配置项为“应用信息”。
        prod.put("appId", "${appId}");
        // 支付宝线上网关地址(prodAlipayGateway),对应配置项为“支付宝网关”。
        prod.put("gatewayUrl", "${prodAlipayGateway}");
        // 支付宝线上公钥(prodAlipayPublicKey),对应配置项为“密钥配置”。
        prod.put("alipayPublicKey", "${prodAlipayPublicKey}");
        // 应用线上私钥(prodAppPrivateKey),需要替换为线上环境使用的应用私钥,对应配置项为“密钥配置”,注意 Java 语言需要 PKCS8 格式的密钥。
        prod.put("appPrivateKey", "${prodAppPrivateKey}");
        CONFIG_MAG.put("sandbox", sandbox);
        CONFIG_MAG.put("prod", prod);
    }

    @Override
    public String pay(PayDto payDto) {
        try {
            AlipayConfig alipayConfig = new AlipayConfig();
            ApiConfig config = payDto.getApiConfig();
            alipayConfig.setServerUrl(config.getApiUrl());
            alipayConfig.setAppId(config.getApiId());

            String path = this.getClass().getResource("/").getPath();
            path = path.replace("/", "//");
            path = path.replace("//target//classes//", "");
            path = path.replace("//WEB-INF//classes//", "");
            //获取秘钥内容
            String publicKey = getKey(path+config.getPublicKeyPath());
            String privateKey = getKey(path+config.getPrivateKeyPath());

            alipayConfig.setPrivateKey(privateKey);
            alipayConfig.setAlipayPublicKey(publicKey);

            alipayConfig.setFormat("json");
            alipayConfig.setCharset("UTF-8");
            alipayConfig.setSignType("RSA2");
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            // 构造请求参数以调用接口
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

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

            model.setProductCode("QR_CODE_OFFLINE");
            // 设置订单总金额
            model.setTotalAmount(payDto.getAmount());
            // 设置订单标题
            model.setSubject(payDto.getOrderId());
            // 设置商户的原始订单号
            model.setMerchantOrderNo(payDto.getOrderId());

            request.setBizModel(model);
            request.setNotifyUrl(config.getApiRedirectUri()+"/"+payDto.getCompanyId());
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            System.out.println(response.getBody());
            if (response.isSuccess()) {
                log.info("订单号:{}请求支付宝支付",response.getOutTradeNo());
                return response.getQrCode();
            } else {
                System.out.println(response.getSubMsg());
                System.out.println("调用失败");
                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                System.out.println(diagnosisUrl);
                return response.getSubMsg();
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void closeTrade(String orderId, String mchId, ApiConfig apiConfig) {

    }

    @Override
    public void refund() {

    }

    @Override
    public String getChannel() {
        return "alipay";
    }

    private String getKey(String filePath) throws IOException{
        String fixed = filePath
                .replaceAll("^/+([A-Za-z]):/+", "$1:/")   // 去掉前导 // 并保留盘符
                .replace('/', File.separatorChar);          // 把 / 换成平台分隔符

        // 2. 读取
        byte[] bytes = Files.readAllBytes(Paths.get(fixed));
        return new String(bytes, StandardCharsets.UTF_8);
    }
}