对接支付宝App支付和网页支付接口详解

之前在项目中使用过支付宝的沙箱测试支付和实际开发支付,是关于App对接支付宝接口的,由于前段时间有朋友询问怎么对接网页支付,通过研究支付包的开发文档,在这里总结一下对接支付宝的App支付接口和网页支付接口的具体细节。

前期准备
要先注册一个支付宝企业账号,获取appid,在支付宝平台获取支付宝公钥和自己的公钥与私钥,这些准备工作就不再这里具体操作

项目具体实现
1.搭建springboot项目框架
2.引入支付宝支付的sdk

 
            com.alipay.sdk
            alipay-sdk-java
            3.0.0
        

3.创建支付宝配置文件pay.properties

#支付宝的支付网关
alipay_url=https://openapi.alipay.com/gateway.do
#商家appid,我们注册账号所得到的appid
app_id=XXXXXXX
#商家我们自己的私钥
app_private_key=这里是我们在支付宝开发平台生成的自己的私钥

#支付宝的公钥
alipay_public_key=我们在支付宝开发平台获取的支付宝公钥

# 同步回调地址 重定向地址本地浏览器,用户支付完之后,支付宝回调我们的接口,一定要加http获取https的完整路径,并且不能带参数
return_payment_url=http://localhost:8011/pay/ret

# 异步通知地址 公网接口(webService)
notify_payment_url=http://60.205.215.91/alipay/callback/notify

4.创建支付配置文件,生成支付客户端bean

package com.pay.config;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
 * @param
 * @return
 */
@Configuration
@PropertySource("classpath:alipay.properties")
public class AlipayConfig {
    @Value("${alipay_url}")
    private String alipay_url;
    @Value("${app_private_key}")
    private String app_private_key;
    @Value("${app_id}")
    private String app_id;
    //返回的数据格式
    public final static String format = "json";
    //使用的编码方式
    public final static String charset = "utf-8";
    //签名的加密算法
    public final static String sign_type = "RSA2";
    public static String return_payment_url;
    public static String notify_payment_url;
    public static String alipay_public_key;

    @Value("${alipay_public_key}")
    public void setAlipay_public_key(String alipay_public_key) {
        AlipayConfig.alipay_public_key = alipay_public_key;
    }

    @Value("${return_payment_url}")
    public void setReturn_url(String return_payment_url) {
        AlipayConfig.return_payment_url = return_payment_url;
    }

    @Value("${notify_payment_url}")
    public void setNotify_url(String notify_payment_url) {
        AlipayConfig.notify_payment_url = notify_payment_url;
    }

/**
*生成的客户端bean
**/
    @Bean
    public AlipayClient alipayClient() {
        AlipayClient alipayClient = new DefaultAlipayClient(alipay_url, app_id, app_private_key, format, charset, alipay_public_key, sign_type);
        return alipayClient;
    }
}

5.下面就是就是我们要具体的实现支付宝支付的具体细节,也是最重要的部分,一定要每步都要自己看
(1).网页对接支付宝支付

@RestController
public class PayController {

    @Autowired
    AlipayClient alipayClient;

    /**
     * @Author yyk
     * @Description //TODO 支付成功后的异步回调函数
     * @Date 2020/6/3 0:13
     * @Param [request, modelMap]
     * @return java.lang.String
     **/
    @RequestMapping("pay/return")
    public String reCall(HttpServletRequest request){
        // 回调请求中获取支付宝参数
        String sign = request.getParameter("sign");
        String trade_no = request.getParameter("trade_no");
        String out_trade_no = request.getParameter("out_trade_no");
        String trade_status = request.getParameter("trade_status");
        String total_amount = request.getParameter("total_amount");
        String subject = request.getParameter("subject");
        String call_back_content = request.getQueryString();

        // 通过支付宝的paramsMap进行签名验证,2.0版本的接口将paramsMap参数去掉了,导致同步请求没法验签
        if(sign!=null){
            // 验签成功
            System.out.println("验签成功");
		//做具体的业务请求
        }

        return "succsee";
    }

/**
     * @Author yyk
     * @Description //TODO 请求支付接口
     * @Date 2020/6/3 0:06
     * @Param [request]
     * @return java.lang.String
     **/
    @RequestMapping("alipay/pay")
    public String alipay(HttpServletRequest request){

        String form="";
        //获取一个支付宝客户端
        AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
        //把回调函数也放入里面
       alipayTradePagePayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        alipayTradePagePayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);
        Map map = new HashMap<>();
        //商户网站唯一订单号
        map.put("out_trade_no","1A4566776576");
        //销售产品码,商家和支付宝签约的产品码,注:目前仅支持FAST_INSTANT_TRADE_PAY
        map.put("product_code","FAST_INSTANT_TRADE_PAY");
        //订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]。(,这里要与微信支付区分,微信支付单位为分)
        map.put("total_amount",0.01);
        //商品的标题/交易标题/订单标题/订单关键字等。
        map.put("subject","XXXXX");
        String param = JSON.toJSONString(map);
		//biz_content,请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
		//下面我会具体介绍哪些是公共参数,哪些是请求参数
        alipayTradePagePayRequest.setBizContent(param);
   
        try {
        //最核心内容,其实跟App对接的区别也在这里,返回的是一个form表单支付成功后会跳到这个页面
             form = alipayClient.execute(alipayTradePagePayRequest).getBody();
            System.out.println(form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }
}

当执行完alipay/pay支付接口时会出现下面的页面,支付之后,会回调pay/return接口,同时调用异步接口,这里没有写。在同步回调接口中2.0版本以后不再进行验签,但是异步回调一定要验签。并且异步回调返回给支付宝的结果一定是sucess
注意:异步接口必须是公网能访问的
对接支付宝App支付和网页支付接口详解_第1张图片
请求时的公共参数和请求参数
公共参数就是我们在AlipayConfig类中配置的那些属性值
请求参数是我们在controller中传入到biz_content中的参数
具体参数请参考支付宝开发文档
https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay#%E5%85%AC%E5%85%B1%E5%8F%82%E6%95%B0

(2).对接App接口

  /**
     * @Author yyk
     * @Description //TODO 请求app支付接口
     * @Date 2020/6/3 0:36
     * @Param []
     * @return java.lang.String
     **/
    @RequestMapping("/app")
    public String appAlipay(HttpServletRequest request){
 
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay,这里和网页接口是由区别的
        **AlipayTradeAppPayRequest aliPayRequest = new AlipayTradeAppPayRequest();**
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setSubject(subject);
        model.setOutTradeNo("q23er56gg");
        model.setTimeoutExpress("30m");
        model.setTotalAmount(String.valueOf(orderPrice));// 单位:元
        model.setProductCode("QUICK_MSECURITY_PAY");
        aliPayRequest.setBizModel(model);
        //回调接口
        aliPayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        aliPayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(aliPayRequest);
            //把这个返回给前端,然后前端调支付宝接口
            String body1 = response.getBody();
            return body1;
        } catch (AlipayApiException e) {
            //e.printStackTrace();
           return null;
        }



 /**
     * @Author yyk
     * @Description //TODO 支付成功后的异步回调函数
     * @Date 2020/6/3 0:13
     * @Param [request, modelMap]
     * @return java.lang.String
     **/
    @RequestMapping("pay/return")
    public String reCall(HttpServletRequest request){
        // 回调请求中获取支付宝参数
        String sign = request.getParameter("sign");
        String trade_no = request.getParameter("trade_no");
        String out_trade_no = request.getParameter("out_trade_no");
        String trade_status = request.getParameter("trade_status");
        String total_amount = request.getParameter("total_amount");
        String subject = request.getParameter("subject");
        String call_back_content = request.getQueryString();


        //AlipaySignature.rsaCheck();
        // 通过支付宝的paramsMap进行签名验证,2.0版本的接口将paramsMap参数去掉了,导致同步请求没法验签
        boolean signVerified = false;
       try {
            //3.1调用SDK验证签名,params是我们获取的参数,alipayPublicKey是支付宝公钥
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.setAlipay_public_key,
                    "UTF-8", "RSA2");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
if(signVerified ){
system.out.println("验签通过");
}
        return "调用succsee";
    }
    }

你可能感兴趣的:(java,接口)