好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

工作需要,写了服务器端的支付和退款功能,包含微信和支付宝,网上也有很多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

查看更多关于java服务器端微信、支付宝支付和退款功能的详细内容...

  阅读:21次