package com.pay;
import java.util.Date;
import java.util.Map;
public class test {
/**
* 生成统一下单
* @throws Exception
*/
public static void main1(String[] args) throws Exception {
String appid = ""; //微信小程序--》“开发者ID”
String mch_id = ""; //商户号,将该值赋值给partner
String key = ""; //微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位)
String openid = ""; //openid
String ip = ""; //ip地址
String body = "测试"; //描述
int total_fee = 1; //支付金额
Date data = new Date();
String notify_url = "http://www.weixin.qq.com/wxpay/pay.php"; //回调链接
String out_trade_no = "SH" + DateUtil.dateFormatSSS.format(data);
System.out.println("支付订单号:"+out_trade_no);
Map<Object, Object> map=WeiXinAtcion.me.weixinPlay(mch_id, appid, key, openid, total_fee, out_trade_no, notify_url, body, ip);
System.out.println("paySign:"+map.get("paySign"));
System.out.println("timeStamp:"+map.get("timeStamp"));
System.out.println("nonceStr:"+map.get("nonceStr"));
System.out.println("package:"+map.get("package"));
}
/**
* 退款
* @throws Exception
*/
public static void main2(String[] args) throws Exception {
String out_trade_no = ""; //退款订单
int all_total_fee = 100; //订单金额(这里是按分来计算的)
int refund_fee = 0; //退款金额(这里是按分来计算的)
String appid = ""; //微信小程序--》“开发者ID”
String mch_id = ""; //商户号,将该值赋值给partner
String key = ""; //微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位)
Map<String, String> refundmap= WeiXinAtcion.me.wechatRefund(mch_id, appid, key, out_trade_no, all_total_fee, refund_fee);
if(refundmap.get("return_code").equals("SUCCESS")) {
if(refundmap.get("result_code").equals("FAIL")) {
System.out.println("退款失败:原因"+refundmap.get("err_code_des"));
}else {
System.out.println("退款成功");
}
}else {
System.out.println("退款失败:原因"+refundmap.get("return_ms"));
}
}
}
package com.pay;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class WeiXinAtcion {
public static final WeiXinAtcion me = new WeiXinAtcion();
/**
* 退款函数,该方法可以对曾经部分退款的订单进行再次退款
* @param out_trade_no 商户订单号
* @param total_fee1 退款对应的订单的总金额(以“元”为单位)
* @param refund_fee1 计划退款的金额(以“元”为单位)
* @throws Exception
*/
public static Map<String, String> wechatRefund(String mch_id,String appid,String key,String out_trade_no,int all_total_fee,int refund_fee) throws Exception{
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid",appid);
packageParams.put("mch_id",mch_id);
packageParams.put("op_user_id",mch_id);
packageParams.put("nonce_str", WXUtil.generate());
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("out_refund_no", WXUtil.generate());
packageParams.put("total_fee",String.valueOf( all_total_fee));
packageParams.put("refund_fee", String.valueOf( refund_fee));
String sign = WXUtil.createSign_ChooseWXPay("UTF-8", packageParams, key);
packageParams.put("sign", sign);
String XML = WXUtil.getRequestXml(packageParams);
return WXUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", XML,mch_id);
}
/**
* 生成微信订单
*
* @param openid
* @param period_number
* @param merchant_id
* @param num
* @return
*/
public SortedMap<Object, Object> weixinPlay(String mch_id,String appid,String key,String openid,int total_fee,String out_trade_no,String notify_url,String body,String ip) throws UnsupportedEncodingException, DocumentException {
SortedMap<Object, Object> paymentPo = new TreeMap<Object, Object>();
paymentPo.put("appid",appid);
paymentPo.put("mch_id", mch_id);
paymentPo.put("nonce_str", WXUtil.generate());
paymentPo.put("body",body);
paymentPo.put("out_trade_no",out_trade_no);
paymentPo.put("total_fee",String.valueOf(total_fee));
paymentPo.put("spbill_create_ip", "127.0.0.1");//这里填写你的服务器IP地址
paymentPo.put("notify_url", notify_url);
paymentPo.put("trade_type", "JSAPI");
paymentPo.put("openid", openid);
String sign = WXUtil.createSign_ChooseWXPay("UTF-8", paymentPo, key);
paymentPo.put("sign", sign);
String param = WXUtil.getRequestXml(paymentPo);;
String request = WXUtil.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", param);
Map<String, String> map = new HashMap<String, String>(); // 将解析结果存储在HashMap中
InputStream in = new ByteArrayInputStream(request.getBytes());
SAXReader reader = new SAXReader(); // 读取输入流
Document document = reader.read(in);
Element root = document.getRootElement(); // 得到xml根元素
@SuppressWarnings("unchecked") // 得到根元素的所有子节点
List<Element> elementList = root.elements();
for (Element element : elementList) {
map.put(element.getName(), element.getText());
}
SortedMap<Object, Object> result = new TreeMap<Object, Object>();
if (map.get("return_code").equals("SUCCESS")) { // 业务结果
String nonceStr =WXUtil.generate();
Long timeStamp = System.currentTimeMillis() / 1000;
SortedMap<Object, Object> params = new TreeMap<Object, Object>();
params.put("appId", appid);
params.put("nonceStr", nonceStr);
params.put("package", "prepay_id=" + map.get("prepay_id"));
params.put("signType", "MD5");
params.put("timeStamp", timeStamp);
String paySign = WXUtil.createSign_ChooseWXPay("UTF-8", params, key);
result.put("paySign", paySign);
result.put("timeStamp", timeStamp + "");
result.put("nonceStr", nonceStr);
result.put("package", "prepay_id=" + map.get("prepay_id"));
result.put("return_code", "SUCCESS");
}else {
result.put("return_code", "Fail");
result.put("return_msg", map.get("return_msg"));
}
return result;
}
/**
* 支付成功的回调函数
* @param request
* @param response
* @throws Exception
*/
public void weixinpay_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{
InputStream inputStream ;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s ;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null){
sb.append(s);
}
in.close();
inputStream.close();
Map<String, String> m = new HashMap<String, String>();
m = WXUtil.doXMLParse(sb.toString());
SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
Iterator it = m.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = m.get(parameter);
String v = "";
if(null != parameterValue) {
v = parameterValue.trim();
}
packageParams.put(parameter, v);
}
String key = ""; //秘钥
if(WXUtil.isTenpaySign("UTF-8", packageParams,key)) {
String resXml = "";
if("SUCCESS".equals((String)packageParams.get("result_code"))){
//得到返回的参数
String openid = (String)packageParams.get("openid");
String transaction_id = (String)packageParams.get("transaction_id");
String out_trade_no = (String)packageParams.get("out_trade_no");
String total_fee = (String)packageParams.get("total_fee");
Float fee= Float.parseFloat(total_fee)/100;
//这里可以写你需要的业务
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
} else {
System.out.println("回调失败");
}
} else{
System.out.println("回调失败");
}
}
}
package com.pay;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class WXUtil {
/**
* 随机字符串
* @return
*/
public static String generate() {
return UUID.randomUUID().toString().trim().replaceAll("-", "");
}
/**
* 解析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 = WXUtil.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(WXUtil.getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
}
/**
* 将请求参数转换为xml格式的string字符串,微信服务器接收的是xml格式的字符串
*
* 作者: zhoubang 日期:2015年6月10日 上午9:25:51
*
* @param parameters
* @return
*/
public static String getRequestXml(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set<Entry<Object, Object>> es = parameters.entrySet();
Iterator<Entry<Object, Object>> it = es.iterator();
while (it.hasNext()) {
Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) 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 + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* sign签名,必须使用MD5签名,且编码为UTF-8
* 作者: zhoubang 日期:2015年6月10日 上午9:31:24
* @param characterEncoding
* @param parameters
* @return
*/
public static String createSign_ChooseWXPay(String characterEncoding, SortedMap<Object, Object> parameters, String key) {
StringBuffer sb = new StringBuffer();
Set<Entry<Object, Object>> es = parameters.entrySet();
Iterator<Entry<Object, Object>> it = es.iterator();
while (it.hasNext()) {
Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
/** 支付密钥必须参与加密,放在字符串最后面 */
sb.append("key=" + key);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
/**
*
* @param requestUrl请求地址
* @param requestMethod请求方法
* @param outputStr参数
*/
public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
// 创建SSLContext
StringBuffer buffer=null;
try{
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(requestMethod);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();
//往服务器端写内容
if(null !=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
// 读取服务器端返回的内容
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
public static String urlEncodeUTF8(String source){
String result=source;
try {
result=java.net.URLEncoder.encode(source, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
/**
* 退款
*/
public static Map<String, String> doRefund(String url,String data,String partner) throws Exception {
//p12证书的位置
//微信公众平台:“微信支付”--》“商户信息”--》“交易数据”--》“详情请登录微信支付商户平台查看”(登录)--》“API安全”--》“API证书”--》“下载证书”
//下载证书后将apiclient_cert.p12放在src目录下面(出于安全考虑,请自行下载自己的证书)
String apiclient_certLocation = "apiclient_cert.p12";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
URL url2 = WXUtil.class.getClassLoader().getResource(apiclient_certLocation);
URI uri = url2.toURI();
FileInputStream instream = new FileInputStream(new File(uri));//P12文件目录
try {
keyStore.load(instream, partner.toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, partner.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
try {
HttpPost httpost = new HttpPost(url); // 设置响应头信息
httpost.addHeader("Connection", "keep-alive");
httpost.addHeader("Accept", "*/*");
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpost.addHeader("Host", "api.mch.weixin.qq.com");
httpost.addHeader("X-Requested-With", "XMLHttpRequest");
httpost.addHeader("Cache-Control", "max-age=0");
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
httpost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpResponse response = httpclient.execute(httpost);
try {
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return WXUtil.doXMLParse(jsonStr);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
* @return boolean
*/
public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> 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);
}
}
package com.pay;
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.pay;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public static SimpleDateFormat dateFormatMillisecond = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static SimpleDateFormat dateFormatWithYMD = new SimpleDateFormat("yyyy-MM-dd");
public static SimpleDateFormat dateFormatWithYMDHM = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public static SimpleDateFormat dateFormatSSS = new SimpleDateFormat("yyyyMMddHHmmssSSS");
public static String addDateMinut(Date date, int x) {// 返回的是字符串型的时间,输入的//是String // day, int x
// 引号里面个格式也可以是 HH:mm:ss或者HH:mm等等,很随意的,不过在主函数调用时,要和输入的变
// 量day格式一致
if (date == null)
return "";
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MINUTE, x);// 24小时制
date = cal.getTime();
cal = null;
return dateFormat.format(date);
}
public static void main(String[] args) {
System.out.println("asd");
}
/**
* 计算两个日期之间相差的天数
* @param smdate 较小的时间
* @param bdate 较大的时间
* @return 相差天数
* @throws ParseException
*/
public static int daysBetween(Date smdate,Date bdate) throws ParseException
{
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
smdate=sdf.parse(sdf.format(smdate));
bdate=sdf.parse(sdf.format(bdate));
Calendar cal = Calendar.getInstance();
cal.setTime(smdate);
long time1 = cal.getTimeInMillis();
cal.setTime(bdate);
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
/**
*字符串的日期格式的计算
*/
public static int daysBetween(String smdate,String bdate) throws ParseException{
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(smdate));
long time1 = cal.getTimeInMillis();
cal.setTime(sdf.parse(bdate));
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
public static Date addDateHour(Date date, int x) {// 返回的是字符串型的时间,输入的//是String
// 引号里面个格式也可以是 HH:mm:ss或者HH:mm等等,很随意的,不过在主函数调用时,要和输入的变
// 量day格式一致
if (date == null)
return new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR_OF_DAY, x);
return cal.getTime();
}
public static String dateFormatWithData(Date data, SimpleDateFormat format) {
return format.format(data);
}
public static Date dateFormatWithData(String data, SimpleDateFormat format) {
try {
return format.parse(data);
} catch (ParseException e) {
return null;
}
}
}
链接:https://pan.baidu.com/s/18hqm16SHjyhfray60bw38A
密码:002y
java 实现native 退款 java退款接口
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章