支付宝配置:
package com.integralpay.config;
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "2018000000000";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "xxxxxxxxxxxxxxxxxxxxxx";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "xxxxxxxxxxxxxxxxxxxxxx";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 支付宝与服务器交互的页面,用户看不到
public static String notify_url = "http://xxxxx/notify_url";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 付款成功之后返回给用户查看的界面
public static String return_url = "http://xxxxx/return_url";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关 现在是沙箱地址
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
微信配置(微信使用的是第二种方式 统一支付):
package com.integralpay.config;
public class WechatConfig {
public static String appid = "wx12345678910"; // appid
public static String appsecret = ""; // appsecret
public static String mch_id = "150000000000"; // 商业号
public static String key = "6acd9791afa5adz9das8a5d04e1388a"; // API_KEY
public static String spbill_create_ip = "0.0.0.0"; // 获取发起电脑 ip
public static String notify_url = "http://xxxx/weixin_notify"; // 回调接口
}
下面是具体实现
支付宝
package com.integralpay.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
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.talent.cloud.integralpay.config.AlipayConfig;
import com.talent.cloud.integralpay.entity.T_integralRecharge;
import com.talent.cloud.integralpay.service.IntegralrechargeService;
@Controller
public class AliPayController {
@Autowired
private IntegralrechargeService integralrechargeService;
/**
* 获取订单数据接口
* @param request
* @param response
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping("/AliPay")
public void AliPay(T_integralRecharge integralRecharge,HttpServletRequest req, Model mod, HttpServletResponse rep) throws AlipayApiException, IOException{
//系统下单
int hashCodeV = UUID.randomUUID().toString().hashCode();
if(hashCodeV < 0) { //有可能是负数
hashCodeV = - hashCodeV;
}
integralRecharge.setOrder_id(integralRecharge.getEnterprise_id()+String.format("%015d", hashCodeV));
integralRecharge.setState(0);
integralrechargeService.insertOrder(integralRecharge);
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_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 = integralRecharge.getOrder_id();
//付款金额,必填
String total_amount = integralRecharge.getAmount().toString();
//订单名称,必填
String subject = "积分充值";
//商品描述,可空
String body = "人才云积分充值";
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求
String result = alipayClient.pageExecute(alipayRequest).getBody();
rep.setContentType("text/html;charset=" + AlipayConfig.charset);
rep.getWriter().write(result);//直接将完整的表单html输出到页面
rep.getWriter().flush();
rep.getWriter().close();
}
/**
* 回调路径return_url
* @param request
* @param response
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping(value = "/return_url", method = RequestMethod.GET)
public void returnUrl(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException{
String msg = new String();
//获取支付宝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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,AlipayConfig.sign_type);
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");
//系统处理根据支付宝回调更改订单状态或者其他关联表的数据
T_integralRecharge order = integralrechargeService.findOneByTradeCode(out_trade_no);
if(order == null) {
msg = "订单号不存在";
}else {
/* if(!order.getAmount().toString().equals(total_amount)){
msg = "付款金额错误";
}*/
if(order.getState() == 1){ //判断当前订单是否已处理
msg = "系统订单:"+ out_trade_no + "成功支付。";
}
}
}else{
msg = "验签失败";
}
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("");
}
@RequestMapping(value = "/notify_url", method = RequestMethod.POST)
public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException{
//获取支付宝POST过来反馈信息
response.setContentType("text/html;charset=" + AlipayConfig.charset);
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,AlipayConfig.sign_type);
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");
//系统处理根据支付宝回调更改订单状态或者其他关联表的数据
T_integralRecharge order = integralrechargeService.findOneByTradeCode(out_trade_no);
if(trade_status.equals("TRADE_FINISHED")){ //已经付款过
if(order.getState() == 0) {
integralrechargeService.handleOrder(out_trade_no,order.getEnterprise_id(),order.getAmount());
}
}else if (trade_status.equals("TRADE_SUCCESS")){ //付款成功
if(order.getState() == 0) {
integralrechargeService.handleOrder(out_trade_no,order.getEnterprise_id(),order.getAmount());
}
}
response.getWriter().write("success");
}else {//验证失败
response.getWriter().write("fail");
}
response.getWriter().flush();
response.getWriter().close();
}
}
微信
package com.integralpay.controller;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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 com.talent.cloud.integralpay.config.WechatConfig;
import com.talent.cloud.integralpay.entity.T_integralRecharge;
import com.talent.cloud.integralpay.service.IntegralrechargeService;
import com.talent.cloud.integralpay.util.HttpUtil;
import com.talent.cloud.integralpay.util.PayCommonUtil;
import com.talent.cloud.integralpay.util.XMLUtil;
import net.sf.json.JSONObject;
@Controller
public class WechatController {
@Autowired
private IntegralrechargeService integralrechargeService;
@RequestMapping("/WechatPay")
@ResponseBody
public String weixin_pay(T_integralRecharge integralRecharge) throws Exception {
JSONObject object = new JSONObject();
// 账号信息
String appid = WechatConfig.appid; // appid
//String appsecret = PayConfigUtil.APP_SECRET; // appsecret
String mch_id = WechatConfig.mch_id; // 商业号
String key = WechatConfig.key; // key
String currTime = PayCommonUtil.getCurrTime();
String strTime = currTime.substring(8, currTime.length());
String strRandom = PayCommonUtil.buildRandom(4) + "";
String nonce_str = strTime + strRandom;
//integralRecharge.setAmount(integralRecharge.getAmount() * 100);
String order_price = integralRecharge.getAmount().toString(); // 价格 注意:价格的单位是分
String body = "人才云积分充值"; // 商品名称
int hashCodeV = UUID.randomUUID().toString().hashCode();
if(hashCodeV < 0) { //有可能是负数
hashCodeV = - hashCodeV;
}
String out_trade_no = integralRecharge.getEnterprise_id()+String.format("%015d", hashCodeV); // 订单号
object.put("out_trade_no", out_trade_no);
//生成订单
integralRecharge.setOrder_id(out_trade_no);
integralRecharge.setState(0);
integralrechargeService.insertOrder(integralRecharge);
// 获取发起电脑 ip
String spbill_create_ip = WechatConfig.spbill_create_ip;
// 回调接口
String notify_url = WechatConfig.notify_url;
String trade_type = "NATIVE";
SortedMap
微信还需要几个工具类
package com.integralpay.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
public class HttpUtil {
private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
private final static String DEFAULT_ENCODING = "UTF-8";
public static String postData(String urlStr, String data){
return postData(urlStr, data, null);
}
public static String postData(String urlStr, String data, String contentType){
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(contentType != null)
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null)
data = "";
writer.write(data);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
}
}
package com.integralpay.util;
import java.security.MessageDigest;
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
package com.integralpay.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
public class PayCommonUtil {
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
* @return boolean
*/
public static boolean isTenpaySign(String characterEncoding, SortedMap packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if(!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
//算出摘要
String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();
//System.out.println(tenpaySign + " " + mysign);
return tenpaySign.equals(mysign);
}
/**
* @author
* @date 2016-4-22
* @Description:sign签名
* @param characterEncoding
* 编码格式
* @param parameters
* 请求参数
* @return
*/
public static String createSign(String characterEncoding, SortedMap packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
/**
* @author
* @date 2016-4-22
* @Description:将请求参数转换为xml格式的string
* @param parameters
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap parameters) {
StringBuffer sb = new StringBuffer();
sb.append("");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "" + k + ">");
} else {
sb.append("<" + k + ">" + v + "" + k + ">");
}
}
sb.append(" ");
return sb.toString();
}
/**
* 取出一个指定长度大小的随机正整数.
*
* @param length
* int 设定所取出随机数的长度。length小于11
* @return int 返回生成的随机数。
*/
public static int buildRandom(int length) {
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < length; i++) {
num = num * 10;
}
return (int) ((random * num));
}
/**
* 获取当前时间 yyyyMMddHHmmss
*
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
}
package com.talent.cloud.integralpay.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class XMLUtil {
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if(null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("" + name + ">");
}
}
return sb.toString();
}
}