【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

时间:2024-04-13 09:02:20

      最近公司有电脑网站跟手机网站的支付宝支付需求,正好博主最近相对有空,于是花了一天时间去实现这个功能。先是在支付宝的开放平台的文档中心看了半天,,发现并不能找到立马就能上手开发的内容。于是搜了几篇博客,综合之下终于实现了功能。在此将java沙箱调试的历程整理出来,希望能对大家有所帮助,好了废话不扯,来看看怎么一步步实现的。

第一步

    访问开放平台文档中西,看看支付宝的支付流程,大概了解一下就行了。地址如下https://docs.open.alipay.com/270/105898/

第二步

         下载java的demo(非常重要),里面包含了需要的jar包以及定义好了支付宝支付的基本参数,下载下来之后我们把自己的参数copy进去,调用起来就很方便。下载路径如下

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

第三步

       申请沙箱环境。沙箱环境相当于是一个支付宝的测试中心,申请之后,会给你指定的appid,测试买家的账号(付款账号),测试卖家账号(收款账号)。有了这些,我们就能愉快的享受调试买买买的乐趣了。

      申请及资料采集步骤如下

1.进入支付宝沙箱测试中心     【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

2.需要生成RSA2(SHA256)的应用公钥,并且配置好RSA2(SHA256)的应用公钥,这里注意,不需要配置RSA(SHA1)**。(生成RSA2的应用公钥详情请参考:https://docs.open.alipay.com/291/105971) 然后将生成的公钥填写到下图中的应用公钥,再将支付宝的公钥copy下来备用。

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

3.沙箱应用中,还需要配置应用网关,这里就需要做内网穿透了。需要让你本地的服务能在公网上被访问到。博主使用的是natapp工具,使用起来很方便,生成了自己的域名之后,然后直接访问,看看tomcat服务能不能跑起来,能访问到之后,将域名天下到应用网关下。至此,沙箱配置就完成啦

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

第四步,将下载下来的demo解压,导入到自己的开发工具中,博主用的myeclipse,目录及结构如下

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

其中为了方便处理支付宝的结构化参数,额外导入了fastjson的包 ,具体的资源大家可以在百度maven 在仓库中搜索下载啦

第五部,添加自己的代码快,如下

 package com.inspiron.alipay;


import java.util.HashMap;
import java.util.Map;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.config.AlipayConfig;




public class AlipayClientFactory {
    
    /*private static final AlipayClient client = new DefaultAlipayClient( 
        AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, 
        AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY); */
    
    private static final AlipayClient client = new DefaultAlipayClient( 
        AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, 
        AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        
    public static AlipayClient getAlipayClientInstance() { 
      return client; 
    } 
    
    /** 
     * appAuthToken 
     * 如ISV代替商家调用当面付接口,需将商户授权后获取的app_auth_token带上;如商家申请当面付自己调用,则传null bizContent 
     * JSON格式 商户的请求参数 
     */
    
    // 手机网页支付 网站支付 
    public String ydAndPc_Pay(Map<String, String> maps) 
        throws AlipayApiException { 
      AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); 
      String NotifyUrl = maps.get("NotifyUrl"); 
      String ReturnUrl = maps.get("ReturnUrl"); 
      // 后台回调 
      if (!StringUtils.isEmpty(NotifyUrl)) { 
        alipayRequest.setNotifyUrl(NotifyUrl); 
        // bizContent 中不需要 公共参数 
        maps.remove("NotifyUrl"); 
      } 
      // 页面回调 
      if (!StringUtils.isEmpty(ReturnUrl)) { 
        alipayRequest.setReturnUrl(ReturnUrl); 
        // bizContent 中不需要 公共参数 
        maps.remove("ReturnUrl"); 
      } 
      String bizCon = JSON.toJSONString(maps); 
      alipayRequest.setBizContent(bizCon); 
      String form = ""; 
      try { 
        form = AlipayClientFactory.getAlipayClientInstance() 
            .pageExecute(alipayRequest).getBody(); 
      } catch (AlipayApiException e) { 
        form = "err"; 
        e.printStackTrace(); 
      } // 调用SDK生成表单 
      return form; 
    } 
    
    
    public String Pc_Pay(Map<String, String> maps) 
        throws AlipayApiException { 
      AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); 
      String NotifyUrl = maps.get("NotifyUrl"); 
      String ReturnUrl = maps.get("ReturnUrl"); 
      // 后台回调 
      if (!StringUtils.isEmpty(NotifyUrl)) { 
        alipayRequest.setNotifyUrl(NotifyUrl); 
        // bizContent 中不需要 公共参数 
        maps.remove("NotifyUrl"); 
      } 
      // 页面回调 
      if (!StringUtils.isEmpty(ReturnUrl)) { 
        alipayRequest.setReturnUrl(ReturnUrl); 
        // bizContent 中不需要 公共参数 
        maps.remove("ReturnUrl"); 
      } 
      String bizCon = JSON.toJSONString(maps); 
      System.out.println("bizCon :"+bizCon);
      alipayRequest.setBizContent(bizCon); 
      String form = ""; 
      try { 
        form = AlipayClientFactory.getAlipayClientInstance() 
            .pageExecute(alipayRequest).getBody(); 
      } catch (AlipayApiException e) { 
        form = "err"; 
        e.printStackTrace(); 
      } // 调用SDK生成表单 
      return form; 
    } 
    
    
    
    // 查询订单状态 
    public AlipayTradeQueryResponse query(String appAuthToken, String bizContent) 
        throws AlipayApiException { 
      AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); 
      request.putOtherTextParam("app_auth_token", appAuthToken); 
      request.setBizContent(bizContent); 
      return AlipayClientFactory.getAlipayClientInstance().execute(request); 
    } 
    
    // 条码支付 
    public AlipayTradePayResponse pay(String appAuthToken, String bizContent) 
        throws AlipayApiException { 
      AlipayTradePayRequest request = new AlipayTradePayRequest(); 
      request.putOtherTextParam("app_auth_token", appAuthToken); 
      request.setBizContent(bizContent); 
      return AlipayClientFactory.getAlipayClientInstance().execute(request); 
    } 
    
    // 扫码支付 
    public AlipayTradePrecreateResponse precreate(String appAuthToken, 
        String bizContent) throws AlipayApiException { 
      AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); 
      request.putOtherTextParam("app_auth_token", appAuthToken); 
      request.setBizContent(bizContent); 
      return AlipayClientFactory.getAlipayClientInstance().execute(request); 
    } 
    
    // 订单撤销 
    public AlipayTradeCancelResponse cancel(String appAuthToken, 
        String bizContent) throws AlipayApiException { 
      AlipayTradeCancelRequest request = new AlipayTradeCancelRequest(); 
      request.putOtherTextParam("app_auth_token", appAuthToken); 
      request.setBizContent(bizContent); 
      return AlipayClientFactory.getAlipayClientInstance().execute(request); 
    } 
    
    // 申请退款 
    public AlipayTradeRefundResponse refund(String appAuthToken, 
        String bizContent) throws AlipayApiException { 
      AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); 
      request.putOtherTextParam("app_auth_token", appAuthToken); 
      request.setBizContent(bizContent); 
      return AlipayClientFactory.getAlipayClientInstance().execute(request); 
    } 
    
    @SuppressWarnings("unused") 
    public static void main(String[] args) { 
      AlipayClientFactory c = new AlipayClientFactory(); 
      try { 
        Map<String, String> map = new HashMap<String, String>(); 
        map.put("out_trade_no", "20160914113218"); 
        String bizContent = JSON.toJSONString(map); 
        System.err.println(bizContent); 
        AlipayTradeQueryResponse rp = c.query(null, bizContent); 
      } catch (AlipayApiException e) { 
        e.printStackTrace(); 
      } 
    } 
    

}



package com.inspiron.alipay;


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.alipay.api.AlipayApiException;


public class CsPay extends HttpServlet {
    private static final long serialVersionUID = 1L;


    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }


    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 参数目前都是 写死的 根据业务需求 写活
        System.out.println("已经成功进入到后台接口");
        Map<String, String> maps = new HashMap<String, String>();
        maps.put("out_trade_no", UtilDate.getOrderNum());
        maps.put("total_amount","1.00");
        maps.put("subject", "Iphone6 16G");
        maps.put("body", "Iphone6 16G");
        //maps.put("product_code", "QUICK_WAP_PAY");
        maps.put("product_code", "FAST_INSTANT_TRADE_PAY");//网页版参数不同
        // 下面两个 参数的 KEY 不要乱写 要和工具类里面对应
        maps.put("ReturnUrl", "http://f8s7ks.natappfree.cc/alipay.trade.wap.pay-java-utf-8/return_url.jsp");
        maps.put("NotifyUrl", "http://f8s7ks.natappfree.cc/alipay.trade.wap.pay-java-utf-8/notify_url.jsp");
        try {
            AlipayClientFactory ali = new AlipayClientFactory();
            String form = ali.Pc_Pay(maps);
            if (!form.equals("err")) {
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write(form);// 直接将完整的表单html输出到页面
                response.getWriter().flush();
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        
    }

}


package com.inspiron.alipay;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;


public class CsUtil {
    /**
     * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * 
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {


        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);


        String prestr = "";


        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);


            if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }


        return prestr;
    }

}


package com.inspiron.alipay;


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


/*
 * * 类名:UtilDate 功能:自定义订单类 详细:工具类,可以用作获取系统日期、订单编号等 版本:3.3 日期:2012-08-17 说明:
 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */
public class UtilDate {


    /** 年月日时分秒(无下划线) yyyyMMddHHmmss */
    public static final String dtLong = "yyyyMMddHHmmss";


    /** 完整时间 yyyy-MM-dd HH:mm:ss */
    public static final String simple = "yyyy-MM-dd HH:mm:ss";


    /** 年月日(无下划线) yyyyMMdd */
    public static final String dtShort = "yyyyMMdd";


    /**
     * 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
     * 
     * @return 以yyyyMMddHHmmss为格式的当前系统时间
     */
    public static String getOrderNum() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(dtLong);
        return df.format(date);
    }


    /**
     * 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
     * 
     * @return
     */
    public static String getDateFormatter() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(simple);
        return df.format(date);
    }


    /**
     * 获取系统当期年月日(精确到天),格式:yyyyMMdd
     * 
     * @return
     */
    public static String getDate() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(dtShort);
        return df.format(date);
    }


    /**
     * 产生随机的三位数
     * 
     * @return
     */
    public static String getThree() {
        Random rad = new Random();
        return rad.nextInt(1000) + "";
    }


}



代码贴进去之后,填写AlipayConfig文件中的参数,如下

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

然后需要配置servelt的入口,我们在web.xml 文件中作如下配置

<servlet>
<servlet-name>cspay</servlet-name>
<servlet-class>com.inspiron.alipay.CsPay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cspay</servlet-name>
<url-pattern>/cspay</url-pattern>

</servlet-mapping>


将项目加载到服务器中,访问路径 http://自己的网址/alipay.trade.wap.pay-java-utf-8/cspay   

出现以下页面

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

恭喜你,大公高成啦。


如果是手机网站,调用app的方式,需要在代码中做如下修改

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

然后访问出现如下页面

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

【java】小白最详细调试支付宝沙箱手机网站支付,电脑网站扫码支付

表示成功 。然后可以登录沙箱给我们的买家的账号,就可以体验支付的流程啦

如果有问题,欢迎大家沟通指导~~