mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	完善支付宝的 AlipayPayClient 的实现
This commit is contained in:
		@@ -1,15 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.PayClient;
 | 
			
		||||
import com.alipay.api.DefaultAlipayClient;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付客户端的抽象类,提供模板方法,减少子类的冗余代码
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractPayClient implements PayClient {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core;
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付客户端,用于对接各支付渠道的 SDK,实现发起支付、退款等功能
 | 
			
		||||
@@ -9,6 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
 */
 | 
			
		||||
public interface PayClient {
 | 
			
		||||
 | 
			
		||||
    CommonResult<String> unifiedOrder();
 | 
			
		||||
    // TODO 缺少注释
 | 
			
		||||
    CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core;
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付客户端的配置,本质是支付渠道的配置
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 将 API 的错误码,转换为通用的错误码
 | 
			
		||||
 *
 | 
			
		||||
 * @see PayCommonResult
 | 
			
		||||
 * @see PayFrameworkErrorCodeConstants
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
public interface PayCodeMapping extends Function<String, ErrorCode> {
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,60 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.exceptions.ExceptionUtil;
 | 
			
		||||
import cn.hutool.core.lang.Assert;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.ToString;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付的 CommonResult 拓展类
 | 
			
		||||
 *
 | 
			
		||||
 * 考虑到不同的平台,返回的 code 和 msg 是不同的,所以统一额外返回 {@link #apiCode} 和 {@link #apiMsg} 字段
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@ToString(callSuper = true)
 | 
			
		||||
public class PayCommonResult<T> extends CommonResult<T> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * API 返回错误码
 | 
			
		||||
     *
 | 
			
		||||
     * 由于第三方的错误码可能是字符串,所以使用 String 类型
 | 
			
		||||
     */
 | 
			
		||||
    private String apiCode;
 | 
			
		||||
    /**
 | 
			
		||||
     * API 返回提示
 | 
			
		||||
     */
 | 
			
		||||
    private String apiMsg;
 | 
			
		||||
 | 
			
		||||
    private PayCommonResult() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> PayCommonResult<T> build(String apiCode, String apiMsg, T data, PayCodeMapping codeMapping) {
 | 
			
		||||
        Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
 | 
			
		||||
        PayCommonResult<T> result = new PayCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg);
 | 
			
		||||
        result.setData(data);
 | 
			
		||||
        // 翻译错误码
 | 
			
		||||
        if (codeMapping != null) {
 | 
			
		||||
            ErrorCode errorCode = codeMapping.apply(apiCode);
 | 
			
		||||
            if (errorCode == null) {
 | 
			
		||||
                errorCode = PayFrameworkErrorCodeConstants.EXCEPTION;
 | 
			
		||||
            }
 | 
			
		||||
            result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> PayCommonResult<T> error(Throwable ex) {
 | 
			
		||||
        PayCommonResult<T> result = new PayCommonResult<>();
 | 
			
		||||
        result.setCode(PayFrameworkErrorCodeConstants.EXCEPTION.getCode());
 | 
			
		||||
        result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.alipay;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayClient;
 | 
			
		||||
import com.alipay.api.AlipayApiException;
 | 
			
		||||
import com.alipay.api.DefaultAlipayClient;
 | 
			
		||||
import com.alipay.api.domain.AlipayTradePrecreateModel;
 | 
			
		||||
import com.alipay.api.request.AlipayTradePrecreateRequest;
 | 
			
		||||
import com.alipay.api.response.AlipayTradePrecreateResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付宝的 PayClient 实现类
 | 
			
		||||
 */
 | 
			
		||||
public class AlipayPayClient extends AbstractPayClient {
 | 
			
		||||
 | 
			
		||||
    private DefaultAlipayClient client = new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do","2021000118634035","MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=","json","utf-8","MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB","RSA2");
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CommonResult<String> unifiedOrder() {
 | 
			
		||||
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
 | 
			
		||||
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
 | 
			
		||||
        request.setBizModel(model);
 | 
			
		||||
        model.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
 | 
			
		||||
        model.setTotalAmount("88.88");
 | 
			
		||||
        model.setSubject("Iphone6 16G");
 | 
			
		||||
        AlipayTradePrecreateResponse response = null;
 | 
			
		||||
        try {
 | 
			
		||||
            response = client.execute(request);
 | 
			
		||||
        } catch (AlipayApiException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println(response.getBody());
 | 
			
		||||
        System.out.println(response.getQrCode());
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        AlipayPayClient client = new AlipayPayClient();
 | 
			
		||||
        client.unifiedOrder();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,58 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.dto;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.hibernate.validator.constraints.Length;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.DecimalMin;
 | 
			
		||||
import javax.validation.constraints.NotEmpty;
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 统一下单 Request DTO
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class PayOrderUnifiedReqDTO {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 客户端 IP
 | 
			
		||||
     */
 | 
			
		||||
    @NotEmpty(message = "客户端 IP 不能为空")
 | 
			
		||||
    private String clientIp;
 | 
			
		||||
 | 
			
		||||
    // ========== 商户相关字段 ==========
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 商户订单编号
 | 
			
		||||
     */
 | 
			
		||||
    @NotEmpty(message = "商户订单编号不能为空")
 | 
			
		||||
    private String merchantOrderId;
 | 
			
		||||
    /**
 | 
			
		||||
     * 商品标题
 | 
			
		||||
     */
 | 
			
		||||
    @NotEmpty(message = "商品标题不能为空")
 | 
			
		||||
    @Length(max = 32, message = "商品标题不能超过 32")
 | 
			
		||||
    private String subject;
 | 
			
		||||
    /**
 | 
			
		||||
     * 商品描述信息
 | 
			
		||||
     */
 | 
			
		||||
    @NotEmpty(message = "商品描述信息不能为空")
 | 
			
		||||
    @Length(max = 128, message = "商品描述信息长度不能超过128")
 | 
			
		||||
    private String body;
 | 
			
		||||
 | 
			
		||||
    // ========== 订单相关字段 ==========
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 支付金额,单位:分
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull(message = "支付金额不能为空")
 | 
			
		||||
    @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
 | 
			
		||||
    private Integer amount;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 支付过期时间
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull(message = "支付过期时间不能为空")
 | 
			
		||||
    private Date expireTime;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.impl;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付客户端的抽象类,提供模板方法,减少子类的冗余代码
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractPayClient implements PayClient {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 错误码枚举类
 | 
			
		||||
     */
 | 
			
		||||
    protected PayCodeMapping codeMapping;
 | 
			
		||||
 | 
			
		||||
    protected Double calculateAmount(Integer amount) {
 | 
			
		||||
        return amount / 100.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,79 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.bean.BeanUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
 | 
			
		||||
import com.alipay.api.AlipayApiException;
 | 
			
		||||
import com.alipay.api.AlipayConfig;
 | 
			
		||||
import com.alipay.api.DefaultAlipayClient;
 | 
			
		||||
import com.alipay.api.domain.AlipayTradePrecreateModel;
 | 
			
		||||
import com.alipay.api.request.AlipayTradePrecreateRequest;
 | 
			
		||||
import com.alipay.api.response.AlipayTradePrecreateResponse;
 | 
			
		||||
import lombok.SneakyThrows;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付宝的 PayClient 实现类
 | 
			
		||||
 */
 | 
			
		||||
public class AlipayPayClient extends AbstractPayClient {
 | 
			
		||||
 | 
			
		||||
    private final DefaultAlipayClient client;
 | 
			
		||||
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    public AlipayPayClient(AlipayPayConfig config) {
 | 
			
		||||
        // 创建 DefaultAlipayClient 对象
 | 
			
		||||
        AlipayConfig alipayConfig = new AlipayConfig();
 | 
			
		||||
        BeanUtil.copyProperties(config, alipayConfig, false);
 | 
			
		||||
        this.client = new DefaultAlipayClient(alipayConfig);
 | 
			
		||||
 | 
			
		||||
        // 创建 AlipayPayCodeMapping 对象
 | 
			
		||||
        super.codeMapping = new AlipayPayCodeMapping();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO 芋艿:暂时是扫码支付,需要调整成 wap https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
 | 
			
		||||
    @Override
 | 
			
		||||
    public CommonResult<Object> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
 | 
			
		||||
        // 构建 AlipayTradePrecreateModel 请求
 | 
			
		||||
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
 | 
			
		||||
        model.setOutTradeNo(reqDTO.getMerchantOrderId());
 | 
			
		||||
        model.setSubject(reqDTO.getSubject());
 | 
			
		||||
        model.setBody(reqDTO.getBody());
 | 
			
		||||
        model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString());
 | 
			
		||||
        // TODO 芋艿:clientIp + expireTime
 | 
			
		||||
        // 构建 AlipayTradePrecreateRequest
 | 
			
		||||
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
 | 
			
		||||
        request.setBizModel(model);
 | 
			
		||||
 | 
			
		||||
        // 执行请求
 | 
			
		||||
        AlipayTradePrecreateResponse response = null;
 | 
			
		||||
        try {
 | 
			
		||||
            response = client.execute(request);
 | 
			
		||||
        } catch (AlipayApiException e) {
 | 
			
		||||
            return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        System.out.println(response.getBody());
 | 
			
		||||
        System.out.println(response.getQrCode());
 | 
			
		||||
 | 
			
		||||
        // TODO 芋艿:sub Code
 | 
			
		||||
        return PayCommonResult.build(response.getCode(), response.getMsg(), response, codeMapping);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        AlipayPayConfig config = new AlipayPayConfig();
 | 
			
		||||
        config.setAppId("2021000118634035");
 | 
			
		||||
        config.setServerUrl(AlipayPayConfig.SERVER_URL_SANDBOX);
 | 
			
		||||
        config.setSignType(AlipayPayConfig.SIGN_TYPE_DEFAULT);
 | 
			
		||||
        config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8=");
 | 
			
		||||
        config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB");
 | 
			
		||||
        AlipayPayClient client = new AlipayPayClient(config);
 | 
			
		||||
 | 
			
		||||
        PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO();
 | 
			
		||||
        reqDTO.setAmount(123);
 | 
			
		||||
        reqDTO.setSubject("IPhone 13");
 | 
			
		||||
        reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis()));
 | 
			
		||||
        client.unifiedOrder(reqDTO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.client.PayCodeMapping;
 | 
			
		||||
 | 
			
		||||
public class AlipayPayCodeMapping implements PayCodeMapping {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ErrorCode apply(String s) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.alipay;
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
@@ -15,11 +15,11 @@ public class AlipayPayConfig {
 | 
			
		||||
    /**
 | 
			
		||||
     * 网关地址 - 线上
 | 
			
		||||
     */
 | 
			
		||||
    private static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
 | 
			
		||||
    public static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do";
 | 
			
		||||
    /**
 | 
			
		||||
     * 网关地址 - 沙箱
 | 
			
		||||
     */
 | 
			
		||||
    private static final String SERVER_URL_SANDBOX = "https://openapi.alipay.com/gateway.do";
 | 
			
		||||
    public static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 公钥类型 - 公钥模式
 | 
			
		||||
@@ -33,7 +33,7 @@ public class AlipayPayConfig {
 | 
			
		||||
    /**
 | 
			
		||||
     * 签名算法类型 - RSA
 | 
			
		||||
     */
 | 
			
		||||
    private static final String SIGN_TYPE_DEFAULT = "RSA2";
 | 
			
		||||
    public static final String SIGN_TYPE_DEFAULT = "RSA2";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 网关地址
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client;
 | 
			
		||||
@@ -0,0 +1,47 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.enums;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 支付框架的错误码枚举
 | 
			
		||||
 *
 | 
			
		||||
 * 短信框架,使用 2-002-000-000 段
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
public interface PayFrameworkErrorCodeConstants {
 | 
			
		||||
 | 
			
		||||
    ErrorCode PAY_UNKNOWN = new ErrorCode(2001000000, "未知错误,需要解析");
 | 
			
		||||
 | 
			
		||||
//    // ========== 权限 / 限流等相关 2001000100 ==========
 | 
			
		||||
//
 | 
			
		||||
//    ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2001000100, "没有发送短信的权限");
 | 
			
		||||
//    // 云片:可以配置 IP 白名单,只有在白名单中才可以发送短信
 | 
			
		||||
//    ErrorCode SMS_IP_DENY = new ErrorCode(2001000100, "IP 不允许发送短信");
 | 
			
		||||
//
 | 
			
		||||
//    // 阿里云:将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。
 | 
			
		||||
//    ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2001000102, "指定手机的发送限流");
 | 
			
		||||
//    // 阿里云:已经达到您在控制台设置的短信日发送量限额值。在国内消息设置 > 安全设置,修改发送总量阈值。
 | 
			
		||||
//    ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2001000103, "每天的发送限流");
 | 
			
		||||
//
 | 
			
		||||
//    ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2001000104, "短信内容有敏感词");
 | 
			
		||||
//
 | 
			
		||||
//    // ========== 模板相关 2001000200 ==========
 | 
			
		||||
//    ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2001000200, "短信模板不合法"); // 包括短信模板不存在
 | 
			
		||||
//    ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2001000201, "模板参数不正确");
 | 
			
		||||
//
 | 
			
		||||
//    // ========== 签名相关 2001000300 ==========
 | 
			
		||||
//    ErrorCode SMS_SIGN_INVALID = new ErrorCode(2001000300, "短信签名不可用");
 | 
			
		||||
//
 | 
			
		||||
//    // ========== 账户相关 2001000400 ==========
 | 
			
		||||
//    ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2001000400, "账户余额不足");
 | 
			
		||||
//    ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2001000401, "apiKey 不存在");
 | 
			
		||||
//
 | 
			
		||||
//    // ========== 其它相关 2001000900 开头 ==========
 | 
			
		||||
//    ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2001000900, "请求参数缺失");
 | 
			
		||||
//    ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2001000901, "手机格式不正确");
 | 
			
		||||
//    ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2001000902, "手机号在黑名单中");
 | 
			
		||||
 | 
			
		||||
    ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user