Java支付宝支付

Java支付宝支付

一:支付宝支付接入准备工作:

首先,支付宝支付和微信支付意愿,都是只支持企业用户,个人用户是不能接入支付宝支付的,所以要想接入支付宝支付,首先需要有支付宝的企业账号,有了企业账号才能拿到支付宝支付的所需参数,这些工作都是需要公司层面的人操作的,作为码农,只管拿到这些需要的参数就可以进行看文档,对接支付支付接口了。那支付宝支付都需要哪些参数呢,请看下面:

	// 支付宝支付参数配置 //
    @Value("${ALIPAY.APPID}")
    protected String app_id;//应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    @Value("${ALIPAY.PRIVATEKEY}")
    protected String merchant_private_key;//商户私钥,您的PKCS8格式RSA2私钥
    @Value("${ALIPAY.PUBLICKEY}")
    protected String alipay_public_key;//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    @Value("${ALIPAY.NOTIFY_URL}")
    protected String notify_url;//服务器异步通知页面路径
    @Value("${ALIPAY.RETURNA_URL}")
    protected String return_url;//页面跳转同步通知页面路径
    @Value("${ALIPAY.SIGN}")
    protected String sign_type = "RSA2";//签名方式
    protected String charset = "utf-8";//字符编码格式
    @Value("${ALIPAY.GATEWAY_URL}")
    protected String gateway_url;//支付宝网关

上面就是支付宝支付需要的各类参数,在开始写代码之前,需要先把这些参数配置好才能进行下面的工作。
二:支付宝(电脑网站支付)接口说明:
首页访问支付宝的开放平台:https://docs.open.alipay.com/270 ,然后查看快速接入文档,首先是创建应用,然后是配置密钥,最好是搭建和配置开放环境。配置好上面的各项工作,下面来看下支付宝支付的接口说明:
alipay.trade.page.pay(PC场景下单并支付)
支付流程
Java支付宝支付_第1张图片
公共参数
请求地址:

环境 HTTPS请求地址
正式环境 https://openapi.alipay.com/gateway.do

公共请求参数:
Java支付宝支付_第2张图片
请求参数
Java支付宝支付_第3张图片
Java支付宝支付_第4张图片
在这里插入图片描述
三:下载支付宝的SDK

下载地址:https://docs.open.alipay.com/270/106291/, 下载后可以导入本地,然后修改对应的配置,就可以测试支付接口了

四:安装支付宝的SDKmaven依赖

由于我们准备使用支付宝提供的SDK实现支付接口的对接,所以需要把支付宝的SDK安装到我们的本地maven仓库,安装命令如下:

mvn install:install-file -DgroupId=com.alipay.api -DartifactId=alipay-sdk-java20170324180803 -Dversion=1.0.0 -Dpackaging=jar -Dfile=D://alipay-sdk-java20170324180803.jar

安装好支付宝的SDK后,就可以在maven项目里面引用该依赖了,如下:

!--支付宝SDK-->
        
            com.alipay.api
            alipay-sdk-java20170324180803
            1.0.0
        

五:支付宝支付的核心代码

AlipayVo.java

package com.micai.springboot.vo.pay;
 
import java.io.Serializable;
 
/**
 * @Auther: Mike
 * @Date: 2018/8/30 15:14
 * @Description: 支付请求参数
 */
public class AlipayVo implements Serializable {
 
    private static final long serialVersionUID = 1L;
    /**
     * 订单名称
     */
    private String subject;
    /**
     * 商户网站唯一订单号
     */
    private String out_trade_no;
    /**
     * 该笔订单允许的最晚付款时间
     */
    private String timeout_express;
    /**
     * 付款金额
     */
    private String total_amount;
    /**
     * 销售产品码,与支付宝签约的产品码名称
     */
    private String product_code;
 
    public String getSubject() {
        return subject;
    }
 
    public void setSubject(String subject) {
        this.subject = subject;
    }
 
    public String getOut_trade_no() {
        return out_trade_no;
    }
 
    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }
 
    public String getTimeout_express() {
        return timeout_express;
    }
 
    public void setTimeout_express(String timeout_express) {
        this.timeout_express = timeout_express;
    }
 
    public String getTotal_amount() {
        return total_amount;
    }
 
    public void setTotal_amount(String total_amount) {
        this.total_amount = total_amount;
    }
 
    public String getProduct_code() {
        return product_code;
    }
 
    public void setProduct_code(String product_code) {
        this.product_code = product_code;
    }
}

PayBaseController.java

package com.micai.springboot.controller.pay;
 
import com.micai.springboot.base.BaseController;
import org.springframework.beans.factory.annotation.Value;
 
/**
 * @Auther: Mike
 * @Date: 2018/8/31 13:40
 * @Description:
 */
public abstract class PayBaseController extends BaseController {
 
    // 支付宝支付参数配置 //
    @Value("${ALIPAY.APPID}")
    protected String app_id;//应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    @Value("${ALIPAY.PRIVATEKEY}")
    protected String merchant_private_key;//商户私钥,您的PKCS8格式RSA2私钥
    @Value("${ALIPAY.PUBLICKEY}")
    protected String alipay_public_key;//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    @Value("${ALIPAY.NOTIFY_URL}")
    protected String notify_url;//服务器异步通知页面路径
    @Value("${ALIPAY.RETURNA_URL}")
    protected String return_url;//页面跳转同步通知页面路径
    @Value("${ALIPAY.SIGN}")
    protected String sign_type = "RSA2";//签名方式
    protected String charset = "utf-8";//字符编码格式
    @Value("${ALIPAY.GATEWAY_URL}")
    protected String gateway_url;//支付宝网关
 
    // 微信支付参数配置 //
    @Value("${WXPAY.APPID}")
    protected String APPID;//公众账号ID
    @Value("${WXPAY.MCHID}")
    protected String MCHID;//微信支付商户号
    @Value("${WXPAY.KEY}")
    protected String KEY;//API密钥
    @Value("${WXPAY.APPSECRET}")
    protected String APPSECRET;//AppSecret是APPID对应的接口密码
    @Value("${WXPAY.NOTIFY_URL}")
    protected String NOTIFY_URL;//回调地址。测试回调必须保证外网能访问到此地址
    @Value("${WXPAY.CREATE_IP}")
    protected String CREATE_IP;//发起请求的电脑IP
 
}

AlipayController.java

package com.micai.springboot.controller.pay;
 
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.AlipayTradePagePayRequest;
import com.google.gson.Gson;
import com.micai.springboot.vo.pay.AlipayVo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
 
/**
 * @Auther: Mike
 * @Date: 2018/8/30 15:11
 * @Description: 支付宝后台接口
 */
@RestController
@RequestMapping(value = "/alipay")
public class AlipayController extends PayBaseController {
 
    /**
     * 支付网站扫码支付接口-统一下单支付接口
     * @return
     * @throws AlipayApiException
     */
    @GetMapping("/pay")
    private String alipayPay() throws AlipayApiException {
        //这个应该是从前端端传过来的,这里为了测试就从后台写死了
        AlipayVo vo = new AlipayVo();
        vo.setOut_trade_no(UUID.randomUUID().toString().replace("-", ""));
        vo.setTotal_amount("0.01");
        vo.setSubject("nelson-test-title");
        vo.setProduct_code("FAST_INSTANT_TRADE_PAY"); //这个是固定的
        String json = new Gson().toJson(vo);
        logger.info("json: {}", json);
 
        AlipayClient alipayClient = new DefaultAlipayClient(gateway_url, app_id, merchant_private_key, "json",charset,alipay_public_key,sign_type);
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(return_url);
        alipayRequest.setNotifyUrl(notify_url);
        alipayRequest.setBizContent(json);
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        logger.info("result: {}", result);
        return result; //这里生成一个表单,会自动提交
    }
 
    /**
     * 支付宝服务器异步通知页面
     * @param request
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易凭证号
     * @param trade_status 交易状态
     * @return
     * @throws AlipayApiException
     */
    @PostMapping("/notify")
    public String alipayNotify(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status) throws AlipayApiException {
        Map params = getParamsMap(request);
        logger.info("notify params: {}", JSONObject.toJSON(params));
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset, sign_type);
        logger.info("notify signVerified: {}", signVerified);
        if (signVerified) {
            //处理你的业务逻辑,更细订单状态等
            return ("success");
        } else {
            logger.info("验证失败,不去更新状态");
            return ("fail");
        }
    }
 
    /**
     * 支付宝服务器同步通知页面
     * @param request
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易凭证号
     * @param total_amount 交易状态
     * @return
     * @throws AlipayApiException
     */
    @GetMapping("/return")
    public String alipayReturn(HttpServletRequest request, String out_trade_no,String trade_no,String total_amount) throws AlipayApiException {
        Map params = getParamsMap(request);
        logger.info("return params: {}", JSONObject.toJSON(params));
 
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, charset, sign_type);
        logger.info("return signVerified: {}", signVerified);
 
        if (signVerified) {
            return ("success");
        } else {
            logger.info("验证失败,不去更新状态");
            return ("fail");
        }
    }
 
    private Map getParamsMap(HttpServletRequest request) {
        Map params = new HashMap<>();
        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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
            try {
                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return params;
    }
 
}

六:运行支付宝支付URL:http://dvnq2b.natappfree.cc/alipay/pay, 返回如下支付二维码页面:

Java支付宝支付_第5张图片
Java支付宝支付_第6张图片
Java支付宝支付_第7张图片
支付宝回调日志如下,其中包括了同步回调和异步回调:

Java支付宝支付_第8张图片

七:总结:

经过上面的所以流程,相信大家都明白了支付宝支付的流程,这里我们对上面的流程做个总结,要想接入支付宝支付,必须是企业用户才行,个人用户不支持,所以在开始写代码之前,要和公司的相关负责人申请好支付宝支付的相关配置参数,有了这些才能进行下面的工作,这里最重要的一点就是支付宝支付的回调了,回调,在生产环境必须配置可以外网访问的URL,同时域名必须是备案过的,二级域名也可以,这里我们为了方便测试,所以就使用了内网穿透工具natapp,该工具既有免费通道也有收费通道,收费通道也很便宜,如果只是测试,免费通道就够用了,另外还有一点要注意,就是支付宝支付的回调,默认支付宝是回调多次的,所以会有重复回调的问题,这里留给大家一个思考,怎么防止支付宝的多次回调,以免影响业务,希望有兴趣的小伙伴可以留言交流。以上就是支付宝支付(电脑网站支付)的全部内容了

你可能感兴趣的:(支付宝)