第一部分:如何接入支付宝支付(2019年6月)

背景:突然有一个整合支付宝、微信、银联三种支付方式在一个接口下,通过简单的配置即可实现支付的想法。故,想不如做,马上动手搞一下并做记录。首先了解一下支付宝。

一、准备工作(沙箱模式):

1、注册蚂蚁开放平台——点击研发服务

2、生成公钥、秘钥,查看APPID

3、安卓手机下载沙箱版支付宝

4、在此查看,沙箱支付宝用到的账号和密码

二、代码阶段(此处是我任意找到的一个项目,将代码集成进去的。关于代码逻辑,注释已经写得很清楚了自己看,不做赘述),直接上代码:

1、代码结构:

2、pom文件配置

<!--支付宝-->
 <dependency>
     <groupId>com.alipay.sdk</groupId>
     <artifactId>alipay-sdk-java</artifactId>
     <version>3.1.0</version>
 </dependency>
 <!--支付宝--><!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
 <dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>2.8.2</version>
 </dependency>
<!-- 使用注释处理器生成自己的元数据-->
 <dependency>
     <groupId>org.springframework.boot </groupId>
     <artifactId>spring-boot-configuration-processor</artifactId>
     <optional>true</optional>
 </dependency>

3、新建并配置alipay.properties

#需要配置,支付宝私钥(生产环境和沙箱环境生成方式稍微有点差别)
ALIPAY.PRIVATEKEY=你生成的应用私钥
#需要配置,支付宝公钥(生产环境和沙箱环境生成方式稍微有点差别)
ALIPAY.PUBLICKEY=你生成的应用公钥
#支付宝解签公钥(这个需要注意一下)
ALIPAY.RETURNPUBLICKEY=支付宝公钥(如果找不到,请看本教程“准备工作——第2步”)
#支付宝应用APPID
ALIPAY.APPID=你的应用APPID
#支付宝正式网关
#ALIPAY.SERVER=https://openapi.alipay.com/gateway.do
#支付宝沙箱网关
ALIPAY.SERVER=https://openapi.alipaydev.com/gateway.do
#公网可以访问的地址
ALIPAY.NOTIFY_URL=http://localhost:8080/pay/notify
#公网可以访问的地址
ALIPAY.RETURNA_URL=http://localhost:8080/pay/notify
ALIPAY.SIGN=RSA2

4、AlipayConfig.java的代码

package com.jiao.tangtang.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = {"classpath:alipay.properties"})
@ConfigurationProperties
public class AlipayConfig {

    @Value("${ALIPAY.APPID}")
    private String alipay_app_id;
    @Value("${ALIPAY.PRIVATEKEY}")
    private String merchant_private_key;
    @Value("${ALIPAY.PUBLICKEY}")
    private String alipay_public_key;
    @Value("${ALIPAY.RETURNPUBLICKEY}")
    private String alipay_return_public_key;
    @Value("${ALIPAY.NOTIFY_URL}")
    private String alipay_notify_url;

    @Value("${ALIPAY.RETURNA_URL}")
    private String return_url;

    @Value("${ALIPAY.SIGN}")
    private String sign_type;
//    private String charset = "utf-8";

    @Value("${ALIPAY.SERVER}")
    private String gatewayUrL;

    public String getAlipay_app_id() {
        return alipay_app_id;
    }

    public void setAlipay_app_id(String alipay_app_id) {
        this.alipay_app_id = alipay_app_id;
    }

    public String getMerchant_private_key() {
        return merchant_private_key;
    }

    public void setMerchant_private_key(String merchant_private_key) {
        this.merchant_private_key = merchant_private_key;
    }

    public String getAlipay_public_key() {
        return alipay_public_key;
    }

    public void setAlipay_public_key(String alipay_public_key) {
        this.alipay_public_key = alipay_public_key;
    }

    public String getAlipay_return_public_key() {
        return alipay_return_public_key;
    }

    public void setAlipay_return_public_key(String alipay_return_public_key) {
        this.alipay_return_public_key = alipay_return_public_key;
    }

    public String getAlipay_notify_url() {
        return alipay_notify_url;
    }

    public void setAlipay_notify_url(String alipay_notify_url) {
        this.alipay_notify_url = alipay_notify_url;
    }

    public String getReturn_url() {
        return return_url;
    }

    public void setReturn_url(String return_url) {
        this.return_url = return_url;
    }

    public String getSign_type() {
        return sign_type;
    }

    public void setSign_type(String sign_type) {
        this.sign_type = sign_type;
    }

    public String getGatewayUrL() {
        return gatewayUrL;
    }

    public void setGatewayUrL(String gatewayUrL) {
        this.gatewayUrL = gatewayUrL;
    }
}

5、AlipayVo.java

package com.jiao.tangtang.entity;
import java.io.Serializable;

public class AlipayVo implements Serializable {

    // 订单名称
    private String subject;
    //商户网站唯一订单号
    private String out_trade_no;
    //该笔订单允许的最晚付款时间
    private String timeout_express;
    //付款金额
    private String total_amount;
    //销售产品码,与支付宝签约的产品码名称
    private String product_code;
    //订单描述
    private String body;


    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;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

6、AlipayController.java

package com.jiao.tangtang.controller;
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.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.google.gson.Gson;
import com.jiao.tangtang.entity.AlipayVo;
import com.jiao.tangtang.common.config.AlipayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller()
@RequestMapping("pay")
public class AlipayController {

    @Autowired
    private AlipayConfig aliPayConfig;

    @RequestMapping("/alipayWeb")
    @ResponseBody
    private String alipaytest(String orderid, String totalAmount, String subject, String body) throws AlipayApiException {

        AlipayVo vo = new AlipayVo();
        //订单号
        vo.setOut_trade_no(orderid);
        //支付金额
        vo.setTotal_amount(totalAmount);
        //商品名称
        vo.setSubject(subject);
        //商品描述
        vo.setBody(body);
        vo.setProduct_code("FAST_INSTANT_TRADE_PAY"); //这个是固定的
        String json = new Gson().toJson(vo);

        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrL()
                , aliPayConfig.getAlipay_app_id(), aliPayConfig.getMerchant_private_key()
                , "json", "UTF-8", aliPayConfig.getAlipay_public_key()
                , aliPayConfig.getSign_type());
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(aliPayConfig.getReturn_url());
        //设置支付宝可访问外网URL
        alipayRequest.setNotifyUrl(aliPayConfig.getAlipay_notify_url());
        alipayRequest.setBizContent(json);
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result; //这里生成一个表单,会自动提交
    }

    @RequestMapping("/notify")
    @ResponseBody
    private String alipayNotify(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status)
            throws AlipayApiException {
        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }
        // 买家付款账号
//        String buyer_logon_id = map.get("buyer_logon_id");
        // 交易状态
//    trade_status = map.get("trade_status");
        // 商户订单号
        // out_trade_no = map.get("out_trade_no");
        // 支付宝交易号
//        trade_no = map.get("trade_no");
        //商户编号
//        String stord_id = map.get("body");
        //充值硬币
//        Integer coin_num = Integer.parseInt(map.get("passback_params"));
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map,aliPayConfig.getAlipay_return_public_key(),
                    "UTF-8",aliPayConfig.getSign_type());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ("fail");// 验签发生异常,则直接返回失败
        }
        if (signVerified) {
            // TODO
            //处理你的业务逻辑,更细订单状态等
            System.out.println("****************处理业务逻辑,更细订单状态****************");

            return ("success");
        } else {
            return ("fail");
        }
    }

    @RequestMapping("/return")
    @ResponseBody
    private Map<String, Object> paymentresult(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status)
            throws AlipayApiException {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }

        // 买家付款账号
//        String buyer_logon_id = map.get("buyer_logon_id");
        // 交易状态
//    trade_status = map.get("trade_status");
        // 商户订单号
        // out_trade_no = map.get("out_trade_no");
        // 支付宝交易号
//        trade_no = map.get("trade_no");
        //商户编号
//        String stord_id = map.get("body");
        //充值硬币
//        Integer coin_num = Integer.parseInt(map.get("passback_params"));
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map, aliPayConfig.getAlipay_return_public_key(),
                    "UTF-8", aliPayConfig.getSign_type());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            resultMap.put("1", "验签发生异常");
            return resultMap;// 验签发生异常,则直接返回失败
        }
        if (signVerified) {
            // TODO
            //处理你的业务逻辑,更细订单状态等
            resultMap.put("0", "处理成功!");
            return resultMap;
        } else {
            resultMap.put("1", "验证失败,不去更新状态!");
            return resultMap;
        }
    }

    @RequestMapping("/alipayAndroid")
    @ResponseBody
    public Map<String,Object> getAliPayOrderStr(AlipayVo tOrder) {
        Map<String, Object> resultMap = new HashMap<>();
        //最终返回加签之后的,app需要传给支付宝app的订单信息字符串
        System.out.println("==================支付宝下单,商户订单号为:" + tOrder.getOut_trade_no());
        try {
            //实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
            AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrL()
                    , aliPayConfig.getAlipay_app_id(), aliPayConfig.getMerchant_private_key()
                    , "json", "UTF-8", aliPayConfig.getAlipay_public_key()
                    , aliPayConfig.getSign_type());
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
            AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            //业务参数传入,可以传很多,参考API
            //model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用参数(附加数据)
            model.setBody(tOrder.getBody());                       //对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
            model.setSubject(tOrder.getSubject());                 //商品名称
            model.setOutTradeNo(tOrder.getOut_trade_no());           //商户订单号(自动生成)
            // model.setTimeoutExpress("30m");                 //交易超时时间
            model.setTotalAmount(tOrder.getTotal_amount());         //支付金额
            model.setProductCode("QUICK_MSECURITY_PAY");              //销售产品码(固定值)
            ali_request.setBizModel(model);
            ali_request.setNotifyUrl(aliPayConfig.getAlipay_notify_url());        //异步回调地址(后台)
            ali_request.setReturnUrl(aliPayConfig.getReturn_url());        //同步回调地址(APP)
            // 这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request); //返回支付宝订单信息(预处理)
            String orderString = alipayTradeAppPayResponse.getBody();//就是orderString 可以直接给APP请求,无需再做处理。
            resultMap.put("0", "加签成功!");
            resultMap.put("data", orderString);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            resultMap.put("1", "与支付宝交互出错,未能生成订单,请检查代码!");
            resultMap.put("data", null);
        }
        return resultMap;
    }
}

三、至此代码就结束了,那么测试该怎么办呢:

1、直接调用AlipayController中的方法,最简单的方式就是,

例如:localhost:8080/pay/alipayWeb?orderid=参数1&totalAmount=参数2&subject=参数3&body=参数4(参数为alipaytest方法中需要传的参),

执行这个方法后,会生成支付二维码。

2、使用沙箱支付宝,扫码支付

四、那么正式环境该怎么办呢:

1、首先需要在开放平台中进行创建,然后等着审核通过

2、审核通过后,在你的应用上配置好对应的公钥,查看自己的APPID,最后修改掉alipay.properties配置文件中对应的内容,就可以了,当然正式的还是不太一样的,这个在调试的过程中就会发现。

至此就全部结束了。

转载于:https://my.oschina.net/jhy168/blog/3067386

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值