微信继续支付java实现_Java 从零开始实现微信支付(后台)

框架使用的是spring boot

我们集成微信支付 也就需要提供两个接口出来.一个是给前端 作用是拿到请求参数加签请求统一下单接口,得到预支付id,然后再加签返回给前端

前端拿到我们返回的数据.进行调起支付就行了,第二个接口是提供给微信支付的服务器,支付成功或者失败的时候.微信服务器会回调我们的这个接口.异步通知我们支付结果

好了.废话不哆嗦,直接上代码:

@RestController

@RequestMapping("/wxpayment")

public class WxPaymentController {

public static final String WXUNIFIEDORDER_HTTPURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";// 微信统一下单接口

public static final String APP_ID = "";// 微信appid

public static final String MCH_ID = "";// 商户号

public static final String API_KEY = "";// apikey

/**

* 对微信支付信息进行签名

*

* @param info

* 数据类

* @return

* @throws AlipayApiException

* @throws UnsupportedEncodingException

*/

@PostMapping("/sign")

public Object sign(@RequestBody WXSignInfo wxSignInfo, HttpServletRequest httpServletRequest)

throws AlipayApiException, UnsupportedEncodingException {

String create_ip = NetStateUtils.getIpAddr(httpServletRequest);

ResponseWxSign4App response = new ResponseWxSign4App();

response.setResult(wxUnifiedorder(create_ip, wxSignInfo.Content));

String result = GsonUtils.object2Json(response);

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

return result;

}

/**

* 微信支付成功后.微信服务器会回调该接口

*

* @param request

* @return

* @throws UnsupportedEncodingException

*/

@PostMapping("/notify")

public String notify(HttpServletRequest request) throws UnsupportedEncodingException {

System.out.println("notify come");

Response2WxPayServer response2WxPayServer = new Response2WxPayServer();

;

// 读取 入参

StringBuilder sb = new StringBuilder();

try {

BufferedReader br = new BufferedReader(

new InputStreamReader((ServletInputStream) request.getInputStream()));

String line = null;

while ((line = br.readLine()) != null) {

sb.append(line);

}

System.out.println("request:" + sb);

} catch (Exception e) {

e.printStackTrace();

System.out.println("微信支付回调读取入参发生异常.直接返回更新失败");

response2WxPayServer.setReturn_code(Constants.FAIL);

response2WxPayServer.setReturn_msg("unknown");

return XmlUtils.toXml(response2WxPayServer);

}

XStream xStream = new XStream();

xStream.alias("xml", WxNotifyBean.class);

WxNotifyBean wxNotifyBean = (WxNotifyBean) xStream.fromXML(sb.toString());

System.out.println("notify info:" + GsonUtils.object2Json(wxNotifyBean));

if (null != wxNotifyBean && wxNotifyBean.getReturn_code().equals(Constants.SUCCESS)

&& wxNotifyBean.getResult_code().equals(Constants.SUCCESS)) {// 支付成功

String result = PaymentController.updateALiPayOrderStatus(wxNotifyBean.getOut_trade_no());

System.out.println("验证成功,去更新状态 \t订单号:" + wxNotifyBean.getOut_trade_no() + "来自微信支付,更新结果:" + result);

BaseResponse baseResponse = GsonUtils.getGson().fromJson(result, BaseResponse.class);

if (null != baseResponse && baseResponse.isSucceeded) {

response2WxPayServer.setReturn_code(Constants.SUCCESS);

} else {

response2WxPayServer.setReturn_code(Constants.FAIL);

response2WxPayServer.setReturn_msg("unknown");

}

} else {

// 支付失败

response2WxPayServer.setReturn_code(Constants.FAIL);

response2WxPayServer.setReturn_msg("unknown");

}

return XmlUtils.toXml(response2WxPayServer);

}

// https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3 文档地址

/**

* 微信统一下单接口

*

* @param orderNumber

* @return

*/

public Return4AppWxPayBean wxUnifiedorder(String create_ip, RequestUnifiedOrderBean requestUnifiedOrderBean) {

requestUnifiedOrderBean.setNonce_str(NumUtils.getRandomStringByDate());

requestUnifiedOrderBean.setSign("");

requestUnifiedOrderBean.setSpbill_create_ip(create_ip);

HashMap hashMap = getHashMap2SignFromRequestUnifiedOrderBean(requestUnifiedOrderBean);

String sign = addSign(hashMap);

if (null == sign) {

return null;

}

requestUnifiedOrderBean.setSign(sign);

String requestContent = XmlUtils.getXstream().toXML(requestUnifiedOrderBean);

requestContent = requestContent.replaceAll("__", "_");// xstream

// 转换的时候会把单个下划线弄成两个,所以这里替换下

String result = HttpUtils.doPost(WXUNIFIEDORDER_HTTPURL, requestContent);

System.out.println("微信统一下单接口 返回结果:" + result);

if (TextUtils.isEmpty(result)) {// 统一下单都失败了.直接返回null

return null;

}

XStream xstream = XmlUtils.getXstream();

xstream.alias("xml", ResponseUnifiedOrderBean.class);// xml对应ResponseUnifiedOrderBean的根节点的名字

ResponseUnifiedOrderBean responseUnifiedOrderBean = (ResponseUnifiedOrderBean) xstream.fromXML(result);

if (responseUnifiedOrderBean.getReturn_code().equals("SUCCESS")

&& responseUnifiedOrderBean.getResult_code().equals("SUCCESS")) {// 全为成功.则进行相应的处理

// 分割线

Return4AppWxPayBean return4AppWxPayBean = new Return4AppWxPayBean();

return4AppWxPayBean.setNonceStr(responseUnifiedOrderBean.getNonce_str());

return4AppWxPayBean.setPrepayId(responseUnifiedOrderBean.getPrepay_id());

// return4AppWxPayBean.setSign(responseUnifiedOrderBean.getSign());

return4AppWxPayBean.setTimeStamp("" + TimeUtils.getTime_Second());

// 再次签名appid,partnerid等全部参数必须全小写

HashMap hashMap2Sign = getHashMap2SignFromReturn4AppWxPayBean(return4AppWxPayBean);

String sign1 = addSign(hashMap2Sign);

if (null == sign1) {

return null;

}

return4AppWxPayBean.setSign(sign1);

return return4AppWxPayBean;

} else {

return null;

}

}

/**

* 从requestUnifiedOrderBean 拿到一个待签名的hashmap

*

* @param requestUnifiedOrderBean

* @return

*/

private HashMap getHashMap2SignFromRequestUnifiedOrderBean(

RequestUnifiedOrderBean requestUnifiedOrderBean) {

HashMap hashMap = new HashMap<>();

hashMap.put("appid", requestUnifiedOrderBean.getAppid());

hashMap.put("device_info", requestUnifiedOrderBean.getDevice_info());

hashMap.put("mch_id", requestUnifiedOrderBean.getMch_id());

hashMap.put("nonce_str", requestUnifiedOrderBean.getNonce_str());

hashMap.put("notify_url", requestUnifiedOrderBean.getNotify_url());

hashMap.put("spbill_create_ip", requestUnifiedOrderBean.getSpbill_create_ip());

hashMap.put("trade_type", requestUnifiedOrderBean.getTrade_type());

hashMap.put("body", requestUnifiedOrderBean.getBody());

hashMap.put("total_fee", requestUnifiedOrderBean.getTotal_fee() + "");

hashMap.put("out_trade_no", requestUnifiedOrderBean.getOut_trade_no());

return hashMap;

}

/**

* 把信息从return4AppWxPayBean弄到hashmap里面

*

* @param return4AppWxPayBean

* @return

*/

private HashMap getHashMap2SignFromReturn4AppWxPayBean(Return4AppWxPayBean return4AppWxPayBean) {

HashMap hashMap2Sign = new HashMap<>();

hashMap2Sign.put("appid", return4AppWxPayBean.getAppId());

hashMap2Sign.put("partnerid", return4AppWxPayBean.getPartnerId());

hashMap2Sign.put("prepayid", return4AppWxPayBean.getPrepayId());

hashMap2Sign.put("noncestr", return4AppWxPayBean.getNonceStr());

hashMap2Sign.put("timestamp", return4AppWxPayBean.getTimeStamp());

hashMap2Sign.put("package", "Sign=WXPay");

return hashMap2Sign;

}

/**

* 对hashmap进行加签

*

* @param hashMap2Sign

* @return

*/

private String addSign(HashMap hashMap2Sign) {

String stringA2Sign = AlipayCore.createLinkString(hashMap2Sign);

String stringSignTemp2Sign = stringA2Sign + "&key=" + API_KEY;

String md5 = EncodeUtils.md5(stringSignTemp2Sign);

if (null == md5) {// 签名失败 直接返回null

return null;

}

String sign1 = md5.toUpperCase();

return sign1;

}

}

createLinkString方法是把一个hashmap依据参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string,方法实现如下:

/**

* 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串

* @param params 需要排序并参与字符拼接的参数组

* @return 拼接后字符串

*/

public static String createLinkString(Map params) {

List keys = new ArrayList(params.keySet());

Collections.sort(keys);

String prestr = "";

for (int i = 0; i < keys.size(); i++) {

String key = keys.get(i);

String value = params.get(key);

if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符

prestr = prestr + key + "=" + value;

} else {

prestr = prestr + key + "=" + value + "&";

}

}

return prestr;

}

说一下遇到的坑:

1.加签的时候appid和别的参数都是小写,并不是appId这种形式

2.本地服务器支付没问题.部署到win server2012服务器上时,签名失败,这个是因为本地服务器win8 默认utf-8编码,而win server 2012 默认 gbk编码,我们加签,进行md5编码的时候,把格式指定为utf-8就好了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值