java服务端开发支付宝支付接口,网页支付与app支付

s

前言

在开发的过程中,不可避免的都需要使用支付功能,本文档主要给大家分享,自己的一次支付宝开发时的经历.支付宝开发,对于个人开发者而言相对于其他支付来说相对比较友好,因为有沙箱环境支持我们在开发阶段测试使用,话不多说,接下来就介绍开发过程

注册成为开发者
  • 官网地址: https://open.alipay.com/platform/home.htm
  • 使用支付宝登录即可
  • 找到沙箱环境
  • 在这里插入图片描述
配置沙箱环境
  • 官方参考文档:https://opendocs.alipay.com/open/200/105311

  • 沙箱环境配置首页:https://openhome.alipay.com/platform/appDaily.htm 需要登陆后方可进入

  • 具体配置步骤:

    • 设置秘钥

      • (参考链接:https://opendocs.alipay.com/open/291/105971)根据文档生成秘钥对
      • 将生成的秘钥中的公钥设置到下方的参数中

    在这里插入图片描述

在这里插入图片描述

- 这时我们也能看到支付宝的公钥,回头我们要在配置文件中使用
  • 获取 APPID

  • 下载沙箱app环境

  • 登录账号:支付宝为我们提供了商家账号和卖家账号,也可以设置账户余额(突然感觉自己变有钱了)

  • 在这里插入图片描述

到此时我们的沙箱以及沙箱App环境已经准备好了,接下来我们将要编写java后台代码

支付代码
准备工作
  • 创建springboot项目

  • 引入依赖

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!--  支付宝依赖 https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
            <dependency>
                <groupId>com.alipay.sdk</groupId>
                <artifactId>alipay-sdk-java</artifactId>
                <version>4.10.140.ALL</version>
            </dependency>
            <!--常用工具类 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
            </dependency>
    
  • 设定服务端口:我设置的为8089,大家可以随意设定,也可以不进行配置,默认80

  • 创建配置类AliPayConfig,配置属性参数

    /**
     * AliPayConfig
     *
     * @author cmm
     * @date 2020/10/29 9:48
     */
    public class AliPayConfig {
    
    //部分参数这里并没有设定,具体开发时大家可以根据需求自己设定
    	/*  
    	//当面付最大查询次数和查询间隔(毫秒)
        max_query_retry = 5
        query_duration = 5000
    
        //当面付最大撤销次数和撤销间隔(毫秒)
        max_cancel_retry = 3
        cancel_duration = 2000
    
        //交易保障线程第一次调度延迟和调度间隔(秒)
        heartbeat_delay = 5
        heartbeat_duration = 900
        */
        /**
         * 支付宝网关名
         */
        //private static String openApiDomain = "https://openapi.alipay.com/gateway.do"; 正式环境
        public static String openApiDomain = "https://openapi.alipaydev.com/gateway.do"; //开发环境
        /**
         * appid 沙箱环境处可以找到我们的APPID
         */
        public static String appId = "自己的APPID";
        /**
         * 应用私钥
         */
        public static String privateKey = "自己配置沙箱环境秘钥时生成的密钥对中的私钥";
        /**
         * 应用公钥
         */
        public static String publicKey ="自己配置沙箱环境秘钥时生成的密钥对中的公钥";
    
        /**
         * 支付宝公钥
         */
        public static String alipayPublicKey = "配置沙箱秘钥时显示的支付宝公钥";
        /**
         * 签名类型
         */
        public static String signType = "RSA2";
    
    }
    
    
网页支付代码

package com.cmm.alipay.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.cmm.alipay.config.AliPayConfig;
import com.cmm.alipay.config.DateUtils;
import com.cmm.alipay.config.HttpsUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * AliPayController
 *
 * @author cmm
 * @date 2020/10/29 10:01
 */
@RestController
@RequestMapping("/alipay")
public class AliPayController {
    /**创建请求客户端*/
    private static AlipayClient alipayClient;
    static {
        //静态初始化请求客户端,补充加载配置文件中的参数
        alipayClient = new DefaultAlipayClient(AliPayConfig.openApiDomain,AliPayConfig.appId,
                AliPayConfig.privateKey,"JSON","UTF-8",AliPayConfig.alipayPublicKey,AliPayConfig.signType);
    }

    /**
     * 网页支付创建并下单接口
     * 参考API文档链接:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay
     * 本接口商品信息没有填写,具体参数参考api接口根据需求自由补充即可
     * @param response
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping("/pay")
    public void aliPay(HttpServletResponse response) throws AlipayApiException, IOException {

        //网页支付页面所需要的请求类
        AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
        //创建请求参数
        Map<String, Object> mapParams = new HashMap<>();
        //设置异步回调地址(此地址一般为支付成功后调用该地址处理服务逻辑)
        alipayTradePagePayRequest.setNotifyUrl("http://alipay.free.idcfengye.com/alipay/notify");//自己服务的接口地址,要求外网可以访问
        //设置同步回调地址,这里我跳转了页面
        alipayTradePagePayRequest.setReturnUrl("http://alipay.free.idcfengye.com/paySuccess.html");//自己服务的接口地址,要求外网可以访问
        //设置订单编号(商家端,即后台要保证订单编号唯一)
        mapParams.put("out_trade_no",System.currentTimeMillis());
        //销售产品码
        mapParams.put("product_code","FAST_INSTANT_TRADE_PAY");
        //设置商品标题
        mapParams.put("subject","Iphone111");
        //设置商品金额(必须保证小数点后两位,例如88应为88.00)
        mapParams.put("total_amount",18+".88");
        //设置跳转模式
        /**
         * 跳转模式。
         * 前置模式是将二维码前置到商户
         * 的订单确认页的模式。需要商户在
         * 自己的页面中以 iframe 方式请求
         * 支付宝页面。具体分为以下几种:
         * 0:订单码-简约前置模式,对应 iframe 宽度不能小于600px,高度不能小于300px;
         * 1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于600px;
         * 3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于75px;
         * 4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小。
         *
         * 跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。
         * 2:订单码-跳转模式
         */
        mapParams.put("qr_pay_mode","4");
        //设置超时时间
        String dateStr = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", DateUtils.addMinutes(DateUtils.getNowDate(), 3));
        mapParams.put("time_expire",dateStr);
        //额外参数,等其他参数参考该接口的api文档根据需求设计即可
        //将参数转为json串
        String s = JSONObject.toJSONString(mapParams);
        //设置请求参数
        alipayTradePagePayRequest.setBizContent(s);
        //发送请求获取页面信息
        AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(alipayTradePagePayRequest);
        //获取body中的信息
        String body = alipayTradePagePayResponse.getBody();
        System.out.println(body);
        //以页面的形式响应信息
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(body);
        response.getWriter().flush();
        response.getWriter().close();

    }


    @RequestMapping("/notify")
    public String notify(HttpServletRequest request)  {
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        System.out.println("支付完成进入异步通知");
        String out_trade_no= paramsMap.get("out_trade_no");
        String trade_status= paramsMap.get("trade_status");
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AliPayConfig.alipayPublicKey, "UTF-8", AliPayConfig.signType);
            //无论同步异步都要验证签名
            if(signVerified){
                if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
                    //处理自己系统的业务逻辑,如:将支付记录状态改为成功,需要返回一个字符串success告知支付宝服务器

                    return "异步 success";
                } else {
                    //支付失败不处理业务逻辑
                    return "failure";
                }
            }else {
                //签名验证失败不处理业务逻辑
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }
    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }
    @RequestMapping("/query")
    public void query(HttpServletResponse response) throws AlipayApiException, IOException {

        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();

        Map<String, Object> mapParams = new HashMap<>();
        //设置订单编号
        mapParams.put("trade_no","2020102922001475080500830170");
        String s = JSONObject.toJSONString(mapParams);
        alipayTradeQueryRequest.setBizContent(s);
        AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.pageExecute(alipayTradeQueryRequest);
        String body = alipayTradeQueryResponse.getBody();
        System.out.println(body);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(body);
        response.getWriter().flush();
        response.getWriter().close();
        //2088102180871897
        //

    }

    /**
     * 退款接口
     * @param response
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping("/refund")
    public void refund(HttpServletResponse response) throws Exception {
        AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();

        Map<String, Object> mapParams = new HashMap<>();
        //设置订单编号
        mapParams.put("trade_no","2020102922001475080500830170");
        mapParams.put("out_request_no","ABCDEF");
        mapParams.put("refund_amount","20.00");
        mapParams.put("refund_reason","正常退款");
        String s = JSONObject.toJSONString(mapParams);
        alipayTradeRefundRequest.setBizContent(s);
        AlipayTradeRefundResponse alipayTradeRefundResponse = alipayClient.pageExecute(alipayTradeRefundRequest, "GET");

        boolean success = alipayTradeRefundResponse.isSuccess();
        if(success){
            String body = alipayTradeRefundResponse.getBody();
            System.out.println(body);
            String s1 = HttpsUtils.get(body, null, null);
            System.out.println(s1);
        }
        /**/
        //2088102180871897
        //
    }
    
}

app支付
  • 下载app支付测试工具:https://openclub.alipay.com/club/history/read/7695

在这里插入图片描述

  • 参考api地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay

-在这里插入图片描述

  • 服务端代码

    package com.cmm.alipay.controller;
    
    import com.alibaba.fastjson.JSONObject;
    import com.alipay.api.AlipayApiException;
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.domain.AlipayTradeAppPayModel;
    import com.alipay.api.domain.AlipayTradePayModel;
    import com.alipay.api.internal.util.AlipaySignature;
    import com.alipay.api.request.*;
    import com.alipay.api.response.*;
    import com.cmm.alipay.config.AliPayConfig;
    import com.cmm.alipay.config.DateUtils;
    import com.cmm.alipay.config.HttpsUtils;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Path;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /**
     * AliPayController
     *
     * @author cmm
     * @date 2020/10/29 10:01
     */
    @RestController
    @RequestMapping("/aliapp")
    public class AliPayAppController {
        private static AlipayClient alipayClient;
        static {
            alipayClient = new DefaultAlipayClient(AliPayConfig.openApiDomain,AliPayConfig.appId,
                    AliPayConfig.privateKey,"JSON","UTF-8",AliPayConfig.alipayPublicKey,AliPayConfig.signType);
        }
       @RequestMapping("/pay")
        public String aliPay(HttpServletResponse response) throws AlipayApiException, IOException {
    
            AlipayTradeAppPayRequest alipayTradeAppPayRequest = new AlipayTradeAppPayRequest();
    
            Map<String, Object> mapParams = new HashMap<>();
            alipayTradeAppPayRequest.setNotifyUrl("http://alipay.free.idcfengye.com/aliapp/notify");
            alipayTradeAppPayRequest.setReturnUrl("http://alipay.free.idcfengye.com/paySuccess.html");
            //设置订单编号
            mapParams.put("out_trade_no",System.currentTimeMillis());
            mapParams.put("timeout_express","30m");
            //设置支付类型
            mapParams.put("subject","app商品");
            mapParams.put("total_amount",18+".88");
            //设置超时时间
            String dateStr = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", DateUtils.addMinutes(DateUtils.getNowDate(), 3));
            mapParams.put("time_expire",dateStr);
            String s = JSONObject.toJSONString(mapParams);
            alipayTradeAppPayRequest.setBizContent(s);
            AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(alipayTradeAppPayRequest);
            String body = alipayTradeAppPayResponse.getBody();
            System.out.println(body);
            return body;
        }
    }
    
  • 调用接口响应如下:

    alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2016102400750511&biz_content=%7B%22time_expire%22%3A%222020-11-04+23%3A04%3A19%22%2C%22out_trade_no%22%3A1604502079233%2C%22total_amount%22%3A%2218.88%22%2C%22subject%22%3A%22app%E5%95%86%E5%93%81%22%2C%22timeout_express%22%3A%2230m%22%7D&charset=UTF-8&format=JSON&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Falipay.free.idcfengye.com%2Faliapp%2Fnotify&return_url=http%3A%2F%2Falipay.free.idcfengye.com%2FpaySuccess.html&sign=khruIxseoHq0XT72mcASv16Mp80BaIL5npE%2FkPAjueZN16FKT8Xzw4cTRfMezGtX2zsGKNI1dcGNdkbxfPbyC0WNu55J0JYhRrAtXAuy9OCcFYFzQF1QJNoYCfm7AnowfxiDDDfb4lwfpI3NCJIoCMce%2BwG3SAVnw5956Dm7cvakcfyDwo3WdGU9KhD1QZIm1JOTtdNQ25cuGsnhPPuf7xRs%2FTHxbLpXEwv1jlF0r0KgrCmXn8Q9rC8gCvmsykjjX0qQ%2F4YfmobChAC7zwi0UUMN9ClBZ11oBCu4MLpkxef8qxskncbfNT0DUnypGVi5cu2PSvdATIPxlf0Bt%2BnonA%3D%3D&sign_type=RSA2×tamp=2020-11-04+23%3A01%3A19&version=1.0
    
  • 见上面响应的字符串拷贝到测试客户端中

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

至此,简单的支付宝支付功能已经完成,关于退款,查询及异步通知等功能,大家可以参考官方

[api文档]: https://opendocs.alipay.com/apis/api_1

如有其它问题也可留言询问!
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值