目录

工程总介绍:

第一弹: 微信 支付下单

展示结果截图

1.配置说明

1.1数据库设计 需要拿到微信官方给的一些参数

1.2用到的jar包

1.3信支付接口请求状态枚举

1.3.1接口请求

1.3.2状态

1.4 微信参数常量配置

1.4.1微信支付HTTP请求头相关常量

1.4.2 微信支付参数 常量

2.APP下单

2.1.1创建订单VO

2.1.2 构造HttpClient

2.1.3计算签名

2.2 微信下单service

2.3 返回前端参数

3.3 controller


工程总介绍:

下面会有几期关于app微信支付的经验分享

微信支付功能已通过测试可以使用 可能一些设计不合理 欢迎提出更好的方案 让我们改进

第一弹: 微信 支付下单

展示结果截图

1.配置说明

1.1数据库设计 需要拿到微信官方给的一些参数

1.2用到的jar包

可能不太全 如果项目代码中有没有写出的包可以指出来

 <!--mybatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3.4</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>3.4.3.4</version></dependency><!--mybatis-plus代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.2.0</version></dependency>
<!--spring data redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--        springcache--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>
<!--微信支付    --><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.2</version></dependency>
<!--hutool工具类        --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.6</version></dependency><!--参数校验        --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.0.1.Final</version></dependency><dependency><groupId>org.glassfish</groupId><artifactId>jakarta.el</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
<!--google-->
<dependency><groupId>com.vaadin.external.google</groupId><artifactId>android-json</artifactId><version>0.0.20131108.vaadin1</version><scope>compile</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.60</version></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId></dependency>

1.3信支付接口请求状态枚举

1.3.1接口请求

package com.yqs.Enum;/***微信支付 api调用接口* @author zhangjunrong* @date 2022/5/9 19:57*/
public enum WxApiType {/** 下单API */CREATE_ORDER("https://api.mch.weixin.qq.com/v3/pay/transactions/app"),/** 查询支付订单API ONE{}=>outTradeNo – 商户订单号 系统生 TOW{}=>mchId商户的商户号,由微信支付生成并下发。 */QUERY_CREATE_ORDER("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{}?mchid={}"),/** 查询退款订单API {}=>outRefundNo 商户退款单号*/QUERY_REFUND_ORDER("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/{}"),/** 关闭订单API {}=>outTradeNo 商户订单号*/CLOSE_ORDER("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{}/close"),/** 申请退款API {}=>outTradeNo 商户订单号*/REFUND_ORDER("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"),/** 申请交易账单API {}=>bill_date 账单日期 格式yyyy-MM-DD仅支持三个月内的账单下载申请*/TRADE_BILLS("https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date={}"),/** 申请资金账单API {}=>bill_date 账单日期 格式yyyy-MM-DD仅支持三个月内的账单下载申请*/FUND_FLOW_BILLS("https://api.mch.weixin.qq.com/v3/bill/fundflowbill?bill_date={}");private final String value;WxApiType(String value) {this.value = value;}public String getValue() {return value;}
}

1.3.2状态

package com.yqs.Enum;/*** @Description 微信支付状态* @Author 小乌龟* @Date 2022/5/14 10:56*/
public enum WxPayStatusEnum {/** 未支付 */NOTPAY(0,"NOTPAY"),/** 支付成功 */SUCCESS(1,"SUCCESS"),/** 转入退款 */REFUND(2,"REFUND"),/** 已关闭 */CLOSED(3,"CLOSED"),/**  退款处理中 */REF_PROCESSING(0,"PROCESSING"),/**  退款成功 */REF_SUCCESS(1,"SUCCESS"),/** 退款已关闭 */REF_CLOSED(2,"CLOSED"),/** 退款异常 */REF_ABNORMAL(3,"ABNORMAL");private final Integer code;private final String value;WxPayStatusEnum(Integer code,String value) {this.code=code;this.value = value;}public Integer getCode() {return code;}public String getValue() {return value;}/***退款状态 转换 String => int* @param value 退款String* @return Integer* @author zhangjunrong* @date 2022/5/19 13:47*/public static Integer getCode(String value){switch(value){case "PROCESSING":return REF_PROCESSING.code;case "SUCCESS":return REF_SUCCESS.code;case "CLOSED":return REF_CLOSED.code;default:return REF_ABNORMAL.code;}}
}

1.4 微信参数常量配置

1.4.1微信支付HTTP请求头相关常量

package com.yqs.constant.wechatPay;/***微信支付HTTP请求头相关常量* @author zhangjunrong* @return*/
public final class WechatPayHttpHeaders {//请求头配置public static final String ACCEPT = "Accept";public static final String CONTENT_TYPE = "Content-type";public static final String APPLICATION_JSON = "application/json";public static final String APPLICATION_JSON_UTF = "application/json; charset=utf-8";/***微信回调参数==>微信序列号*/public static final String WECHATPAY_SERIAL = "Wechatpay-Serial";/***微信回调参数==>应答随机串*/public static final String WECHATPAY_NONCE="Wechatpay-Nonce";/***微信回调参数==>应答时间戳*/public static final String WECHATPAY_TIMESTAMP="Wechatpay-Timestamp";/***微信回调参数==>应答签名*/public static final String WECHATPAY_SIGNATURE="Wechatpay-Signature";private WechatPayHttpHeaders() {// Don't allow instantiation}}

1.4.2 微信支付参数 常量

package com.yqs.constant.wechatPay;/*** @Description 微信支付参数* @Author 小乌龟* @Date 2022/5/4 8:44*/
public class WXOrderConstant {/***应用ID*/public final static String APPID ="appid";/***直连商户号*/public final static String MCHID ="mchid";/***用户支付状态*/public final static String TRADE_STATE ="trade_state";/***用户退款状态*/public final static String STATUS ="status";/***商品描述*/public final static String DESCRIPTION ="description";/***通知地址*/public final static String NOTIFY_URL ="notify_url";/***预支付交易会话标识*/public final static String PREPAY_ID ="prepay_id";/***商户订单号*/public final static String OUT_TRADE_NO ="out_trade_no";/***商户退款单号*/public final static String OUT_REFUND_NO ="out_refund_no";/***微信支付系统生成的订单号*/public final static String TRANSACTION_ID ="transaction_id";/***微信支付系统生成的订单号*/public final static String REFUND_ID ="refund_id";/***订单金额*/public final static String AMOUNT ="amount";/***总金额    下单时系统计算金额 单位为分*/public final static String AMOUNT_TOTAL ="total";/***总金额 退款时 退款金额*/public final static String AMOUNT_REFUND ="refund";/***总金额 退款时 币种*/public final static String AMOUNT_CURRENCY ="currency";/***用户支付金额*/public final static String AMOUNT_PAYER_TOTAL ="payer_total";/***优惠功能*/public final static String PROMOTION_DETAIL ="promotion_detail";/***优惠类型*/public final static String PROMOTION_DETAIL_TYPE ="type";/*** 微信优惠 CASH:充值型代金券*/public final static String WX_DISCOUNT_TYPE="CASH";/***下单回调给微信支付成功信息*/public final static String WX_BACK_OK="SUCCESS";/***退款回调 退款状态*/public final static String REFUND_STATUS="refund_status";/***微信回调 通知数据*/public final static String RESOURCE="resource";/***微信账单类型 交易账单*/public final static String TRADE_BILL="tradebill";/***微信账单类型 资金账单*/public final static String FUND_FLOW_BILL="fundflowbill";/***微信账单下载地址*/public final static String DOWNLOAD_URL="download_url";/***微信回调 通知数据=>数据密文*/public final static String RESOURCE_CIPHERTEXT="ciphertext";/***微信回调 通知数据=>附加数据*/public final static String RESOURCE_ASSOCIATED_DATA="associated_data";/***微信回调 通知数据=>随机串*/public final static String RESOURCE_NONCE="nonce";}

2.APP下单

2.1.1创建订单VO

/*** @Description* @Author 小乌龟* @Date 2022/4/13 19:49*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="前端=>微信创建订单", description="")
public class ToCreatOrderVO {@ApiModelProperty(value = "订单号")@NotBlankString outTradeNo;@ApiModelProperty(value = "金额")@NotBlankString total;@ApiModelProperty(value = "订单描述")@NotBlankString description;
}

2.1.2 构造HttpClient

/***构造HttpClient 实现 微信申请接口 调用功能* @param wxConfig 微信支付数据库参数* @param verifier 微信验签器* @return CloseableHttpClient* @author zhangjunrong* @date 2022/5/16 8:54*/public static CloseableHttpClient getHttpClient(ToolWxConfig wxConfig, Verifier verifier) {PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(wxConfig.getPrivateKey().getBytes(StandardCharsets.UTF_8)));//通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(wxConfig.getMchId(), wxConfig.getMchSerialNo(), merchantPrivateKey).withValidator(new WechatPay2Validator(verifier));return builder.build();}

2.1.3计算签名

   /***签名生成 计算签名* @param message  签名体* @param privateKey 商户私钥* @return String* @author zhangjunrong* @date 2022/4/10 20:15*/public static String sign(byte[] message, PrivateKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(privateKey);sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}

2.2 微信下单service

//1.数据库查询配置参数
@Override@Cacheable(key = "'config'")public ToolWxConfig find() {ToolWxConfig wxConfig = toolWxConfigMapper.selectById(1L);return wxConfig;}
//2.微信下单
@Overridepublic ReCreatOrderVO createOrder(ToolWxConfig wxConfig, ToCreatOrderVO toCreatOrderVO) {try {//1.请求配置参数HttpPost httpPost = new HttpPost(WxApiType.CREATE_ORDER.getValue());//格式配置httpPost.addHeader(WechatPayHttpHeaders.ACCEPT, WechatPayHttpHeaders.APPLICATION_JSON);httpPost.addHeader(WechatPayHttpHeaders.CONTENT_TYPE, WechatPayHttpHeaders.APPLICATION_JSON_UTF);//2.读取privateKey私钥PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(wxConfig.getPrivateKey().getBytes(StandardCharsets.UTF_8)));ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectMapper objectMapper = new ObjectMapper();//3.配置下单参数ObjectNode rootNode = objectMapper.createObjectNode();rootNode.put(WXOrderConstant.MCHID, wxConfig.getMchId()).put(WXOrderConstant.APPID, wxConfig.getAppId()).put(WXOrderConstant.DESCRIPTION, toCreatOrderVO.getDescription()).put(WXOrderConstant.NOTIFY_URL, wxConfig.getCreNotifyUrl()).put(WXOrderConstant.OUT_TRADE_NO, toCreatOrderVO.getOutTradeNo());rootNode.putObject(WXOrderConstant.AMOUNT)//total 微信需要int类型 为了不丢失精度 单位为分.put(WXOrderConstant.AMOUNT_TOTAL, new BigDecimal(toCreatOrderVO.getTotal()).movePointRight(SystemConstant.NUM_TWO).intValue());log.warn("金额" + new BigDecimal(toCreatOrderVO.getTotal()).movePointRight(SystemConstant.NUM_TWO).intValue());objectMapper.writeValue(bos, rootNode);//4.调用微信下单接口httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));//接口返回值 申请获取prepay_idCloseableHttpResponse response = WxPayUtil.getHttpClient(wxConfig, WxPayUtil.getVerifier(wxConfig)).execute(httpPost);//预支付交易会话标识 prepay_idString bodyAsString = EntityUtils.toString(response.getEntity());//5.APP调起支付API 构造签名串String timestamp = DateUtil.currentSeconds() + "";String nonce = RandomUtil.randomString(SystemConstant.NUM_32);StringBuilder builder = new StringBuilder();//应用idbuilder.append(wxConfig.getAppId()).append("\n");//时间戳builder.append(timestamp).append("\n");//随机字符串builder.append(nonce).append("\n");//预支付交易会话标识 prepay_id  通过bodyAsString获取 prepay_idJsonNode node = objectMapper.readTree(bodyAsString);builder.append(node.get(WXOrderConstant.PREPAY_ID).textValue()).append("\n");String prepayId = node.get(WXOrderConstant.PREPAY_ID).textValue();//6.计算签名String sign = WxPayUtil.sign(builder.toString().getBytes(StandardCharsets.UTF_8), merchantPrivateKey);//todo 测试签名是否成功System.err.println(sign);//7.返回参数 让前端调微信支付return new ReCreatOrderVO(wxConfig.getAppId(), prepayId, wxConfig.getMchId(), wxConfig.getWxPackage(), nonce, timestamp, sign);} catch (Exception e) {log.error(toCreatOrderVO.getOutTradeNo() + "订单下单失败");//下单失败抛异常throw new YqsException(MessageEnum.NOT_ACCEPTABLE.getCode(), "下单失败 重新尝试付款");}}

2.3 返回前端参数

(这个参数是根据uniapp来的 可能其他的会不一样所以注意了)

/*** @author 小乌龟*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="微信创建订单", description="")
public class ReCreatOrderVO {
//uniapp需要参数
//    "appid": "wx499********7c70e",  // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
//            "noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
//            "package": "Sign=WXPay",        // 固定值
//            "partnerid": "148*****52",      // 微信支付商户号
//            "prepayid": "wx202254********************fbe90000", // 统一下单订单号
//            "timestamp": 1597935292,        // 时间戳(单位:秒)
//            "sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5/RSA 签名@ApiModelProperty(value = "appid")private String appId;@ApiModelProperty(value = "统一下单订单号 prepayid ")private String prepayId;@ApiModelProperty(value = "微信支付商户号")private String partnerId;@ApiModelProperty(value = "订单详情扩展字符串")private String wxPackage;@ApiModelProperty(value = "随机字符串")private String wxNonce;@ApiModelProperty(value = "时间戳")private String wxTimestamp;@ApiModelProperty(value = "签名")private String wxSign;}

3.3 controller

@PostMapping("/toWxPayApp")@ApiOperation("微信支付")@RequiresAuthenticationpublic ResultResponse<ReCreatOrderVO> toWxPayApp(@ApiParam("订单信息") @RequestBody @Valid ToCreatOrderVO toCreatOrderVO, BindingResult br) {return process(() -> iToolWxConfigService.createOrder(iToolWxConfigService.find(), toCreatOrderVO), br);}

微信支付 APP端 后端 第一弹 微信下单相关推荐

  1. 微信支付 APP端 后端 第二弹 微信回调

    目录 第二弹:支付回调 成果展示 1 订单设计思路 1.1设计思路 2.回调接口 2.1controller 2.2验证静态方法 2.3缓存参数 常量 2.4 service 校验金额 2.4.1金额 ...

  2. 微信支付 APP端 后端 第四-五弹 退款定时任务 账单下载

    目录 第四弹 退款定时任务 成果展示: 1.设计思路 2.代码实现 2.1数据库查询订单 2.2定时任务 检查退款订单 2.3调用微信支付 get请求 统一配置(如果是看了前几篇的友友 前面有一样的 ...

  3. 【微信支付】(亲测可用)对接app微信支付V2版本 后端代码示例

    业务场景:基本上做业务的话,也是逃不开对接各种支付接口的,比如数字人民币支付.农行免密支付.支付宝支付.微信支付等等.在着手开发时候,也是遇到不少阻力,微信官方提供的接口文档很散乱,如果之前没接触过, ...

  4. JAVA对接微信支付和支付宝支付(APP端支付)

    本文主要介绍的是JAVA对接支付宝和微信支付,废话少说上代码(部分业务代码就不上了,例如订单等,根据业务需求自行修改): 用到的工具类: maven依赖: <!-- https://mvnrep ...

  5. 微信支付 APP支付 Java 服务器端

    微信支付 APP支付 Java 服务器端 本文介绍微信支付中APP支付的java服务端. 微信APP支付文档:https://pay.weixin.qq.com/wiki/doc/api/app/ap ...

  6. php苹果app微信支付 无法返回,微信支付,php_微信支付APP返回-1怎么解决,微信支付,php,移动app - phpStudy...

    微信支付APP返回-1怎么解决 开发文档上面-1"可能的原因:签名错误.未注册APPID.项目设置APPID不正确.注册的APPID与设置的不匹配.其他异常等.",但是我检查过没问 ...

  7. 手把手安排 --- JavaH5微信支付(移动端浏览器H5拉起微信支付)

    Java项目接入H5微信支付 开发环境 前期准备 申请微信公众平台及微信支付 准备内网穿透域名 微信支付开发配置 开始撸代码 成功案例 总结 公司项目需要接入微信支付,因为主要是在移动端的网页进行支付 ...

  8. 微信支付-App支付服务端详解

    微信App支付服务端详解 引言 主要实现app支付统一下单.异步通知.调起支付接口.支付订单查询.申请退款.查询退款功能:封装了https对发起退款的证书校验.签名.xml解析等. 支付流程 具体支付 ...

  9. 微信支付APP支付完全攻略

    微信支付接入应用 最近项目中要接入微信支付,所以就去研究了下,发现坑还真不少啊.也就有了这篇博客. 接入前准备 在开始接入微信支付前你的去微信的开发平台上面注册你自己的应用.具体的链接是微信开发平台 ...

最新文章

  1. [Elixir008]Nested Module里的动态函数调用方式
  2. 【渝粤题库】广东开放大学 建设监理 形成性考核
  3. Java常用设计模式————建造者模式
  4. CentOS 6.5安装使用docker
  5. 2019入门级云主机选型测试报告
  6. 【英语学习】【医学】Unit 03 Blood
  7. Android 系统(95)---Android build.prop参数详解
  8. 你还会不会选择我(刘墉 )
  9. mysql获取变量_获取Mysql的状态、变量
  10. PySpark : Structured Streaming
  11. 华为签约计算机大学,2020年,华为签约学生多的16所大学,你知道几个?
  12. 新手如何发网站外链,网站的外链如何发,发外链的方法集合
  13. 搜索词纠错(拼写检查)、相关搜索的原理与实现
  14. maven的资源过滤filters
  15. 有赞招聘 | 遇见offer之就要圆你的大厂梦
  16. iPhone7产业链不为人知的辛酸
  17. python爬虫之糗事百科
  18. IP前缀列表配置实验
  19. 华为语音解锁设置_华为手机该怎么实现语音翻译?其实超级简单,这里教你
  20. 计算机cpu的字母,电脑处理器后面的字母你认识几个?不认识跟我来学学(intel篇)...

热门文章

  1. 中国计算机学会推荐的期刊论文
  2. 在微信中查看打印的消息
  3. 未能链接ea服务器,《双人成行》无法连接到EA服务器怎么办 无法连接到EA服务器解决办法...
  4. MilenageTest 4G/5G鉴权值验证工具的使用
  5. 古月居_ROS自定义消息
  6. 电脑文件凭空消失了怎么恢复?
  7. 虎符2022RE复现
  8. Java 堆和栈的区别
  9. 《视频直播技术详解》系列:(6)编码和封装
  10. 某瓣_sig参数逆向破解