微信支付 java_java 微信支付实现

一、业务需求

实现app微信支付,后端需要做生成预支付单,响应支付结果

二、业务流程

查看官方文档

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3

三、实现方法

3.1 创建微信工具类  ConstantUtil

public classConstantUtil {/*** 微信开发平台应用ID*/

public static final String APP_ID="wx2421b1c4370ec43b";/*** 应用对应的凭证*/

public static final String APP_SECRET="1add1a30ac87aa2db72f57a2375d8fec";/*** 应用对应的密钥*/

public static final String APP_KEY="1add1a30ac87aa2db72f57a2375d8fec";/*** 微信支付商户号*/

public static final String MCH_ID="10000100";/*** 商品描述*/

public static final String BODY="充值";/*** 商户号对应的密钥*/

public static final String PARTNER_key="*******";/*** 商户id*/

public static final String PARTNER_ID="*******";/*** 常量固定值*/

public static final String GRANT_TYPE="client_credential";/*** 获取预支付id的接口url*/

public static String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";/*** 微信服务器回调通知url*/

public static String NOTIFY_URL="http://url"; //可以访问的url/*** 微信服务器查询订单url*/

public static String ORDER_QUERY="https://api.mch.weixin.qq.com/pay/orderquery";

}

3.2 生成预支付订单

Map getOrder(@RequestParam(value = "totalFee") String totalFee, @RequestParam(value = "deviceInfo") String deviceInfo,

@RequestParam(value= "attach") String attach,

HttpServletRequest request, HttpServletResponse response)throwsException {

Map map = new HashMap();//获取生成预支付订单的请求类

PrepayIdRequestHandler prepayReqHandler = newPrepayIdRequestHandler(request, response);//String totalFee = request.getParameter("total_fee");

int total_fee = (int) (Float.valueOf(totalFee) * 100);

System.out.println("total:" +total_fee);

System.out.println("total_fee:" +total_fee);

prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);

prepayReqHandler.setParameter("body", ConstantUtil.BODY);

prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID);

prepayReqHandler.setParameter("device_info", deviceInfo); //卡号

prepayReqHandler.setParameter("attach", attach);//套餐值

String nonce_str =WXUtil.getNonceStr();

prepayReqHandler.setParameter("nonce_str", nonce_str);

prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL);

out_trade_no=String.valueOf(UUID.next());

prepayReqHandler.setParameter("out_trade_no", out_trade_no);

prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr());

String timestamp=WXUtil.getTimeStamp();

prepayReqHandler.setParameter("time_start", timestamp);

System.out.println(String.valueOf(total_fee));

prepayReqHandler.setParameter("total_fee", String.valueOf(total_fee));

prepayReqHandler.setParameter("trade_type", "APP");/*** 注意签名(sign)的生成方式,具体见官方文档(传参都要参与生成签名,且参数名按照字典序排序,最后接上APP_KEY,转化成大写)*/prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());

prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);

String prepayid=prepayReqHandler.sendPrepay();//若获取prepayid成功,将相关信息返回客户端

if (prepayid != null && !prepayid.equals("")) {

String signs= "appid=" + ConstantUtil.APP_ID + "&noncestr=" + nonce_str + "&package=Sign=WXPay&partnerid="

+ ConstantUtil.PARTNER_ID + "&prepayid=" + prepayid + "&timestamp=" + timestamp + "&key="

+ConstantUtil.APP_KEY;

map.put("code", 0);

map.put("info", "success");

map.put("prepayid", prepayid);/*** 签名方式与上面类似*/map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());

map.put("appid", ConstantUtil.APP_ID);

map.put("device_info", deviceInfo);

map.put("attach", attach);

map.put("timestamp", timestamp); //等于请求prepayId时的time_start

map.put("noncestr", nonce_str); //与请求prepayId时值一致

map.put("package", "Sign=WXPay"); //固定常量

map.put("partnerid", ConstantUtil.PARTNER_ID);

}else{

map.put("code", 1);

map.put("info", "获取prepayid失败");

}returnmap;

}

3.3  异步通知客户结果

PrintWriter writer =response.getWriter();

InputStream inStream=request.getInputStream();

ByteArrayOutputStream outSteam= newByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {

outSteam.write(buffer,0, len);

}

outSteam.close();

inStream.close();

String result= new String(outSteam.toByteArray(), "utf-8");

System.out.println("微信支付通知结果:" +result);

Map map = null;try{/*** 解析微信通知返回的信息*/map=XMLUtil.doXMLParse(result);

}catch(JDOMException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

官方文档中特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失

支付结果通知内容做签名验证

//支付成功后sign校验

String appid=map.get("appid");

String transaction_id=map.get("transaction_id");

String nonce_str =map.get("nonce_str");

String bank_type =map.get("bank_type");

String openid=map.get("openid");

String sign =map.get("sign");

String fee_type =map.get("fee_type");

String mch_id =map.get("mch_id");

String cash_fee =map.get("cash_fee");

String device_info =map.get("device_info");

String out_trade_no =map.get("out_trade_no");

String total_fee =map.get("total_fee");

String trade_type =map.get("trade_type");

String result_code =map.get("result_code");

String attach =map.get("attach");

String time_end =map.get("time_end");

String is_subscribe =map.get("is_subscribe");

String return_code=map.get("return_code");

PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);

prepayReqHandler.setParameter("appid",appid);

prepayReqHandler.setParameter("attach",attach);

prepayReqHandler.setParameter("bank_type",bank_type);

prepayReqHandler.setParameter("cash_fee",cash_fee);

prepayReqHandler.setParameter("device_info",device_info);

prepayReqHandler.setParameter("fee_type",fee_type);

prepayReqHandler.setParameter("is_subscribe",is_subscribe);

prepayReqHandler.setParameter("mch_id",mch_id);

prepayReqHandler.setParameter("nonce_str",nonce_str);

prepayReqHandler.setParameter("openid",openid);

prepayReqHandler.setParameter("out_trade_no",out_trade_no);

prepayReqHandler.setParameter("result_code",result_code);

prepayReqHandler.setParameter("return_code",return_code);

prepayReqHandler.setParameter("time_end",time_end);

prepayReqHandler.setParameter("total_fee",total_fee);

prepayReqHandler.setParameter("trade_type",trade_type);

prepayReqHandler.setParameter("transaction_id",transaction_id);

String endSigns =prepayReqHandler.createMD5Sign(); //支付结果通知的内容 签名校验

商户金额的查询

PrepayIdRequestHandler orderQueryHandler = newPrepayIdRequestHandler(request, response);

orderQueryHandler.setParameter("appid",appid);

orderQueryHandler.setParameter("mch_id",mch_id);

orderQueryHandler.setParameter("out_trade_no",out_trade_no);

orderQueryHandler.setParameter("nonce_str",nonce_str);

orderQueryHandler.setParameter("sign",orderQueryHandler.createMD5Sign());

orderQueryHandler.setGateUrl(ConstantUtil.ORDER_QUERY);

String resXml= "";

WeixinOrderBean orderBean=orderQueryHandler.selectOrder();

应答微信

if(sign.equals(endSigns) && Integer.parseInt(total_fee)==orderBean.getTotal_fee()){ //签名通过并且返回的订单的金额与商户金额相同//若支付成功,则告知微信服务器收到通知

if (map.get("return_code").equals("SUCCESS")) {

System.out.println("充值成功!");//PayRecord payRecord=payRecordService.get(Long.valueOf(map.get("out_trade_no")));

System.out.println("订单号:" + Long.valueOf(map.get("out_trade_no")));

String iccids= map.get("device_info");

String monthNum= map.get("attach");

//根据自己的业务处理int count =trafficCardListService.selectExistTrafficCardByOutTradeNo(map.get("out_trade_no")); //查询商户订单号是否存在

if(count==0){//不存在就插入

List msisdnOrderList =trafficCardListService.selectTrafficCardRechargeResult(iccids, monthNum);if (msisdnOrderList.size() > 0) {for(MsisdnOrderBean msisdnOrderBean : msisdnOrderList) {

msisdnOrderBean.setOutTradeNo(map.get("out_trade_no"));

msisdnOrderBean.setDate(map.get("time_end"));

msisdnOrderBean.setIccids(map.get("device_info"));//msisdnOrderBean.setTotalFee(Integer.parseInt(map.get("total_fee")));

msisdnOrderBean.setTotalFee(BigDecimal.valueOf(Integer.parseInt(map.get("total_fee"))).divide(new BigDecimal(100)).doubleValue());

msisdnOrderBean.setTransactionId(map.get("transaction_id"));

msisdnOrderBean.setTrafficNo(DateUtils.getNowDataTime()+ ApiUtils.getFourRandom()); //年月日时分秒+四位随机数

trafficCardListService.insertTrafficCardList(msisdnOrderBean);

}

}

}

resXml= XMLUtil.setXML("SUCCESS", "OK");

}else{

resXml= "" + ""

+ "" + " ";

logger.info("通知签名验证失败");

}

}else{

resXml=XMLUtil.setXML("FAIL", "签名不一致");

}

writer.write(resXml);

writer.flush();

writer.close();

运用到的 PrepayIdRequestHandler  工具类

public class PrepayIdRequestHandler extendsRequestHandler {publicPrepayIdRequestHandler(HttpServletRequest request,

HttpServletResponse response) {super(request, response);

}publicString createMD5Sign() {

StringBuffer sb= newStringBuffer();

Set es= super.getAllParameters().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();

sb.append(k+ "=" + v + "&");

}

String params=sb.append("key="+ConstantUtil.APP_KEY).substring(0);

String sign= MD5Util.MD5Encode(params, "utf8");returnsign.toUpperCase();

}//提交预支付

public String sendPrepay() throwsException {

String prepayid= "";

Set es=super.getAllParameters().entrySet();

Iterator it=es.iterator();

StringBuffer sb= new StringBuffer("");while(it.hasNext()){

Map.Entry entry=(Map.Entry) it.next();

String k=(String) entry.getKey();

String v=(String) entry.getValue();

sb.append(""+v+""+k+">");

}

sb.append("");

String params=sb.substring(0);

System.out.println("请求参数:"+params);

String requestUrl= super.getGateUrl();

System.out.println("请求url:"+requestUrl);

TenpayHttpClient httpClient= newTenpayHttpClient();

httpClient.setReqContent(requestUrl);

String resContent= "";if(httpClient.callHttpPost(requestUrl, params)) {

resContent=httpClient.getResContent();

System.out.println("获取prepayid的返回值:"+resContent);

Map map=XMLUtil.doXMLParse(resContent);if(map.containsKey("prepay_id"))

prepayid=map.get("prepay_id");

}returnprepayid;

}//查询订单

public WeixinOrderBean selectOrder() throwsException {

Set es=super.getAllParameters().entrySet();

Iterator it=es.iterator();

StringBuffer sb= new StringBuffer("");while(it.hasNext()){

Map.Entry entry=(Map.Entry) it.next();

String k=(String) entry.getKey();

String v=(String) entry.getValue();

sb.append(""+v+""+k+">");

}

sb.append("");

String params=sb.substring(0);

System.out.println("请求参数:"+params);

String requestUrl= super.getGateUrl();

System.out.println("请求url:"+requestUrl);

TenpayHttpClient httpClient= newTenpayHttpClient();

httpClient.setReqContent(requestUrl);

String resContent= "";

WeixinOrderBean orderBean=newWeixinOrderBean();if(httpClient.callHttpPost(requestUrl, params)) {

resContent=httpClient.getResContent();

Map map=XMLUtil.doXMLParse(resContent);if(map.size()>0){

orderBean.setAppid(map.get("appid"));

orderBean.setAttach(map.get("attach"));

orderBean.setDevice_info(map.get("device_info"));

orderBean.setBank_type(map.get("bank_type"));

orderBean.setMch_id(map.get("mch_id"));

orderBean.setNonce_str(map.get("nonce_str"));

orderBean.setTotal_fee(Integer.parseInt(map.get("total_fee")));

orderBean.setTrade_state(map.get("trade_state"));

}

}returnorderBean;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值