微信小程序快递java_java调用微信小程序统一下单接口

本文记录了在Java后端如何调用微信小程序的统一下单接口,包括获取用户OpenId、创建订单和生成预支付ID(prepay_id)的流程。详细介绍了关键代码和所需依赖库。
摘要由CSDN通过智能技术生成

java调用微信小程序统一下单接口

今天项目中对接微信支付这一块,记录一下

这是对接微信支付的开发文档地址

837a1c1e4014

微信支付流程

流程分析:

我们可以看到,前端人员只用给我们一个code,我们通过code去获取用户openId,然后生成订单,再调用微信支付统一下单API,微信返回给我们一个prepay_id,我们封装起来一起返给前端即可,前端支付成功了,微信会发送通知给我们的回调地址,我们更新订单状态即可,大致流程就是这样,这篇文章主要讲的就是调用统一下单API返回prepay_id的过程

代码部分:

/**

* 支付接口

*

* @param code 前端传的只能用一次的code

* @param oderInfo 订单信息接口

* @param response 响应

* @return ResultInfo 统一结果集

*/

@RequestMapping(value = "/weChat/getPrePayId/{code}")

@ResponseBody

@ApiOperation(value = "调用微信支付统一下单接口", notes = "调用微信支付统一下单接口", httpMethod = "POST")

public ResultInfo getPrePayId(@PathVariable(value = "code") String code,

@ApiParam(name = "oderInfo", value = "订单详细信息", required = true)

@RequestBody OrderBO oderInfo,

HttpServletResponse response) {

response.addHeader("Access-Control-Allow-Origin", "*");

ResultInfo resultInfo = new ResultInfo();

//通过code获取openId

JSONObject openIdResult;

try {

openIdResult = (JSONObject) WechatUtil.getMpAccessToken(code);

if (null == openIdResult) {

resultInfo.setMsg("结果解析为空!");

resultInfo.setCode(15115);

return resultInfo;

}

} catch (JSONException e) {

resultInfo.setMsg("结果解析不正确!");

resultInfo.setCode(15114);

return resultInfo;

}

String openId = openIdResult.getString("openid");

if (StringUtil.isEmpty(openId)) {

resultInfo.setMsg("获取用户openId出错,获得空的openId!");

resultInfo.setCode(15114);

return resultInfo;

}

//生成订单

//这块我就不贴出来了,毕竟涉及到具体的业务了

SortedMap params = new TreeMap<>();

//生成32位随机数

String nonce_str = create_nonce_str().replace("-", "");

String timestamp = create_timestamp();

//商户的秘钥,在https://pay.weixin.qq.com 中获取

String apiKey = ConstantWeChat.API_KEY;

//小程序ID

params.put("appid", ConstantWeChat.APPID);

//商户号

params.put("mch_id", ConstantWeChat.MCH_ID);

//openId

params.put("openid", openId);

//商品描述

params.put("body", "APP body");

//随机字符串,要求在32位以内

params.put("nonce_str", nonce_str);

//回调地址

params.put("notify_url","http://");

//订单号

params.put("out_trade_no", oderInfo.getOrderId());

//终端ip,调用微信支付API的机器IP,即本机的ip

params.put("spbill_create_ip", "");

//支付金额,total_fee传的单位是分,不能有小数点

int totalFee = (int) (oderInfo.getPayAmount() * 100);

params.put("total_fee", String.valueOf(totalFee));

//交易类型,小程序取值如下:JSAPI

params.put("trade_type", "JSAPI");

//生成签名

String sign = WechatUtil.createSign(params, apiKey);

params.put("sign", sign);

String prepayId = null;

String wxResult;

try {

// 将post的数据转换从xml格式

String xmlObj = WechatUtil.parseXML(params);

wxResult = WechatUtil.sendPost(HttpClients.createDefault(),

"https://api.mch.weixin.qq.com/pay/unifiedorder", xmlObj);

// 解析xml获取prepayId

// 记得引入dom4j的依赖

Document doc = DocumentHelper.parseText(wxResult);

//objMap 的大小为10的时候就是调用成功了

Map objMap = WechatUtil.Dom2Map(doc);

String returnCode = (String) objMap.get("return_code");

String resultCode = (String) objMap.get("result_code");

if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {

prepayId = (String) objMap.get("prepay_id");

}

params.put("package", "prepay_id=" + prepayId);

params.put("timestamp", timestamp);

} catch (Exception e) {

resultInfo.setMsg("解析错误!");

resultInfo.setCode(15114);

return resultInfo;

}

if (null == prepayId) {

resultInfo.setMsg("解析有误!");

resultInfo.setCode(15114);

return resultInfo;

}

SortedMap params2 = new TreeMap<>();

params2.put("appId", params.get("appid"));

params2.put("timeStamp", params.get("timestamp"));

params2.put("nonceStr", params.get("nonce_str"));

params2.put("package", "prepay_id=" + prepayId);

params2.put("signType", "MD5");

String sign2 = WechatUtil.createSign(params2, apiKey);

params2.put("paySign", sign2);

resultInfo.setData(params2);

resultInfo.setMsg("获取准备ID成功!");

return resultInfo;

}

private static String create_nonce_str() {

return UUID.randomUUID().toString();

}

private static String create_timestamp() {

return Long.toString(System.currentTimeMillis() / 1000);

}

用到的包

package com.miao.api.controller;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONException;

import com.alibaba.fastjson.JSONObject;

import com.miao.common.utils.ResultInfo;

import com.miao.common.utils.StringUtil;

import io.swagger.annotations.ApiOperation;

import io.swagger.annotations.ApiParam;

import org.apache.commons.lang.RandomStringUtils;

import org.apache.http.impl.client.HttpClients;

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;

import java.util.Map;

import java.util.SortedMap;

import java.util.TreeMap;

import java.util.UUID;

dom4j依赖

dom4j

dom4j

1.6.1

这是WechatUtil里面的方法

/**

* 生成微信支付签名

*

* @param parameters 参数

* @param apiKey 商户秘钥

* @return String

*/

public static String createSign(SortedMap parameters,

String apiKey) {

StringBuffer sb = new StringBuffer();

Set es = parameters.entrySet();

Iterator it = es.iterator();

while (it.hasNext()) {

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

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

Object v = entry.getValue();

if (null != v && !"".equals(v) && !"sign".equals(k)

&& !"key".equals(k)) {

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

}

}

// 最后加密时添加商户密钥,由于key值放在最后,所以不用添加到SortMap里面去,单独处理,编码方式采用UTF-8

sb.append("key=" + apiKey);

try {

String sign = MD5.encrypt(sb.toString(), "UTF-8").toUpperCase();

return sign;

} catch (Exception e) {

}

return null;

}

public static String parseXML(SortedMap parameters) {

StringBuffer sb = new StringBuffer();

sb.append("");

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

if (null != v && !"".equals(v) && !"appkey".equals(k)) {

sb.append("" + parameters.get(k) + "" + k + ">\n");

}

}

sb.append("");

return sb.toString();

}

public static String sendPost(CloseableHttpClient httpclient, String url, String xmlObj) throws IOException {

String result;

HttpPost httpPost = new HttpPost(url);

// 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别

StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");

httpPost.addHeader("Content-Type", "text/xml");

httpPost.setEntity(postEntity);

log.info(xmlObj);

try {

CloseableHttpResponse response = httpclient.execute(httpPost);

try {

HttpEntity entity = response.getEntity();

result = EntityUtils.toString(entity, "UTF-8");

} finally {

response.close();

}

} finally {

httpclient.close();

}

return result;

}

public static Map Dom2Map(Document doc) {

Map map = new HashMap<>(16);

if (doc == null) {

return map;

}

Element root = doc.getRootElement();

for (Iterator iterator = root.elementIterator(); iterator.hasNext(); ) {

Element e = (Element) iterator.next();

List list = e.elements();

if (list.size() > 0) {

map.put(e.getName(), Dom2Map(e));

} else {

map.put(e.getName(), e.getText());

}

}

return map;

}

参数校验地址:

//检验发送参数是否规范的地址

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1

提醒:

sign参数必须要在最后面生成,否则将生成错误的sign

######### 觉得还可以的话可以的话点个赞呗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值