SpringBoot集成支付宝沙箱环境

时间秒杀一切 提交于 2020-05-08 08:43:49

最近在忙于做毕业设计,刚好用到支付宝充值功能,就过来写个帖子。

1.到支付宝网站注册账号

官网:https://openhome.alipay.com/platform/developerIndex.htm

 

 2.点击研发服务进入沙箱环境

配置RSA2,推荐使用支付宝提供的密匙工具。同步异步接口也可以不设置,下文会在java代码中设置

这里异步调用接口需要公网可以访问,如果经济不允许的情况下可以使用花生壳内网穿透工具:

网址:https://hsk.oray.com/

我的个人配置:开通HTTP协议需要花费6元永久域名

 

 

 

 

 

 

 

 

 3.沙箱账号

用于登录沙箱版支付宝app测试

4.接入项目

创建一个配置类

 

/**
 * @author 码农界的小学生
 * @description:阿里支付配置信息
 * @title: AliDevPayConfig
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 19:06
 */
@Configuration
public class AliDevPayConfig implements Serializable {

// 这个是支付完成后的跳转路径 可以是一个页面地址等
    public static String returnUrl = "http://www.graduation.com/#/addIncoming";
    //服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 这个是支付成功失败以后的通知接口会返回相应的参数
    public static String notifyUrl = "http://3111h4q179.zicp.vip/cms/alipay/notify";

    /**支付宝分配给开发者的应用ID*/
    public static String aliPayAppId = "你的appid";
    /**
     * 商户id
     */
    public static String uid = "2088102180918899";
    /**支付宝网关*/
    public static String aliPayGateWay = "https://openapi.alipaydev.com/gateway.do";
    public static  String mcloud_api_domain = "http://mcloudmonitor.com/gateway.do";
    /**私钥*/
    public static String aliPayPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtPPBOHRZyOPH2Qn4IAWmY+qrJaYSs5PZwRtAxm7oPcgChnacGr8uTZKtZtNFMwoI1RXqutWAWjMhVNHv9JcAdZbL7LsXO8AuP09YcFpGGXEWFoze3RGeN4Oiy1JhC21nkZONXn2RlmR44dHNLvH3p213MjR6omV16qG0SqFyCQ6m3DPVvXn+aclw+0vZPa6wvjKFn57WdgFrrwHSKMvuPoz5qW4Yv7wu4isXyOowczyfX0DERVvcdYdaIPUOEBEN6EcKbVq8/FC1zMq79REBU/iVtVjWunRe6FMq+jbzNsVvZdwm2FEG2hcnw+GmvZUMIstUf3dm3yZiMqULPCGf/AgMBAAECggEAdingx4czrkmFUTHdgVxlSMGCCMv+gWfTaJYEoDHWYX6jS5mbOgZi13CNKC0brj3mTqvLmKuClR8F7ohUIkHDnsmloYsvxY0adcpKevIx5PG/Qf4onMr9z1qfnotAKCoyUIU4RKYl9t7QLDXSBtDVGdRVUJbZWKrzhhyn+Vf5cafOyyQEgMAonAYqkLweZilyFO5TGlgLKJsKXhQjltZrPxVebQ9PowIz47NvQVOBya+WGTAkyN1Bri10ZLxr62VGhUjUGKcRL0qVxtaXpafARcW5HU1U/aJlkX9stHZwRlLsxdN5MV1DwlKInX9shYHOHheCsohlB7ZaZYmwrVulEQKBgQD1cmknrwkiYgocPq7NhQ89IddmWgduqkTE9FbaDXtM7YrvTIPGJDCE5d71R+sw8GG36M0OQxitdB72mbv6md+FxqmAtlD6d0L5V0mJfRErW4W48NhCI03XIWUcy3JrtqVF1N7qlB7D5IkW3DBqFVHf2iO97oMczhhsQsVnrH0VmwKBgQC0r7zyS6DwV1Pb8q3n1dmWD/wg4PuV35PC/uZ5CXiYWOcbaZZM1+3QQ56F/qZugwsb7aXbl7lL67hZ70GcQJPC8YBHebrBK9q/8C29TkPigzY0jWgM4rFbcb/raRKP3Oy1T4itIUH1/nuWwZT2AoT8lLRbLmeUeDCvg3GsbrhvbQKBgQCxhkvKOQ5pQPHBFhFGcsvf0l9CFzGy+BH/Rh6fXgrlTBYmGHhi0oAJT12gmKDiZ6q14vqVKzBpHEjc4bqVeb+yuUqV3sfZMHNPdrOobr4BVxPz/Lbdtz0wsWW5muiqQZNuW5XToshRtTT2RNH7mGn8d4FMeXt5VRNTEkRHRPm/qwKBgEXtGS+gCznYYhDmG110io+jwgyrZVI8Q4Aci+9dtfknttEKDOvSSSvnb2smAR0Vw+/cCesxDboPELpleLvS1hyEwANpXdgyc6cCeYEgz+7SnuC5tQH/nWnpXL/rWw6oDkeg7yEplNBx2zyd0Ftg4DysBByhmd6AoT7bnNuBwgkFAoGAVYXQYh+YgM5mKaagBZOWqwhkP4Pr8Oo44G5RaswP/O7R4ulgQ48BsaPifngek+tDTetX3nlZjogb1YtIEEJNJ1SSPsvEZGzR0cwgysp+wRjER5O+M2rvNWc3G+a4wM864eYuCq1n73xL9FqXYIJXjRlmLobejYiOqYa02bRIpQc=";
    /**支付宝公钥 注意是支付宝公钥 不是应用公钥*/
    public static String aliPayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAix4U83rjS6rT8w8njXFEU+SAYH/zCCRQc98PpUDEBBx3qY7CaJPL0QPETs1WyufqZYRSKbW0Ml9wTA/SXgOp3bJn5v78vhe2LSFtmr0gCyNJXtSDrz91XgR/oK3T5j0yy8NgOMBjdjnI2a6cpqrt3YXkc02hhJTfG+3o6f+gGw6wtU7CC0BTGoH//lk+prNerjeFQLZd7hB0ANlC5JdSfDBHtr/+gPcL7ap84nEJA1TSOCnQP8h2UYd5MAwqwyqitK3B9hEUCWI7Mp3VgI+CAGVXXnUzL74hUK26yrTczucX9bEPUUAyrlxWIUZ3OsX07KwpL1PLnKH/HYJStFG8TQIDAQAB";
    public static String FORMAT = "JSON";

    /**请求使用的编码格式,如utf-8,gbk,gb2312等*/
    public static String CHARSET = "utf-8";

    /**商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2*/
    public static String SIGN_TYPE = "RSA2";
}

 Controller:

 

/**
 * @author 码农界的小学生
 * @description:
 * @title: PayController
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 21:39
 */
@RequestMapping("/cms/alipay")
@RestController
public class PayController implements PayControllerApi {
    @Autowired
    private PayService payService;

    @Override
    @RequestMapping(value = "/pay")
    public String aliPay(@RequestParam("id")String id,
                         @RequestParam("type")String type,@RequestParam("money")String money) throws IOException {
        return payService.aliPay(id,type,money);
    }

    @Override
    @RequestMapping ("/notify")
    public void payNotice(HttpServletRequest request,HttpServletResponse response) throws Exception {
         payService.alipayNotify(request,response);
    }

}

 

 

 

Service:

 

/**
 * @author 码农界的小学生
 * @description:调用支付宝接口业务逻辑
 * @title: PayService
 * @projectName graduation-project
 * @description: TODO
 * @date 2020/4/23 21:43
 */
@Service
public class PayService {
    @Autowired
    private OrderClient orderClient;
    @Autowired
    private OrderCollectionRepository orderCollectionRepository;
    @Autowired
    private SuperRepository superRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private UserRepository userRepository;
    /**
     * 调用支付宝接口
     * @return
     */
    public String aliPay(String id,String type,String money) {
        //非法参数 抛出异常
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(type) || StringUtils.isEmpty(money)){
             ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
        AlipayClient alipayClient = new DefaultAlipayClient(AliDevPayConfig.aliPayGateWay,AliDevPayConfig.aliPayAppId,
                AliDevPayConfig.aliPayPrivateKey,AliDevPayConfig.FORMAT,AliDevPayConfig.CHARSET,AliDevPayConfig.aliPayPublicKey,
                AliDevPayConfig.SIGN_TYPE);
        //实例化具体API对应的request类
        AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
        payRequest.setNotifyUrl(AliDevPayConfig.notifyUrl);
        payRequest.setReturnUrl(AliDevPayConfig.returnUrl);
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
        AlipayTradePagePayModel payModel = new AlipayTradePagePayModel();
        //商户订单号
        UUID uuid = UUID.randomUUID();
        String uid = uuid.toString();
        payModel.setOutTradeNo(uid);
        //对一笔交易的具体描述信息。这里存储用户id
        payModel.setBody(id);
        //商品名称
        payModel.setSubject(type);
        //交易超时时间 这里的30m就是30分钟
        payModel.setTimeoutExpress("30m");
        //支付金额 后面保留2位小数点..不能超过2位
        payModel.setTotalAmount(money);
        // //电脑网站支付销售产品码,不同的支付方式productCode不同 销售产品码(固定值)
        payModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        payRequest.setBizModel(payModel);
        try {
            // 这里和普通的接口调用不同,使用的是sdkExecute
            //返回支付宝订单信息(预处理)
            AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(payRequest);
            //就是orderString 可以直接给APP请求,无需再做处理。
            String result = alipayTradePagePayResponse.getBody();
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付成功后接口回调 加上事务注解
     * @param request
     * @return
     */
    @Transactional
    public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //调用SDK签名验证
        //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AliDevPayConfig.aliPayPublicKey, AliDevPayConfig.CHARSET,AliDevPayConfig.SIGN_TYPE);
        if(signVerified){
            //商户订单号
            String uid = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            //用户id
            String userId = new String(request.getParameter("body").getBytes("ISO-8859-1"),"UTF-8");
            //健身房会员卡类型
            String type = new String(request.getParameter("subject").getBytes("ISO-8859-1"),"UTF-8");
            //金额
            String money = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
            /*
         这里编写业务逻辑 
        */

} } }

 

 

 

 

5.项目调用支付宝接口流程

前端项目调用方法请求/cms/alipay/pay ,然后跳转到支付页面,支付完成后会同步跳转returnUrl返回到商品页面。支付宝支付后会异步请求notifyUrl,这里通过花生壳内网穿透工具代理到/cms/alipay/notify,然后完成业务逻辑。

6.效果图

 

 

点击会员充值调用对应的js方法:

submitPay(item){
                if (!this.params.id){
                    this.$message.error("请先登录");
                    return ;
                }
                this.params.type = item.type;
                this.params.money = item.money;
                let querys = querystring.stringify(this.params);
                window.location ="http://www.graduation.com/cms/alipay/pay?"+querys;
            }

 

 

跳转到支付页面:

 

 

 

完成支付后自动跳转到原来页面:

 

哈哈,界面过于丑陋,咋们不要注重外表。前端页面基本上都是自己一点一点组装起来的,现在看到前端头疼,索性丑就丑点吧。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!