java服务器端微信、支付宝支付和退款功能
工作需要,写了服务器端的支付和退款功能,包含微信和支付宝,网上也有很多demo可以借鉴,我把我的代码放出来,写的比较简单,有问题的欢迎指正,大家一起学习。
微信支付需要调用微信的统一下单接口,而支付宝不用。
我写的时候微信和支付宝都单独写了一个工具类,来调用支付,给前端返回需要的数据。
ps:支付是可以不需要服务器端的,不过为了安全一点点,所以前端需要调起支付的字段都直接从服务器端返回,前端拿到字段直接调起支付就可以了。
Mapmap=newHashMap (); switch(record.getCheckType()){ case10: map=Alipay.prePay(record.getAmount(),out_trade_no); returnResponseData.ok(map); case20: map=WXPay.prePay(record.getAmount(),out_trade_no); returnResponseData.ok(map); }
10是支付宝支付,20是微信支付,map里存放前端需要的字段,直接返回给手机端
其中out_trade_no这个是商户自己生成的唯一订单号
publicclassWXPay{ privatestaticStringurl=String.format("https://api.mch.weixin.qq.com/pay/unifiedorder"); //统一下单 publicstaticMapprePay(BigDecimalamount,Stringout_trade_no){ Stringentity=genProductArgs(amount,out_trade_no); byte[]buf=Util.httpPost(url,entity); Stringcontent=newString(buf); Map xml=decodeXml(content); returngetRep(xml); } privatestaticMap getRep(Map xml){ Randomrandom=newRandom(); List signParams=newLinkedList (); signParams.add(newBasicNameValuePair("appid",Constants.APP_ID_WX)); signParams.add(newBasicNameValuePair("noncestr",MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()))); //signParams.add(newBasicNameValuePair("package","prepay_id="+xml.get("prepay_id"))); signParams.add(newBasicNameValuePair("package","Sign=WXPay")); signParams.add(newBasicNameValuePair("partnerid",Constants.MCH_ID)); signParams.add(newBasicNameValuePair("prepayid",xml.get("prepay_id"))); signParams.add(newBasicNameValuePair("timestamp",String.valueOf(System.currentTimeMillis()/1000))); xml.put("sign",genPackageSign(signParams)); for(inti=0;i removeElements(Map 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"); returnxml; } privatestaticStringgenProductArgs(BigDecimalamount,Stringout_trade_no){ StringBufferxml=newStringBuffer(); StringnonceStr=genNonceStr(); xml.append(""); List packageParams=newLinkedList (); packageParams.add(newBasicNameValuePair("appid",Constants.APP_ID_WX)); packageParams.add(newBasicNameValuePair("body","APPpaytest")); packageParams.add(newBasicNameValuePair("mch_id",Constants.MCH_ID)); packageParams.add(newBasicNameValuePair("nonce_str",nonceStr)); packageParams.add(newBasicNameValuePair("notify_url","填写服务器的支付回调路径")); packageParams.add(newBasicNameValuePair("out_trade_no",out_trade_no)); packageParams.add(newBasicNameValuePair("spbill_create_ip","127.0.0.1")); packageParams.add(newBasicNameValuePair("total_fee",String.valueOf(amount.movePointRight(2)))); //packageParams.add(newBasicNameValuePair("total_fee","1")); packageParams.add(newBasicNameValuePair("trade_type","APP")); Stringsign=genPackageSign(packageParams); packageParams.add(newBasicNameValuePair("sign",sign)); Stringxmlstring=toXml(packageParams); returnxmlstring; } publicstaticStringgenNonceStr(){ Randomrandom=newRandom(); returnMD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } publicstaticStringgenPackageSign(List params){ StringBuildersb=newStringBuilder(); for(inti=0;i params){ StringBuildersb=newStringBuilder(); sb.append(" "); for(inti=0;i "); returnsb.toString(); } }"); sb.append(params.get(i).getValue()); sb.append(""+params.get(i).getName()+">"); } sb.append("
publicclassAlipay{ publicstaticMapprePay(BigDecimalpayAbleAmount,Stringout_trade_no){ //StringorderInfo=getOrderInfo("订单付款","订单付款",out_trade_no,"0.01"); StringorderInfo=getOrderInfo("订单付款","订单付款",out_trade_no,String.valueOf(payAbleAmount)); Stringsign=sign(orderInfo); try{ /** *仅需对sign做URL编码 */ sign=URLEncoder.encode(sign,"UTF-8"); }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } /** *完整的符合支付宝参数规范的订单信息 */ finalStringpayInfo=orderInfo+"&sign=\""+sign+"\"&"+getSignType(); Map map=newHashMap (); map.put("payInfo",payInfo); returnmap; } privatestaticStringgetOrderInfo(Stringsubject,Stringbody,Stringout_trade_no,Stringprice){ //签约合作者身份ID StringorderInfo="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\""; returnorderInfo; } privatestaticStringsign(Stringcontent){ returnSignUtils.sign(content,Constants.RSA_PRIVATE); } privatestaticStringgetSignType(){ return"sign_type=\"RSA\""; } }
退款部分
支付宝
StringstrResponse=null; AlipayTradeRefundResponseresponse=null; try{ AlipayClientalipayClient=newDefaultAlipayClient(url,Constants.APPID_ALIPAY,Constants.RSA_PRIVATE,"json","utf-8",Constants.RSA_PUBLIC); AlipayTradeRefundRequestrequest=newAlipayTradeRefundRequest(); RefundInfoalidata=newRefundInfo(); 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="退款失败"; } returnstrResponse; }catch(Exceptione){ strResponse="退款出错"; } returnstrResponse;
微信
publicclassWXRefund{ privatestaticfinalStringurl="https://api.mch.weixin.qq.com/secapi/pay/refund"; /** *微信退款 *@paramout_trade_no商户订单号 *@paramtotal_fee总金额 *@paramrefund_fee退款金额 *@return */ publicstaticStringdoRefund(Stringout_trade_no,inttotal_fee,intrefund_fee){ InputStreaminstream=null; KeyStorekeyStore=null; CloseableHttpResponseresponse=null; CloseableHttpClienthttpclient=null; StringBuildertext=newStringBuilder(); Stringkey=Constants.MCH_ID; try{ /** *注意PKCS12证书是从微信商户平台-》账户设置-》API安全中下载的 */ keyStore=KeyStore.getInstance("PKCS12"); instream=WXRefund.class.getResourceAsStream("/apiclient_cert.p12");//P12文件 /** *此处要改 */ keyStore.load(instream,key.toCharArray());//这里写密码..默认是MCHID /** *此处要改 */ SSLContextsslcontext=SSLContexts.custom().loadKeyMaterial(keyStore,key.toCharArray())//这里也是写密码的 .build(); //AllowTLSv1protocolonly SSLConnectionSocketFactorysslsf=newSSLConnectionSocketFactory(sslcontext,newString[]{"TLSv1"},null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); httpclient=HttpClients.custom().setSSLSocketFactory(sslsf).build(); //=======================证书配置完成======================== HttpPosthttpPost=newHttpPost(url); Stringxmlstring=getRefunArgs(out_trade_no,total_fee,refund_fee); httpPost.setEntity(newStringEntity(xmlstring)); httpPost.setHeader("Accept","application/json"); httpPost.setHeader("Content-type","application/json"); response=httpclient.execute(httpPost); HttpEntityentity=response.getEntity(); if(entity!=null){ BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(entity.getContent())); Stringstr; while((str=bufferedReader.readLine())!=null){ text.append(str); } } EntityUtils.consume(entity); }catch(Exceptione){ }finally{ if(instream!=null){ try{ instream.close(); }catch(IOExceptione){ e.printStackTrace(); } } if(response!=null){ try{ response.close(); }catch(IOExceptione){ e.printStackTrace(); } } if(httpclient!=null){ try{ httpclient.close(); }catch(IOExceptione){ e.printStackTrace(); } } } Mapmap=WXPay.decodeXml(text.toString()); Stringreturn_msg=map.get("return_msg"); if("OK".equals(return_msg)&&"SUCCESS".equals(map.get("return_code"))){ return"退款成功"; } returnreturn_msg; } //设置请求参数的值 privatestaticStringgetRefunArgs(Stringout_trade_no,inttotal_fee,intrefund_fee){ Stringnonce_str=WXPay.genNonceStr(); List packageParams=newLinkedList (); packageParams.add(newBasicNameValuePair("appid",Constants.APP_ID_WX)); packageParams.add(newBasicNameValuePair("mch_id",Constants.MCH_ID)); packageParams.add(newBasicNameValuePair("nonce_str",nonce_str)); packageParams.add(newBasicNameValuePair("op_user_id",Constants.MCH_ID)); packageParams.add(newBasicNameValuePair("out_refund_no",out_trade_no)); packageParams.add(newBasicNameValuePair("out_trade_no",out_trade_no)); packageParams.add(newBasicNameValuePair("refund_fee",String.valueOf(refund_fee))); packageParams.add(newBasicNameValuePair("total_fee",String.valueOf(total_fee))); Stringsign=WXPay.genPackageSign(packageParams); packageParams.add(newBasicNameValuePair("sign",sign)); returnWXPay.toXml(packageParams); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。