目前国内最火的支付方式,不用思考也能立刻说出来,那就是微信支付。
根据网络数据(是否正确暂未知),微信支付总量已超出支付宝支付。本人倾向与使用支付宝支付,微信仅用于沟通等。
言归正传,以下是与微信交互的经验,遇到的坑也有ꉂ (๑¯ਊ¯)σhhh…
准备工作
使用支付功能,当然要注册微信的各种帐号,最郁闷的就是,APP开发需要 微信开放平台 帐号,若有支付,就要关联一个商户平台帐号;然后要是公众号开发,就要 微信公众平台 帐号,若支付功能开通,又双叒叕需要一个商户平台账号;要是还有小程序,那不用想,再注册一个小程序账号,不过呢, 不用再注册商户平台帐号了,和之前公众平台对应的商户平台帐号绑定就行。
微信小程序中根据CODE获取用户ID
@Controller
@RequestMapping(value = {
"/requestof/wechat" })
public class WechatController {
// 微信根据code获取openid
// code 是微信小程序中,用户同意授权后获取到的,当作参数传递过来
@ResponseBody
@RequestMapping(value = {
"/gain/openid_string" })
public String gainOpenId(String code) throws Exception {
// Map自动转换为Json
Map<String,Object> dataMap = new HashMap<>(8,0.1f);
String strURL = "https://api.weixin.qq.com/sns/jscode2session";
String str2 ="?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
String finalURL = String.format(strURL + str2,
"微信小程序AppID", "对应密钥", code);
// 发送HTTP请求,使用Java原生URL、HttpClient等等均可
String json = httpsRequest(finalURL, "GET", null);
if (json == null || json.trim().equals("")) {
throw new RuntimeException("Fail to get access token string "+json);
} else {
/// 解析数据 ///
@SuppressWarnings("unchecked")
Map<String, String> tokenMap = GsonUtil.fromJson(json, Map.class);
return tokenMap.get("openid");
}
}
}
根据自有服务器程序返回参数,自有APP调起微信支付
@Controller
@RequestMapping(value = {
"/requestof/wechat" })
public class WechatController {
/**
* 获取调起支付的参数
*/
@ResponseBody
@RequestMapping(value = {
"/pre/callFor/payment" })
public Map<String,Object> preCallForPayment(String account,int fee) {
// Map自动转换为Json
Map<String,Object> dataMap = new HashMap<>(8,0.1f);
// 随机数
String strOfR = RandomStringUtils.randomAlphanumeric(24);
SortedMap<String, String> parameterMap = new TreeMap<String, String>();
parameterMap.put("appid", "微信开放平台APPID");
parameterMap.put("mch_id", "开放平台对应的商户平台APPID");
parameterMap.put("nonce_str", strOfR);
parameterMap.put("body", "自定义字符串,如 缴费支付");
parameterMap.put("out_trade_no", "自定义交易订单号,如 2021010110101234567890");
parameterMap.put("fee_type", "CNY");
parameterMap.put("total_fee", fee + ""); // 注意,此处单位为 分
parameterMap.put("spbill_create_ip", "我的公网IP地址");
parameterMap.put("notify_url", "微信支付结果回调URL");
parameterMap.put("trade_type", "APP");
// 生成数据摘要签名字符串
String sign = createSign("UTF-8", parameterMap);
parameterMap.put("sign", sign);
// 要求XML格式数据 ///
String requestXML = mapToXml(parameterMap);
// 发送HTTP请求,使用Java原生URL、HttpClient等等均可
String resultXML = request(WxUtil.UnifiedOrderURL(), requestXML);
// 返回的XML格式数据转为MAP
Map<String, String> resultMap = doXMLParse(resultXML);
// 判断数据并返回给客户端用于调起微信支付
if (resultMap.containsKey("result_code")
&& "SUCCESS".equals(resultMap.get("result_code"))) {
/// 二次签名 ///
long currentTimeMillis = System.currentTimeMillis();// 生成时间戳
long second = currentTimeMillis / 1000L; /// (转换成秒)
String seconds = String.valueOf(second).substring(0, 10);/// (截取前10位)
//
SortedMap<String, String> signParam = new TreeMap<String, String>();
signParam.put("appid", "微信开放平台APPID");
signParam.put("partnerid", "开放平台对应的商户平台APPID");
signParam.put("prepayid", resultMap.get("prepay_id")); // 订单id
signParam.put("package", "Sign=WXPay");
signParam.put("noncestr", strOfR);
signParam.put("timestamp", seconds);
String signAgain = createSign("UTF-8", signParam); // 再次生成签名
dataMap.put("signAgain", signAgain);
dataMap.put("noncestr", strOfR);
dataMap.put("timestamp", seconds);
dataMap.put("out_trade_no", "自定义交易订单号,如 2021010110101234567890");
} else {
dataMap.put("err_msg", "操作失败,请重试!");
}
return dataMap;
}
// 微信支付结果回调
@RequestMapping(value = {
"/payment/callback" }, produces = {
"text/xml" })
public void paymentCallback(
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setCharacterEncoding("UTF-8")