700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java 接入支付宝支付 - 沙箱环境

Java 接入支付宝支付 - 沙箱环境

时间:2021-08-22 10:27:31

相关推荐

Java 接入支付宝支付 - 沙箱环境

Table of Contents

一、沙箱环境

二、下载 Java版dome

三、生成RSA2密钥

四、代码如下

4.1AlipayConfig

4.2AlipayVo

4.3AlipayUtil

4.4 AlipayController

五、结果视图

一、沙箱环境

/platform/appDaily.htm?tab=info

二、下载 Java版dome

/rmsportal_6680_alipay.trade.wap.pay-java-utf-8.zip

三、生成RSA2密钥

https://docs./291/105971

注:生成秘钥看上一个链接。秘钥匹配成功后,主要是要将我们生成的公钥替换我们 [ 蚂蚁金服 ] 的应用公钥。

四、代码如下

4.1AlipayConfig

注:将app_id、merchant_private_key、alipay_public_key 【应用ID、私钥、公钥】补全即可。

package com.rerise.controller.nz.alipay;/*** 类名:AlipayConfig* 功能:基础配置类* 详细:设置帐户有关信息及返回路径* 修改日期:-04-05* 说明:* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。*/public class AlipayConfig {/*** 1. 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号*/public static String app_id = "";/*** 2. 商户私钥,您的PKCS8格式RSA2私钥*/public static String merchant_private_key = "";/*** 3. 支付宝公钥,查看地址:/platform/keyManage.htm 对应APPID下的支付宝公钥。*/public static String alipay_public_key = "";/*** 4. 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/public static String notify_url = "http://localhost/alipay/notifyNotice";/*** 5. 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/public static String return_url = "http://localhost/alipay/returnNotice";/*** 6. 签名方式/加密类型*/public static String sign_type = "RSA2";/*** 7. 编码*/public static String charset = "utf-8";/*** 8.返回格式*/public static String format = "json";/*** 9. 支付宝网关 - 注:沙箱使用 alipaydev , 非 alipay*/public static String gatewayUrl = "/gateway.do";}

4.2AlipayVo

package com.rerise.controller.nz.alipay;import java.io.Serializable;/*** Created by IntelliJ IDEA.** @author NingZe* description: alipay vo* path: DecoSearch-manage-com.rerise.controller.nz.alipay-AlipayVo* date: /8/14 0014 10:17* version: 02.06* To change this template use File | Settings | File Templates.*/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;}}

4.3AlipayUtil

package com.rerise.controller.nz.alipay;import com.alipay.api.AlipayApiException;import com.alipay.api.internal.util.AlipaySignature;import java.lang.management.ManagementFactory;import .InetAddress;import workInterface;import java.util.HashMap;import java.util.Map;/*** Created by IntelliJ IDEA.** @author NingZe* description: alipay util* path: DecoSearch-manage-com.rerise.controller.nz.alipay-AlipayUtil* date: /8/14 0014 10:19* version: 02.06* To change this template use File | Settings | File Templates.*/public class AlipayUtil {/*** 处理请求参数** @param requestParams* @return*/public static Map<String, String> handleParams(Map<String, String[]> requestParams) {Map<String, String> handleMap = new HashMap<>(requestParams.size());for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {String key = entry.getKey();String[] value = entry.getValue();handleMap.put(key, join(value, ","));}return handleMap;}/*** 数组转字符串 ["1", "2"] ==> "1,2"** @param os* @param splitString* @return*/public static String join(Object[] os, String splitString) {String s = "";if (os != null) {StringBuilder sBuffer = new StringBuilder();for (int i = 0; i < os.length; i++) {sBuffer.append(os[i]).append(splitString);}s = sBuffer.deleteCharAt(sBuffer.length() - 1).toString();}return s;}/*** 校验是否支付成功** @param handleParams* @return*/public static boolean rsaCheck(Map<String, String> handleParams) {boolean checkV1 = false;try {checkV1 = AlipaySignature.rsaCheckV1(handleParams, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);} catch (AlipayApiException e) {e.printStackTrace();}return checkV1;}/*** ---------------------------------------单例模式---------------------------------------*/private static class SingletonHolder {private static final AlipayUtil INSTANCE = new AlipayUtil();}public static AlipayUtil get() {return SingletonHolder.INSTANCE;}/** ---------------------------------------单例模式---------------------------------------*//*** 雪花算法生成ID,自带时间排序,一秒可以生成25万个ID左右*/// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)private final static long twepoch = 1288834974657L;// 机器标识位数private final static long workerIdBits = 5L;// 数据中心标识位数private final static long datacenterIdBits = 5L;// 机器ID最大值private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);// 数据中心ID最大值private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 毫秒内自增位private final static long sequenceBits = 12L;// 机器ID偏左移12位private final static long workerIdShift = sequenceBits;// 数据中心ID左移17位private final static long datacenterIdShift = sequenceBits + workerIdBits;// 时间毫秒左移22位private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final static long sequenceMask = -1L ^ (-1L << sequenceBits);/* 上次生产id时间戳 */private static long lastTimestamp = -1L;// 0,并发控制private long sequence = 0L;private final long workerId;// 数据标识id部分private final long datacenterId;public AlipayUtil() {this.datacenterId = getDatacenterId(maxDatacenterId);this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);}/*** @param workerId工作机器ID* @param datacenterId 序列号*/public AlipayUtil(long workerId, long datacenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;}/*** 获取下一个ID** @return*/public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}if (lastTimestamp == timestamp) {// 当前毫秒内,则+1sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 当前毫秒内计数满了,则等待下一秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;// ID偏移组合生成最终的ID,并返回IDlong nextId = ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;return nextId;}private long tilNextMillis(final long lastTimestamp) {long timestamp = this.timeGen();while (timestamp <= lastTimestamp) {timestamp = this.timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** <p>* 获取 maxWorkerId* </p>*/protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {StringBuffer mpid = new StringBuffer();mpid.append(datacenterId);String name = ManagementFactory.getRuntimeMXBean().getName();if (!name.isEmpty()) {/** GET jvmPid*/mpid.append(name.split("@")[0]);}/** MAC + PID 的 hashcode 获取16个低位*/return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);}/*** <p>* 数据标识id部分* </p>*/protected static long getDatacenterId(long maxDatacenterId) {long id = 0L;try {InetAddress ip = InetAddress.getLocalHost();NetworkInterface network = NetworkInterface.getByInetAddress(ip);if (network == null) {id = 1L;} else {byte[] mac = network.getHardwareAddress();id = ((0x000000FF & (long) mac[mac.length - 1])| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;id = id % (maxDatacenterId + 1);}} catch (Exception e) {System.out.println(" getDatacenterId: " + e.getMessage());}return id;}/** 雪花算法生成ID,自带时间排序,一秒可以生成25万个ID左右 */}

4.4 AlipayController

package com.rerise.controller.nz.alipay;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.alipay.api.AlipayApiException;import com.alipay.api.AlipayClient;import com.alipay.api.DefaultAlipayClient;import com.alipay.api.request.AlipayTradePagePayRequest;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.Map;/*** Created by IntelliJ IDEA.** @author NingZe* description:* path: DecoSearch-manage-com.rerise.controller.nz.alipay-AlipayController* date: /8/13 0013 16:51* version: 02.06* To change this template use File | Settings | File Templates.*/@RequestMapping("alipay")@Controllerpublic class AlipayController {/*** @Function: TODO* @description: 前往支付宝第三方网关进行支付* @author: NingZe* @date: /8/13 0013 17:10* @params: []* @return: java.lang.String*/@RequestMapping("goAlipay")@ResponseBodypublic String goAlipay() throws Exception {AlipayVo alipayVo = new AlipayVo();// 设置订单单号,需要保证唯一性alipayVo.setOut_trade_no(AlipayUtil.get().nextId() + "");System.err.println(alipayVo.getOut_trade_no());// 设置支付金额alipayVo.setTotal_amount("18.10");// 设置支付标题alipayVo.setSubject("和番丼饭(昌里路店)外卖订单");// 设置订单有效时长(30分钟)alipayVo.setTimeout_express("30m");// 商品码(必须是QUICK_WAP_WAY、FAST_INSTANT_TRADE_PAY),可以看文档 see: https://docs./203/107090/alipayVo.setProduct_code("FAST_INSTANT_TRADE_PAY");// 商品描述alipayVo.setBody("外卖订单");// 对象转为json字符串String json = JSONObject.toJSONString(alipayVo);//获得初始化的AlipayClientAlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, AlipayConfig.format, AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);//设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(AlipayConfig.return_url);alipayRequest.setNotifyUrl(AlipayConfig.notify_url);// 封装请求支付信息alipayRequest.setBizContent(json);// 请求String result;try {result = alipayClient.pageExecute(alipayRequest).getBody();} catch (AlipayApiException e) {result = "request aliapy has error";e.printStackTrace();}return result;}/*** @Function: TODO* @description: 支付宝完成[同步]回调页面(不可信回调)* @author: NingZe* @date: /8/13 0013 17:20* @params: [request, response]* @return: ModelAndView*/@RequestMapping("returnNotice")@ResponseBodypublic String returnNotice(HttpServletRequest request) throws Exception {Map<String, String[]> parameterMap = request.getParameterMap();Map<String, String> handleParams = AlipayUtil.handleParams(parameterMap);/*** 这里的校验没有多大的意思,不可信,直接获取out_trade_no跳转到对应的payed controller也可*/boolean signVerified = AlipayUtil.rsaCheck(handleParams);/*** 存放信息*/Map<String, String> maps = new HashMap<>(6);// 验证成功if (signVerified) {// 商户订单号String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");// 支付宝交易号String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");// 交易状态String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");if ("TRADE_FINISHED".equals(trade_status)) {//判断该笔订单是否在商户网站中已经做过处理//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序//如果有做过处理,不执行商户的业务程序//注意://退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知} else if ("TRADE_SUCCESS".equals(trade_status)) {//判断该笔订单是否在商户网站中已经做过处理//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序//如果有做过处理,不执行商户的业务程序//注意://付款完成后,支付宝系统发送该交易状态通知}maps.put("out_trade_no", out_trade_no);maps.put("trade_no", trade_no);maps.put("trade_status", trade_status);maps.put("return_msg", "success");} else {maps.put("return_msg", "fail");}return JSON.toJSONString(maps);}/*** @Function: TODO* @description: 支付宝完成[异步]回调页面(可信回调)* @author: NingZe* @date: /8/13 0013 17:20* @params: [request, response]* @return: ModelAndView*/@RequestMapping("notifyNotice")@ResponseBodypublic String notifyNotice(HttpServletRequest request) throws Exception {Map<String, String[]> parameterMap = request.getParameterMap();Map<String, String> handleParams = AlipayUtil.handleParams(parameterMap);/*** 这里的校验没有多大的意思,不可信,直接获取out_trade_no跳转到对应的payed controller也可*/boolean signVerified = AlipayUtil.rsaCheck(handleParams);/*** 存放信息*/Map<String, String> maps = new HashMap<>(6);// 验证成功if (signVerified) {// 商户订单号String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");// 支付宝交易号String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");// 付款金额String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");maps.put("out_trade_no", out_trade_no);maps.put("trade_no", trade_no);maps.put("total_amount", total_amount);maps.put("notify_msg", "success");} else {maps.put("notify_msg", "fail");}return JSON.toJSONString(maps);}}

五、结果视图

http://localhost/alipay/goAlipay

用沙箱扫码付款即可。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。