微信支付之企业付款到个人(提现)
发布日期:2021-05-15 06:52:35 浏览次数:20 分类:精选文章

本文共 4637 字,大约阅读时间需要 15 分钟。

微信支付集成开发指南:从证书到支付回调

由于这是一个新商户的集成开发项目,按照标准流程进行操作,是一个需要细致处理的任务。以下将详细介绍从获取证书、依赖管理、代码开发到支付回调的各个环节,帮助大家顺利完成微信支付功能的实现。

第一步:证书准备

首先,需要下载相关的支付证书,通常情况下,这些证书会以p12格式提供。请自行下载后,将它们放置在项目路径下的src/main/resources下。这里通常是Store_password 为商户号的情况,需要注意保存路径是否正确。

第二步:依赖管理

在项目的依赖中添加必要的库。以下是推荐的版本:

  • kxml2:用于解析支付宝或微信的 XML 结构,版本 2.3.0
  • xmlpull:处理 XML 数据,版本 1.1.3.1
  • httpclient:用于 HTTP 请求,提供基本的通信功能

在 Maven 项目中,这些依赖可以通过添加如下 dependencys 进行配置:

net.sf.kxml
kxml2
2.3.0
xmlpull
xmlpull
1.1.3.1
org.apache.httpcomponents
httpclient
4.2.8

第三步:支付功能开发

根据现有的代码框架,我们可以看到这是一个基本的微信支付功能接口。

@RequestMapping("/wechat/cash")
@CrossOrigin
public Map
cash(
@RequestParam("openId") String openId,
@RequestParam("amount") String amount,
HttpServletRequest request
) {
final Map
result = new HashMap<>();
try {
final UserInfo userInfo = iUserInfoService.queryByUserId(userId);
if (null == userInfo) {
result.put("code", 0);
result.put("msg", "用户不存在");
return result;
}
if (null == userInfo.getOpenid()) {
result.put("code", 0);
result.put("msg", "openid 为空,请先去授权");
return result;
}
// 校验余额
final UserAccount userAccount = iUserAccountService.queryByUserId(userId);
if (null != userAccount) {
if (userAccount.getAccountAmount().compareTo(new BigDecimal(amount)) == -1) {
result.put("code", 0);
result.put("msg", "余额不足");
return result;
}
}
// 获取请求IP地址
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.contains(",")) {
final String[] ips = ip.split(",");
ip = ips[0].trim();
}
// 生成订单号
final String newDate = DateUtil.getDateFormat(new Date(), "yyyyMMddHHmmss");
final String partnerTradeNo = newDate + "UID" + userInfo.getId();
// 参数准备
final Map
paraMap = new HashMap<>();
paraMap.put("mch_appid", WXPayConstants.APP_ID);
paraMap.put("mchid", WXPayConstants.MCH_ID);
final String nonceStr = WXPayUtil.generateNonceStr();
paraMap.put("nonce_str", nonceStr);
paraMap.put("partner_trade_no", partnerTradeNo);
paraMap.put("openid", userInfo.getOpenid());
paraMap.put("check_name", "NO_CHECK");
paraMap.put("amount", money);
paraMap.put("desc", "提现" + amount + "元");
paraMap.put("spbill_create_ip", ip);
// 生成签名
final String sign = WXPayUtil.generateSignature(paraMap, WXPayConstants.MCH_SECRET);
// 添加签名字段
paraMap.put("sign", sign);
// 生成XML参数
final String xml = WXPayUtil.mapToXml(paraMap);
// 发起支付请求
final String xmlStr = HttpClientUtil.posts(WXPayConstants.MAC_PAY_URL, xml);
// 解析返回结果
final Map
map = WXPayUtil.xmlToMap(xmlStr);
if (CollectionUtil.isNotEmpty(map) && "SUCCESS".equals(map.get("result_code"))) {
// 成功处理逻辑
iUserAccountService.cashSuccess(userInfo, amount);
result.put("code", 1);
} else {
if (CollectionUtil.isNotEmpty(map)) {
result.put("msg", "提现失败:" + map.get("err_code") + ":" + map.get("err_code_des"));
}
result.put("code", 0);
}
} catch (Exception e) {
e.printStackTrace();
result.put("code", 0);
result.put("msg", "提现失败");
}
return result;
}

模块功能说明

该代码实现了以下功能:

  • 获取用户信息,验证用户身份和openid。
  • 校验用户的余额是否足够。
  • 确定请求的真实IP地址。
  • 生成订单流水号和唯一标识符。
  • 组装支付参数。
  • 生成签名,确保支付请求的安全性。
  • 发起HTTPS POST 请求。
  • 解析微信支付返回结果。
  • 根据支付结果进行相应的业务处理。
  • 常见错误处理

    由于这是一个新商户,可能会遇到以下常见错误:

  • "安全证书校验失败":请确认 tls版本和证书配置是否正确。
  • "认证失败":可能是商户号或密钥配置错误,建议检查WXPayConstants中的配置是否正确。
  • "IP спор情况":在测试环境中确保请求IP正确识别,代理服务器等情况需要仔细处理。
  • 参考示例

    以下是一些建议的处理步骤:

  • 证书配置:确保证书认证由商户自己提供,并测试是否安装正确。
  • 依赖更新:在项目更新依赖时权限是否正确,确保获取最新版本。
  • 全局变量优化:如果遇到异常处理逻辑,推荐使用异常处理机制。
  • 日志处理:增加更详细的日志,确保开发和测试阶段的信息完整。
  • 缓存机制:对于频繁使用的接口,可以考虑实现缓存机制。
  • 通过以上详细步骤和注意事项,可以顺利完成微信支付功能的集成开发,解决新商户的常见问题,确保支付流程的稳定性和安全性。

    上一篇:Java深入学习路线图
    下一篇:微信支付商户支付密钥key的生成与设置

    发表评论

    最新留言

    感谢大佬
    [***.8.128.20]2025年04月30日 19时54分27秒