支付宝支付-电脑网站支付

官方文档

支付接口(alipay.trade.page.pay):

  1. 商户系统请求支付宝接口alipay.trade.page.pay,支付宝对商户请求参数进行校验,而后重定向至用户登录页面。
  2. 用户确认支付后,支付宝get请求returnUrl(商户入参传入),返回同步返回参数。
    交易成功后,支付宝post请求notifyUrl(商户入参传入),返回异步通知参数。
  3. 若由于网络等问题异步通知没有到达,商户可自行调用alipay.trade.query接口进行查询,根据查询接口获取交易以及支付信息(商户也可以直接调用查询接口,不需要依赖异步通知)。

电脑网站支付和微信支付模式二很有相似点:微信支付-模式二,只是最后一步的处理有点小差别

代码编写(可参考官方demo:支付宝SDK、demo下载)

  • 首先下载sdk导入项目(此步骤省略)
  • 注入支付宝sdk到Spring
    引入阿里配置:pay.properties
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>/WEB-INF/config/application.properties</value>
        <value>/WEB-INF/config/qqconnectconfig.properties</value>
        <value>/WEB-INF/config/pay.properties</value>
      </list>
    </property>
  </bean>

pay.properties

#支付宝支付参数
#dev环境:ali.serverUrl=https://openapi.alipaydev.com/gateway.do
ali.serverUrl=https://openapi.alipay.com/gateway.do
ali.appId=xxxx
ali.privateKey=xxxx
ali.format=json
ali.charset=utf-8
ali.alipayPulicKey=xxxx
ali.signType=RSA2
#通知地址
ali.notifyUrl=http://xxxx/xxxx/xxxx.do
#回调地址
ali.returnUrl=http://xxxx/xxxx/xxxx.do

Spring注入支付宝sdk

<!--阿里支付api-->
  <bean name="defaultAlipayClient" class="com.alipay.api.DefaultAlipayClient">
    <constructor-arg name="serverUrl" value="${ali.serverUrl}"/>
    <constructor-arg name="appId" value="${ali.appId}"/>
    <constructor-arg name="privateKey" value="${ali.privateKey}"/>
    <constructor-arg name="format" value="${ali.format}"/>
    <constructor-arg name="charset" value="${ali.charset}"/>
    <constructor-arg name="alipayPulicKey" value="${ali.alipayPulicKey}"/>
    <constructor-arg name="signType" value="${ali.signType}"/>
  </bean>
  • 支付接口
/**
     * 阿里支付
     *
     * @param money 金额
     */
    @RequestMapping(value = "aliPay")
    public String aliPay(HttpServletResponse res, HttpServletRequest request,
            @RequestParam BigDecimal money) throws IOException {
        final String session = BaseUtil.getUserSession(request);
        if (StringUtils.isBlank(session)) {
            LOG.error(String.format("pc阿里支付错误:%s", "用户未登录"));
            return "redirect:/view/404.html";
        }
        //保存订单
        final PayModel aliPayModel;
        try {
            aliPayModel = webUserPayManager.requestAliPay(money, session);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            LOG.error(String.format("pc阿里支付错误:%s", e.getMessage()), e);
            return "redirect:/view/404.html";
        }
        res.setContentType("text/html;charset=utf-8");
        //直接将完整的表单html输出到页面
        res.getWriter().write(aliPayModel.getBody());
        res.getWriter().flush();
        res.getWriter().close();
        return null;
    }

WebUserPayManager

    @Autowired
    private AliPay aliPay;

    /**
     * 保存订单信息
     *
     * @param
     * @return
     * @throws PayException 支付异常,返回失败抛出异常 回滚订单数据
     */
    @Transactional(rollbackFor = Exception.class)
    public PayModel requestAliPay(BigDecimal buyMoney, String userId) throws AlipayApiException {
        //写入业务逻辑,返回订单信息
        final WzzwwUserPay userPay = saveUserPay(buyMoney, userId, false);
        Map<String, String> content = new HashMap<>(3);
        //订单号
        content.put("out_trade_no", userPay.getOrderId());
        //总金额
        content.put("total_amount", String.valueOf(userPay.getBuyMoney().doubleValue()));
        //商品标题
        content.put("subject", "xxx");
        content.put("product_code", "FAST_INSTANT_TRADE_PAY");
        PayModel aliPayModel = aliPay.pagePay(content);
        if (!aliPayModel.isSuccess()) {
            throw new PayException(String.format("调用支付出错:%s", aliPayModel.getMsg()));
        }
        return aliPayModel;
    }

AliPay(这里只做了pagePay,注意request,不同的支付使用不一样,可以打开源码包看看,官方文档中也写得很详细),其他参数参考下单接口支付宝统一下单接口


    @Value(value = "${ali.alipayPulicKey}")
    private String alipayPulicKey;

    @Value(value = "${ali.notifyUrl}")
    private String notifyUrl;

    @Value(value = "${ali.returnUrl}")
    private String returnUrl;

    @Autowired
    private AlipayClient alipayClient;

    /**
     * 支付
     *
     * @return
     * @throws AlipayApiException
     */
    public PayModel pay(Map<String, String> content)
            throws AlipayApiException {
        return pay(returnUrl, notifyUrl, content);
    }

    /**
     * 支付
     *
     * @return
     * @throws AlipayApiException
     */
    public PayModel pay(String returnUrl, String notifyUrl, Map<String, String> content)
            throws AlipayApiException {
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();
        //设置业务参数
        alipayRequest.setBizContent(JSONObject.toJSONString(content));
        alipayRequest.setNotifyUrl(notifyUrl);
        alipayRequest.setReturnUrl(returnUrl);
        AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);
        return new PayModel(response.isSuccess(), response.getMsg(),
                JSONObject.parseObject(response.getBody()));
    }

    /**
     * 支付
     *
     * @return
     * @throws AlipayApiException
     */
    public PayModel pagePay(Map<String, String> content)
            throws AlipayApiException {
        return pagePay(returnUrl, notifyUrl, content);
    }

    /**
     * 支付
     *
     * @return
     * @throws AlipayApiException
     */
    public PayModel pagePay(String returnUrl, String notifyUrl, Map<String, String> content)
            throws AlipayApiException {
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        //设置业务参数
        final String bizContent = JSONObject.toJSONString(content);
        alipayRequest.setBizContent(bizContent);
        alipayRequest.setNotifyUrl(notifyUrl);
        alipayRequest.setReturnUrl(returnUrl);
        final AlipayTradePagePayResponse response = alipayClient
                .pageExecute(alipayRequest);
        return new PayModel(response.isSuccess(), response.getMsg(),
                response.getBody());
    }

    public String getAlipayPulicKey() {
        return alipayPulicKey;
    }

    public String getNotifyUrl() {
        return notifyUrl;
    }

    public String getReturnUrl() {
        return returnUrl;
    }

PayModel

/**
 * ali支付返回信息
 *
 * @author LiRui
 * @version 1.0
 */
public class PayModel {

    private boolean success;

    private String msg;

    private JSONObject data;

    private String body;

    private PayModel() {
    }

    public PayModel(final boolean success, final JSONObject data) {
        this.success = success;
        this.data = data;
    }

    public PayModel(final boolean success, final String msg) {
        this.success = success;
        this.msg = msg;
    }

    public PayModel(final boolean success, final String msg, final JSONObject data) {
        this.success = success;
        this.msg = msg;
        this.data = data;
    }

    public PayModel(final boolean success, final String msg, final String body) {
        this.success = success;
        this.msg = msg;
        this.body = body;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(final String msg) {
        this.msg = msg;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(final boolean success) {
        this.success = success;
    }

    public JSONObject getData() {
        return data;
    }

    public void setData(final JSONObject data) {
        this.data = data;
    }

    public String getBody() {
        return body;
    }

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

这里是调用阿里API生成xml表单,然后返回到页面跳转到阿里支付

  • 支付回调接口(配置中的returnUrl地址)
    /**
     * 阿里回调
     *
     * @param request
     */
    @RequestMapping(value = "aliPayNotify")
    public String aliPayNotify(HttpServletRequest request)
            throws AlipayApiException, UnsupportedEncodingException {
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        boolean verifyResult = AlipaySignature
                .rsaCheckV1(params, aliPay.getAlipayPulicKey(), "utf-8", "RSA2");
        if (!verifyResult) {
            LOG.error(String.format("pc阿里支付回调错误,验签失败:%s", params.toString()));
            return "redirect:/view/404.html";
        }
        //验证成功
        //业务id
        String outTradeNo = params.get("out_trade_no");
        final String buyerPayAmount = params.get("total_amount");
        if (StringUtil.isEmpty(outTradeNo)) {
            LOG.error(String.format("pc阿里支付回调错误,out_trade_no为空:%s", params.toString()));
            return "redirect:/view/404.html";
        }
        //处理订单回调逻辑,设置订单业务
        final boolean finishOrder = webUserPayManager
                .finishOrder(outTradeNo, BigDecimal.valueOf(Float.valueOf(buyerPayAmount)));
        return finishOrder ? "redirect:/view/user/index.jsp#/finance"
                : "redirect:/view/index.jsp";
    }

官方demo写的也很详细,可以直接参考官方demo。测试使用时一定要是用外网,可以搜索natapp工具使用穿透到外网,官方的沙箱也很好用:支付宝沙箱使用

猜你喜欢

转载自blog.csdn.net/qq_28325291/article/details/82258627
今日推荐