支付宝沙箱的使用


1.扫码,注册信息

https://auth.alipay.com/login/ant_sso_index.htm?redirectType=self&bizFrom=openhome&goto=https%3A%2F%2Fopen.alipay.com%2Fdev%2Fworkspace

2.点击沙箱

 3.自定义密钥选择RSA2密钥,加签内容配置

4.通过支付宝开发平台开发助手,生成密钥

 5.通过提供的商家和买家进行支付

6.创建一个公共的配置文件

package com.jack.all.common;

import java.io.FileWriter;
import java.io.IOException;

public class AlipayConfig {
    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
    public static String APP_ID = ""; //测试

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String APP_PRIVATE_KEY = "";

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String ALIPAY_PUBLIC_KEY = "";

    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "http://localhost:8081/orders/notifyUrl";

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面)
//    public static String return_url = "http://localhost:8081/orders/returnUrl";
    public static String return_url = "http://localhost:8081/orders/returnUrl";
    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String CHARSET = "UTF-8";

    // 支付宝网关,这是沙箱的网关
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; //测试

    // 支付宝网关
    public static String log_path = "E:\\";

    /**
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis() + ".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

7.创建一个测试用到的方法

package com.jack.all.controller;

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.jack.all.common.AlipayConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

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

@Controller
@RequestMapping(value="/Alipay")
public class AlipayController {

    /**
     * 购物车
     *
     * @return
     */
    @RequestMapping(value = "/Shopcart")
    public String Shopcart() {
        return  "pay";
    }

    /**
     * 结算界面
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/PayPage")
    public String  payController (HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);//支付成功后的跳转界面
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//支付成功后的回调地址

        //商户订单号,商户网站订单系统中唯一订单号,必填

        String out_trade_no = request.getParameter("Order");
        //付款金额,必填  ShopName
        String total_amount = request.getParameter("Money");
        //订单名称,必填
        String subject = request.getParameter("Name");
        //商品描述,可空
        String body =request.getParameter("购物测试");
        // 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
        String timeout_express = "1c";
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        String url = "";
        try {
            url = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单

               /* response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);

                response.getWriter().write(url); // 直接将完整的表单html输出到页面
                response.getWriter().flush();
                response.getWriter().close();*/

        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println(url);
        return url;
    }

    /**
     * 同步跳转
     *
     * @param request
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/returnUrl")
    public ModelAndView returnUrl(HttpServletRequest request) throws Exception {
        ModelAndView mav = new ModelAndView();

        // 获取支付宝GET过来反馈信息(官方固定代码)
        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] + ",";
            }
            params.put(name, valueStr);
        }
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.sign_type); // 调用SDK验证签名

        // 返回界面
        if (signVerified) {
            System.out.println("前往支付成功页面");
            mav.setViewName("Shopcart");
        } else {
            System.out.println("前往支付失败页面");
            mav.setViewName("failReturn");
        }
        return mav;
    }

    /**
     * 支付宝服务器异步通知
     *
     * @param request
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/notifyUrl")
    public void notifyUrl(HttpServletRequest request) throws Exception {
        // 获取支付宝GET过来反馈信息
        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] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.sign_type); // 调用SDK验证签名

        if (signVerified) { // 验证成功 更新订单信息
            System.out.println("异步通知成功");
            // 商户订单号
            String out_trade_no = request.getParameter("out_trade_no");
            // 交易状态
            String trade_status = request.getParameter("trade_status");
            // 修改数据库
        } else {
            System.out.println("异步通知失败");
        }
    }
}

二、重点:是前后端分离用

                        $.get("http://localhost:8081/orders/PayPage?id=" + data.id, function (data) {
                            $("body").html(data);
                        })