前期准备工作

1. 微信各平台功能认识

  • 1.1 微信开放平台: 支持移动应用,公众号的开发,创建应用并得到APPID,使你的应用支持微信支付。
  • 1.2 微信公众平台: 微信小程序,服务号,订阅号的开发。
  • 1.3 微信商户平台: 提供微信应用所需要的支付产品,类似支付宝开放平台对应用进行功能签约。
  • :微信支付交易发起依赖于公众号、小程序、移动应用(即APPID)与商户号(即MCHID)的绑定关系,因此商户在完成签约后,需要确认当前商户号同APPID的绑定关系,方可使用
参考url:https://pay.weixin.qq.com/static/pay_setting/appid_protocol.shtml

2. 微信开发平台创建应用信息

  • 2.1 创建应用
  • 2.2 应用信息APPID
    - 2.3 签约APP

3. 微信商户平台信息

  • 3.1 商户信息MCH_ID

4.使用feign通过RPC进行微信支付接入

实战

1. 配置及依赖

  • 1.1 依赖
  <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId>//参数编码依赖<version>1.9</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>//远程调用feign<version>2.1.2.RELEASE</version></dependency>
  • 1.2 配置

    • 1.2.1 前期准备获取的参数
    • 1.2.2 接口参数编码配置
@Configuration
public class WeChatCodecConfig {//调用微信支付接口参数编码格式@Beanpublic Decoder feignDecoder() {MappingJackson2XmlHttpMessageConverter xmlConverter = new MappingJackson2XmlHttpMessageConverter();List<MediaType> types = xmlConverter.getSupportedMediaTypes();List<MediaType> newTypes = new ArrayList<MediaType>();newTypes.add(MediaType.TEXT_PLAIN);for(MediaType t: types) {newTypes.add(t);}xmlConverter.setSupportedMediaTypes(newTypes);ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(xmlConverter);return new ResponseEntityDecoder(new SpringDecoder(objectFactory));}}

注: 微信APP支付拉起支付分两步,第一步统一下单获取prepay_id及相关返回参数,第二步再次构造参数调起微信支付接口。

2. 请求参数及返回值

  • 请求参数
@Data
@AllArgsConstructor
public class WeChatPayCommand {private Integer fee;//订单金额 单位分----微信支付金额单位统一为分private String title;//标题private String remark;//备注private String ip;//ip地址
}
  • 接口返回值
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Slf4j
public class WeChatAppPaySecondResponse {//1.调起支付再次构造的参数@JacksonXmlProperty(localName = "appid")private String appId;@JacksonXmlProperty(localName = "partnerid")private String partnerId;@JacksonXmlProperty(localName = "prepayid")private String prepayId;@JacksonXmlProperty(localName = "package")private String pack;@JacksonXmlProperty(localName = "noncestr")private String nonceStr;@JacksonXmlProperty(localName = "timestamp")private String timestamp;@JacksonXmlProperty(localName = "sign")private String sign;private String result; // 不参与签名,成功标志
}@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "xml")
public class WeChatAppPayResponse {//2.统一下单获取的返回值//返回结果此返回结果是手机支付的返回值@JacksonXmlProperty(localName = "return_code")private String returnCode;@JacksonXmlProperty(localName = "return_msg")private String returnMsg;//return_code为success时返回@JacksonXmlProperty(localName = "appid")private String appId;@JacksonXmlProperty(localName = "mch_id")private String mchId;@JacksonXmlProperty(localName = "device_info")private String deviceInfo;@JacksonXmlProperty(localName = "nonce_str")private String nonceStr;private String sign;@JacksonXmlProperty(localName = "result_code")private String resultCode;@JacksonXmlProperty(localName = "err_code")private String errCode;@JacksonXmlProperty(localName = "err_code_des")private String errCodeDes;@JacksonXmlProperty(localName = "trade_type")//return_code,result_code为success时返回private String tradeType;@JacksonXmlProperty(localName = "prepay_id")private String prepayId;//预支付交易id
}

3. 代码

  • 3.1 业务代码
    public WeChatAppPaySecondResponse generateAppPayInfo(WeChatPayCommand command) {WeChatPayRequest request = WeChatPayRequestBuilder.generateWeChatAppPayRequest(command,weChatAppPayCallBack);WeChatAppPayResponse response = weChatClient.appOrderPayInfo(request);//统一下单生成预支付订单信息if(!response.isSuccess()){return null;}//获取到prepay_id后将参数再次签名,重新构造参数 WeChatAppPaySecondResponse 传输给APP发起支付return WeChatAppPaySecondResponse.buildAppPaySecondResponseDto(response);}
  • 3.2 获取请求参数
    public static WeChatPayRequest generateWeChatAppPayRequest(WeChatPayCommand command, String notifyUrl){WeChatPayRequest request =  WeChatPayRequest.builder().appId(WeChatProperty.APP_ID).mchId(WeChatProperty.MCH_ID).nonceStr(WeChatPayUtil.generateWeChatNonceStr())  : notifyUrl是微信支付成功后异步回调处理通知地址即我们自己处理业务的接口程序地址.signType(WeChatProperty.SIGN_TYPE).body(command.getTitle()).attach(command.getRemark()).outTradeNo(generateTradeId()).totalFee(command.getFee().toString()).spbillCreateIp(command.getIp()).timeStart(DateUtil.obtainStartTime()).timeExpire(DateUtil.obtainEndTime()).notifyUrl(notifyUrl).tradeType(WeChatProperty.APP_PAY).build();request.setSign(WeChatPayUtil.generateSign(request));return request;}
  • 3.3 生成微信支付签名
  public static String generateSign(Object request){Map<String, String> sortedMap = convertToSortedMap(request);String sortRequest = convertToStr(sortedMap) + "key=" + WeChatProperty.KEY;return DigestUtils.md5Hex(sortRequest).toUpperCase();}private static Map<String, String> convertToSortedMap(Object object){ObjectMapper objectMapper = new ObjectMapper();Map<String, String> sortedMap = objectMapper.convertValue(object, TreeMap.class);Map formatedMap = new TreeMap();sortedMap.forEach((key, value) -> {if(!key.equals("sign") && !key.equals("result")){JacksonXmlProperty jacksonXmlProperty = obtainJacksonXmlPropertyAnnotationByKey(object, key);formatedMap.put(jacksonXmlProperty.localName(), value);}});return formatedMap;}private static JacksonXmlProperty obtainJacksonXmlPropertyAnnotationByKey(Object object, String key){JacksonXmlProperty jacksonXmlProperty = null;try {jacksonXmlProperty = object.getClass().getDeclaredField(key).getAnnotation(JacksonXmlProperty.class);} catch (NoSuchFieldException e) {e.printStackTrace();}return jacksonXmlProperty;}private static String convertToStr(Map<String, String> sortedMap){final String[] temp = {""};sortedMap.forEach((key, value) -> {if(!StringUtils.isEmpty(value)){temp[0] += key + "=" + value + "&";}});return temp[0];}
  • 3.4 再次构造调起支付接口参数
 private static WeChatAppPaySecondResponse buildSuccessResponse(WeChatAppPayResponse response){WeChatAppPaySecondResponse weChatAppPayResponseDto = WeChatAppPaySecondResponse.builder().appId(response.getAppId()).partnerId(response.getMchId()).prepayId(response.getPrepayId()).pack(WeChatProperty.PACKAGE).nonceStr(WeChatPayUtil.generateNonceStr()).timestamp(WeChatPayUtil.generateTimestamp()).result(ResultCode.SUCCESS).build();weChatAppPayResponseDto.setSign(WeChatPayUtil.generateSign(weChatAppPayResponseDto));//将参数再次签名传输给APP发起支付return weChatAppPayResponseDto;}
  • 3.5 支付结果通知异步处理回调
参考:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
  • 3.6 微信支付接口的调用
@FeignClient(value = "weChatClient", url = "https://api.mch.weixin.qq.com", configuration = WeChatCodecConfig.class)
public interface WeChatClient {@PostMapping(value = "/pay/unifiedorder", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)@ResponseBodyWeChatAppPayResponse appOrderPayInfo(@RequestBody WeChatPayRequest request);
}

总结

微信APP支付拉起支付接口过于繁琐,需两次构造参数统一下单+调起支付接口,没有支付宝处理的好。而且调取接口以RPC形式过于麻烦。

微信APP支付功能开发相关推荐

  1. android微信支付都需要什么意思,Android开发微信APP支付功能的要点小结

    基本概念 包名值得是你APP的包,在创建工程时候设置的,需要在微信支付平台上面设置. 签名指的是你生成APK时候所用的签名文件的md5,去掉:全部小写,需要在微信支付平台上面设置. 调试阶段,签名文件 ...

  2. 微信app支付功能-服务端的实现-python3版

    微信app支付功能-服务端的实现-python3版 一:需求说明 二:微信app支付处理流程 三:所需依赖 3.1 支付配置 四:接口开发 4.1 创建订单接口 4.2 微信异步回调接口 4.3 订单 ...

  3. php tp 微信支付,PHP实现的微信APP支付功能示例【基于TP5框架】

    本文实例讲述了PHP实现的微信APP支付功能.分享给大家供大家参考,具体如下: 1.进行支付请求 他给的DEMO 用的时候有时候会报错 1)我遇到的情况 把  WxPay.Api.php这个文件的 p ...

  4. 微信公众号开发笔记(三):微信JSAPI支付功能开发

    很久之前做了微信支付,其中也趟过很多坑,现在有时间就做个自我梳理吧算是. 公众号开发的基本配置(不明白的可以参考https://blog.csdn.net/TOP__ONE/article/detai ...

  5. 微信app支付 php,PHP 微信APP支付 整合 thinkphp3.2.3

    php开发APP支付功能中,涉及到微信APP支付功能.为了考虑数据的严密性,加密的过程全部都需要在服务端进行生成.微信APP支付与支付宝的还不太一样.微信APP支付需要二次的加密请求才可以完成整个服务 ...

  6. JAVA微信扫码支付及微信App支付开发(模式二)完整功能实现

    一,准备工作 事前申请一个商家版的微信公众号(目前微信支付只有商家版公众号可开通),然后开通微信支付功能,并做相应的配置. 申请开通微信公众号和开通微信支付需要等待审核,一般都5个工作日左右.开通成功 ...

  7. 微信app支付服务端开发记录

    微信APP支付服务端 调用接口需要注意事项: 1.签名:需要全部参数参加签名,空值去掉.(实际传递了什么参数需要,就根据实际参数进行签名) 2.签名参数:appid是申请支付功能的app对于的ID,k ...

  8. 微信公众号开发,微信支付功能开发(网页JSAPI调用)

    1.微信支付的流程 如下三张手机截图,我们在微信网页端看到的支付,表面上看到的是 "点击支付按钮 - 弹出支付框 - 支付成功后出现提示页面",实际上的核心处理过程是: 点击支付按 ...

  9. 基于spring-boot+uni-app实现app支付功能(微信/支付宝)服务端

    基于spring-boot+uni-app实现app支付功能(微信/支付宝)服务端 支付宝支付 1 准备工作 申请支付能力 接口加签方式 2代码 依赖 支付宝支付配置类 支付宝控制层 异步通知 微信支 ...

最新文章

  1. SharePoint数据表组件错误
  2. Android中网络编程出错
  3. 人脸识别之insightface开源代码使用:训练、验证、测试(4)
  4. 【揭秘】视频直播关键技术
  5. DCMTK:将标准图像格式转换为DICOM的实用程序
  6. 最新xampp下安装mod_security,mod_evasive,mod-cband笔记
  7. 单目可见光静默活体检测 Binary or Auxiliary Supervision论文解读
  8. 34.Silverlight中不得不了解使用的依赖属性
  9. win7无法访问局域网内电脑_win7系统局域网无法访问原因 win7局域网无法访问解决方法【图文】...
  10. Leetcode每日一题:16.3sum-closest(最接近的三数之和)
  11. 中国双燃料(DF)发动机市场趋势报告、技术动态创新及市场预测
  12. hidden field implements session
  13. vue-cli工具搭建vue-webpack项目
  14. 巨人 index.php/user/login,dedecms实现首页顶部会员登陆框的方法
  15. inSSIDer使用方法
  16. 第一篇:初识信息系统监理工程师
  17. 计算机画图怎样更改文字,一招教你利用画图工具修改图片上的文字
  18. 当甲骨文思维遇上谷歌精神,谷歌云将走向何方?
  19. android 分享到新浪微博,Android APP集成新浪微博分享功能
  20. 英文版win11怎么变成中文版?英文版win11改中文版教程

热门文章

  1. C#课程设计-图书管理系统
  2. TypeError: not supported between instances of str and int【python3】
  3. Nginx 根据url参数设置反向代理
  4. java拖拽选区_matplotlib 范围选区(SpanSelector)的使用
  5. maven 插件 转
  6. VS2019查看程序的依赖项
  7. Mac点击关闭按钮退出程序 与 程序隐藏后点击dock图标重新显示
  8. ai建立使用图案_线上课程 | PS/AI时装效果图在线课程
  9. 关于日常开发Java8流处理max()随笔
  10. Thread类及常见方法