服务器之家

服务器之家 > 正文

java服务器端微信、支付宝支付和退款功能

时间:2021-06-02 14:02     来源/作者:居家帅哥

工作需要,写了服务器端的支付和退款功能,包含微信和支付宝,网上也有很多demo可以借鉴,我把我的代码放出来,写的比较简单,有问题的欢迎指正,大家一起学习。

微信支付需要调用微信的统一下单接口,而支付宝不用。

我写的时候微信和支付宝都单独写了一个工具类,来调用支付,给前端返回需要的数据。

ps:支付是可以不需要服务器端的,不过为了安全一点点,所以前端需要调起支付的字段都直接从服务器端返回,前端拿到字段直接调起支付就可以了。

?
1
2
3
4
5
6
7
8
9
map<string,string> map = new hashmap<string,string>();
switch (record.getchecktype()) {
 case 10:
 map = alipay.prepay(record.getamount(),out_trade_no);
 return responsedata.ok(map);
 case 20:
 map = wxpay.prepay(record.getamount(),out_trade_no);
 return responsedata.ok(map);
}

10是支付宝支付,20是微信支付,map里存放前端需要的字段,直接返回给手机端

其中out_trade_no这个是商户自己生成的唯一订单号

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
public class wxpay {
 
 private static string url = string.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
 
 //统一下单
 public static map<string,string> prepay(bigdecimal amount,string out_trade_no){
 string entity = genproductargs(amount,out_trade_no);
 
 byte[] buf = util.httppost(url, entity);
 
 string content = new string(buf);
 map<string,string> xml=decodexml(content);
 return getrep(xml);
 }
 
 private static map<string, string> getrep(map<string, string> xml) {
 random random = new random();
 list<namevaluepair> signparams = new linkedlist<namevaluepair>();
 signparams.add(new basicnamevaluepair("appid", constants.app_id_wx));
 signparams.add(new basicnamevaluepair("noncestr", md5.getmessagedigest(string.valueof(random.nextint(10000)).getbytes())));
// signparams.add(new basicnamevaluepair("package", "prepay_id="+xml.get("prepay_id")));
 signparams.add(new basicnamevaluepair("package", "sign=wxpay"));
 signparams.add(new basicnamevaluepair("partnerid", constants.mch_id));
 signparams.add(new basicnamevaluepair("prepayid", xml.get("prepay_id")));
 signparams.add(new basicnamevaluepair("timestamp", string.valueof(system.currenttimemillis() / 1000)));
 xml.put("sign", genpackagesign(signparams));
 for (int i = 0; i < signparams.size(); i++) {
  xml.put(signparams.get(i).getname(),signparams.get(i).getvalue());
 }
 return removeelements(xml);
 }
 
 private static map<string, string> removeelements(map<string, string> xml) {
 xml.remove("appid");
 xml.remove("mch_id");
 xml.remove("nonce_str");
 xml.remove("trade_type");
 //xml.remove("partnerid");
 xml.remove("prepay_id");
 xml.remove("result_code");
 xml.remove("return_code");
 xml.remove("return_msg");
 return xml;
 }
 
 private static string genproductargs(bigdecimal amount,string out_trade_no) {
 stringbuffer xml = new stringbuffer();
 
 string noncestr = gennoncestr();
 
 xml.append("</xml>");
 list<namevaluepair> packageparams = new linkedlist<namevaluepair>();
 packageparams.add(new basicnamevaluepair("appid", constants.app_id_wx));
 packageparams.add(new basicnamevaluepair("body", "app pay test"));
 packageparams.add(new basicnamevaluepair("mch_id", constants.mch_id));
 packageparams.add(new basicnamevaluepair("nonce_str", noncestr));
 packageparams.add(new basicnamevaluepair("notify_url", "填写服务器的支付回调路径"));
 packageparams.add(new basicnamevaluepair("out_trade_no",out_trade_no));
 packageparams.add(new basicnamevaluepair("spbill_create_ip","127.0.0.1"));
 packageparams.add(new basicnamevaluepair("total_fee", string.valueof(amount.movepointright(2))));
// packageparams.add(new basicnamevaluepair("total_fee", "1"));
 packageparams.add(new basicnamevaluepair("trade_type", "app"));
 
 string sign = genpackagesign(packageparams);
 packageparams.add(new basicnamevaluepair("sign", sign));
 
 
 string xmlstring =toxml(packageparams);
 return xmlstring;
 }
 
 public static string gennoncestr() {
 random random = new random();
 return md5.getmessagedigest(string.valueof(random.nextint(10000)).getbytes());
 }
 
 public static string genpackagesign(list<namevaluepair> params) {
 stringbuilder sb = new stringbuilder();
 
 for (int i = 0; i < params.size(); i++) {
  sb.append(params.get(i).getname());
  sb.append('=');
  sb.append(params.get(i).getvalue());
  sb.append('&');
 }
 sb.append("key=");
 sb.append(constants.api_key);
 
 
 string packagesign = md5.getmessagedigest(sb.tostring().getbytes()).touppercase();
 return packagesign;
 }
 
 public static string toxml(list<namevaluepair> params) {
 stringbuilder sb = new stringbuilder();
 sb.append("<xml>");
 for (int i = 0; i < params.size(); i++) {
  sb.append("<"+params.get(i).getname()+">");
 
 
  sb.append(params.get(i).getvalue());
  sb.append("</"+params.get(i).getname()+">");
 }
 sb.append("</xml>");
 
 return sb.tostring();
 }
 
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public class alipay {
 
 public static map<string,string> prepay(bigdecimal payableamount,string out_trade_no){
 //string orderinfo = getorderinfo("订单付款", "订单付款",out_trade_no,"0.01");
 string orderinfo = getorderinfo("订单付款", "订单付款",out_trade_no,string.valueof(payableamount));
 
 string sign = sign(orderinfo);
 
 try {
  /**
  * 仅需对sign 做url编码
  */
  sign = urlencoder.encode(sign, "utf-8");
 } catch (unsupportedencodingexception e) {
  e.printstacktrace();
 }
 
 /**
  * 完整的符合支付宝参数规范的订单信息
  */
 final string payinfo = orderinfo + "&sign=\"" + sign + "\"&" + getsigntype();
 
 map<string,string> map = new hashmap<string, string>();
 map.put("payinfo", payinfo);
 return map;
 }
 
 private static string getorderinfo(string subject, string body,string out_trade_no,string price) {
 
 // 签约合作者身份id
 string orderinfo = "partner=" + "\"" + constants.partner + "\"";
 
 // 签约卖家支付宝账号
 orderinfo += "&seller_id=" + "\"" + constants.seller + "\"";
 
 // 商户网站唯一订单号
 orderinfo += "&out_trade_no=" + "\"" + out_trade_no + "\"";
 
 // 商品名称
 orderinfo += "&subject=" + "\"" + subject + "\"";
 
 // 商品详情
 orderinfo += "&body=" + "\"" + body + "\"";
 
 // 商品金额
 orderinfo += "&total_fee=" + "\"" + price + "\"";
 
 // 服务器异步通知页面路径
 orderinfo += "¬ify_url=" + "\"" + "填写服务器的支付回调路径" + "\"";
 
 
 // 服务接口名称, 固定值
 orderinfo += "&service=\"mobile.securitypay.pay\"";
 
 // 支付类型, 固定值
 orderinfo += "&payment_type=\"1\"";
 
 // 参数编码, 固定值
 orderinfo += "&_input_charset=\"utf-8\"";
 
 // 设置未付款交易的超时时间
 // 默认30分钟,一旦超时,该笔交易就会自动被关闭。
 // 取值范围:1m~15d。
 // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
 // 该参数数值不接受小数点,如1.5h,可转换为90m。
 orderinfo += "&it_b_pay=\"30m\"";
 
 // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
 // orderinfo += "&extern_token=" + "\"" + extern_token + "\"";
 
 // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
 orderinfo += "&return_url=\"m.alipay.com\"";
 
 // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
 // orderinfo += "&paymethod=\"expressgateway\"";
 
 return orderinfo;
 }
 
 
 private static string sign(string content) {
 return signutils.sign(content, constants.rsa_private);
 }
 
 private static string getsigntype() {
 return "sign_type=\"rsa\"";
 }
}

退款部分

支付宝

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
string strresponse = null;
alipaytraderefundresponse response = null;
try {
   alipayclient alipayclient = new defaultalipayclient(url,constants.appid_alipay,constants.rsa_private,"json","utf-8",constants.rsa_public);
   alipaytraderefundrequest request = new alipaytraderefundrequest();
      
   refundinfo alidata = new refundinfo();
   alidata.setout_trade_no(out_trade_no);
   alidata.setrefund_amount(refund_amount);
      
   request.setbizcontent(json.tojsonstring(alidata));
      
    response = alipayclient.sdkexecute(request);
     if (response.issuccess()) {
       strresponse="退款成功";
     } else {
     strresponse="退款失败";
     }
      
      return strresponse;
    } catch (exception e) {
     strresponse="退款出错";
    }
return strresponse;

微信

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
public class wxrefund {
 private static final string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
 
 /**
 * 微信退款
 * @param out_trade_no 商户订单号
 * @param total_fee 总金额
 * @param refund_fee 退款金额
 * @return
 */
 public static string dorefund(string out_trade_no,int total_fee,int refund_fee) {
 
 inputstream instream = null;
 keystore keystore = null;
 closeablehttpresponse response = null;
 closeablehttpclient httpclient = null;
 stringbuilder text = new stringbuilder();
 string key = constants.mch_id;
 try {
  /**
  * 注意pkcs12证书 是从微信商户平台-》账户设置-》 api安全 中下载的
  */
  keystore = keystore.getinstance("pkcs12");
  instream = wxrefund.class.getresourceasstream("/apiclient_cert.p12");//p12文件
  
  
  /**
  * 此处要改
  */
  keystore.load(instream, key.tochararray());// 这里写密码..默认是mchid
  
  /**
  * 此处要改
  */
  sslcontext sslcontext = sslcontexts.custom().loadkeymaterial(keystore, key.tochararray())// 这里也是写密码的
  .build();
  // allow tlsv1 protocol only
  sslconnectionsocketfactory sslsf = new sslconnectionsocketfactory(sslcontext, new string[] { "tlsv1" }, null, sslconnectionsocketfactory.browser_compatible_hostname_verifier);
  httpclient = httpclients.custom().setsslsocketfactory(sslsf).build();
  
  //=======================证书配置完成========================
  
  
  httppost httppost = new httppost(url);
  
  string xmlstring = getrefunargs(out_trade_no,total_fee,refund_fee);
  
  
  
  httppost.setentity(new stringentity(xmlstring));
  httppost.setheader("accept", "application/json");
  httppost.setheader("content-type", "application/json");
  
  response = httpclient.execute(httppost);
  
  httpentity entity = response.getentity();
  
  if (entity != null) {
  bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(entity.getcontent()));
  
  string str;
  while ((str = bufferedreader.readline()) != null) {
   text.append(str);
  }
  }
  entityutils.consume(entity);
 }catch(exception e){
  
 }finally {
  if(instream != null){
  try {
   instream.close();
  } catch (ioexception e) {
   e.printstacktrace();
  }
  }
  if(response != null){
  try {
   response.close();
  } catch (ioexception e) {
   e.printstacktrace();
  }
  }
  
  if(httpclient != null){
  try {
   httpclient.close();
  } catch (ioexception e) {
   e.printstacktrace();
  }
  }
 }
 map<string,string> map = wxpay.decodexml(text.tostring());
 string return_msg = map.get("return_msg");
 if ("ok".equals(return_msg) && "success".equals(map.get("return_code"))) {
  return "退款成功";
 }
 return return_msg;
 }
 
 //设置请求参数的值
 private static string getrefunargs(string out_trade_no,int total_fee,int refund_fee) {
 string nonce_str = wxpay.gennoncestr();
 list<namevaluepair> packageparams = new linkedlist<namevaluepair>();
 packageparams.add(new basicnamevaluepair("appid", constants.app_id_wx));
 packageparams.add(new basicnamevaluepair("mch_id", constants.mch_id));
 packageparams.add(new basicnamevaluepair("nonce_str", nonce_str));
 packageparams.add(new basicnamevaluepair("op_user_id", constants.mch_id));
 packageparams.add(new basicnamevaluepair("out_refund_no",out_trade_no));
 packageparams.add(new basicnamevaluepair("out_trade_no",out_trade_no));
 packageparams.add(new basicnamevaluepair("refund_fee", string.valueof(refund_fee)));
 packageparams.add(new basicnamevaluepair("total_fee", string.valueof(total_fee)));
 
 string sign = wxpay.genpackagesign(packageparams);
 packageparams.add(new basicnamevaluepair("sign", sign));
 
 
 return wxpay.toxml(packageparams);
 
 }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/l269327509/article/details/53518401

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部