公众号微信支付开发

1.第一步:设置微信支付目录,这个地址指到支付页面的上一级即可。

例如:支付页面的地址是http://www.baidu.com/wechat/pay/shopping,只需填写http://www.baidu.com/wechat/pay/,

一定要以"/"(左斜杆)符号结尾。

2.第二步:设置授权域名,授权域名是为了获取支付中不可缺少的参数openid。每个用户对于每个公众号的openid都是不同的且是唯一的,即是说一个用户在不同的公众号中,他的openid是不同的,并且一直不变。在开发中可以事先获取你自己的在这个公众号(正式公众号,具有支付权限的)的openid,然后就可以跳过授权过程,直接开发并测试支付功能。

3.第三步:引入微信开发jar包,这是别人已经封装好的微信支付API,当然也可以使用官方的微信支付SDK,不过为了方便快速开发,

所以这里我使用了封装好的别人封装好的API,这是API文档的github地址:https://github.com/wechat-group/weixin-java-tools/wiki ,里面有具体的使用方法和开发步骤,如果你嫌看文档麻烦的话可以直接看我的开发步骤:

这是基于springboot开发的,首先引入jar包:

        <dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>3.1.4.BETA</version></dependency>    

4.加入微信开发包两个基本类:

(1)在springboot配置文件application.properties中加入微信支付基本参数:

#微信公众号或者小程序等的appid
wechatpay.appId =#微信支付商户号
wechatpay.mchId =#微信支付商户密钥
wechatpay.mchKey=#服务商模式下的子商户公众账号ID,用不上就注释掉
#wechatpay.subAppId=#服务商模式下的子商户号,用不上就注释掉
#wechatpay.subMchId=# p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)用不上就注释掉
#wechatpay.keyPath=

(2)添加支付配置文件参数类WxPayProperties:

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** wxpay pay properties** @author Binary Wang*/
@ConfigurationProperties(prefix = "wechatpay")
public class WxPayProperties {/*** 设置微信公众号的appid*/private String appId;/*** 微信支付商户号*/private String mchId;/*** 微信支付商户密钥*/private String mchKey;/*** 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除*/private String subAppId;/*** 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除*/private String subMchId;/*** apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定*/private String keyPath;public String getAppId() {return this.appId;}public void setAppId(String appId) {this.appId = appId;}public String getMchId() {return mchId;}public void setMchId(String mchId) {this.mchId = mchId;}public String getMchKey() {return mchKey;}public void setMchKey(String mchKey) {this.mchKey = mchKey;}public String getSubAppId() {return subAppId;}public void setSubAppId(String subAppId) {this.subAppId = subAppId;}public String getSubMchId() {return subMchId;}public void setSubMchId(String subMchId) {this.subMchId = subMchId;}public String getKeyPath() {return this.keyPath;}public void setKeyPath(String keyPath) {this.keyPath = keyPath;}@Overridepublic String toString() {return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);}
}

(3)初始化微信支付配置类WxPayConfiguration:

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;/*** @author Binary Wang*/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
public class WxPayConfiguration {private WxPayProperties properties;@Autowiredpublic WxPayConfiguration(WxPayProperties properties) {this.properties = properties;}@Bean@ConditionalOnMissingBeanpublic WxPayService wxService() {WxPayConfig payConfig = new WxPayConfig();payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);return wxPayService;}}

5.生成支付订单:

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.park.pojo.park.ParkingRecord;
import com.park.service.Interface.ParkService;
import com.park.utils.parkInterfaceUtil.ParkInterfaceRequestParam;
import com.park.utils.parkInterfaceUtil.ParkProtocolParamUtil;
import com.park.utils.wechatUtil.ConstantUtil;
import com.park.utils.wechatUtil.HttpRequest;
import com.park.utils.wechatUtil.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** 微信支付接口*/
@Slf4j
@RestController
@RequestMapping(value = "/wechat/pay")
public class WechatPayController {@Autowiredprivate WxPayService wxService;/*** 统一下单* 在发起微信支付前,需要调用统一下单接口,返回微信支付的所需要的参数* 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder** @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)*/@PostMapping("/getPayInfo")public WxPayMpOrderResult getPayInfo(@RequestBody WxPayUnifiedOrderRequest request , HttpServletRequest httpServletRequest) throws WxPayException,Exception {request.setOutTradeNo(SignUtil.buildRandom(10));                                         //随机字订单号request.setSpbillCreateIp(ConstantUtil.getRemortIP(httpServletRequest));                    //用户iprequest.setTradeType("JSAPI");                                                              //公众号支付request.setNonceStr(SignUtil.createNonceStr());                                             //随机字符串request.setNotifyUrl("http://qwrerewrwqewq/wechat/pay/PayResultNotify");                //回调通知支付结果地址(必须外网能访问的地址)request.setDeviceInfo("WEB");                                                               //客户终端类型request.setSignType("MD5");                                                                 //加密方式(必须参数,虽然官方文档说是非必需,亲测不加一直报签名错误)return this.wxService.createOrder(request);}/*** 接受微信支付返回通知* @param request* @param response* @throws IOException*/@RequestMapping("/PayResultNotify")public void PayResultNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {log.info("微信支付返回通知函数开始---------------------");InputStream inStream = request.getInputStream();ByteArrayOutputStream outSteam = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outSteam.write(buffer, 0, len);}outSteam.close();inStream.close();String result = new String(outSteam.toByteArray(), "utf-8");boolean isPayOk =false;WxPayOrderNotifyResult wxPayOrderNotifyResult =null;// 此处调用订单查询接口验证是否交易成功try {wxPayOrderNotifyResult = wxService.parseOrderNotifyResult(result);if("SUCCESS".equals(wxPayOrderNotifyResult.getResultCode())){isPayOk=true;}log.info("解析数据:"+wxPayOrderNotifyResult.toString());} catch (WxPayException e) {e.printStackTrace();}String noticeStr="";// 支付成功,商户处理后同步返回给微信参数PrintWriter writer = response.getWriter();if (isPayOk) {//建议在这里处理付款完成的业务(虽然前端也可以处理后续业务,但是前端处理并不安全,例如:客户突然关闭浏览器了等情况,付款成功后续的业务将中断)System.out.println("===============付款成功,业务处理完毕==============");// 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口noticeStr = setXML("SUCCESS", "OK");log.info("收到通知返回给微信api信息:-----------"+noticeStr);writer.write(noticeStr);writer.flush();} else {// 支付失败, 记录流水失败noticeStr = setXML("FAIL", "");writer.write(noticeStr);writer.flush();System.out.println("===============支付失败==============");}}public static String setXML(String return_code, String return_msg) {return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";}
}

6.所用到的工具类:

import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;public class SignUtil {private static String token = "weixin";/*** 获取acassToken校验* @param signature* @param timestamp* @param nonce* @return*/public static boolean checkSignature(String signature, String timestamp, String nonce) {boolean result = false;// 对token、timestamp和nonce按字典序排序String[] array = new String[]{token, timestamp, nonce};Arrays.sort(array);// 将三个参数字符拼接成一个字符串String str = array[0].concat(array[1]).concat(array[2]);String sha1Str = null;try {// 对拼接后的字符串进行sha1加密MessageDigest md = MessageDigest.getInstance("SHA-1");byte[] digest = md.digest(str.getBytes());sha1Str = byte2str(digest);}catch(Exception e) {}if(sha1Str != null &&  sha1Str.equals(signature)) {result = true;}return result;}/** 将字节数组转换成字符串*/public static String byte2str(byte[] array) {StringBuffer hexstr = new StringBuffer();String shaHex="";for(int i = 0; i < array.length; i++) {shaHex = Integer.toHexString(array[i] & 0xFF);if(shaHex.length() < 2) {hexstr.append(0);}hexstr.append(shaHex);}return hexstr.toString();}/*** 获取acaccessToken* @param grant_type* @param appid* @param secret* @return*/public static String getAcaccessToken(String grant_type,String appid,String secret){String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+appid+"&secret="+secret;String Str = HttpRequest.httpRequestGet(url);return Str;}/*** 创建随机字符串* @return*/public static String createNonceStr() {return UUID.randomUUID().toString().substring(0, 20);}/*** 获取时间戳* @return*/public static String getCurrTime(){long times = new Date().getTime();return times+"";}/*** 随机数* @param length* @return*/public static String buildRandom(int length){long times = new Date().getTime();int randomNum = (int)((Math.random()*9+1)*(10*length));return randomNum+""+times;}/*** 获取用户IP* @param request* @return*/public static String getRemortIP(HttpServletRequest request) {if (request.getHeader("x-forwarded-for") == null) {return request.getRemoteAddr();}String ipListStr = request.getHeader("x-forwarded-for");if(!(ipListStr.indexOf(",")<0)){String [] list = ipListStr.split(",");return list[0];                                 //当服务部署使用代理,其获取到的IP地址将会是多个,取第一个}else {return ipListStr ;}}
}

7.前端代码:

前端使用的VUE,逻辑代码如下:

getPayInfo(params){                                              //调用统一下单接口获取js支付参数  参数:金额、商品名称等 具体可以看统一接口的接收参数类WxPayUnifiedOrderRequestthis.$api.gotoPay(params).then(res=>{  if(res!=null){this.payInfo.appId = res.data.appId;this.payInfo.timeStamp = res.data.timeStamp;this.payInfo.nonceStr = res.data.nonceStr;this.payInfo.packages = res.data.packages;this.payInfo.sign = res.data.sign;}})},onBridgeReady(){                                //使用微信浏览器内置的对象调起微信支付插件,并传入统一接口返回的参数WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId":this.payInfo.appId,                 //公众号名称,由商户传入"timeStamp":this.payInfo.timeStamp,         //时间戳,自1970年以来的秒数"nonceStr":this.payInfo.nonceStr,           //随机字符串"package":this.payInfo.packages,            //支付验证pay_id"signType":"MD5",                           //微信签名方式"paySign":this.payInfo.sign                 //微信签名},function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ){// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。}});},Gopay(){                                            //点击付款按钮开始支付console.log("开始支付")if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady(), false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady());document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady());}}else{this.onBridgeReady();}}

(8)测试支付功能:

可以将支付页面的地址发送到正式的公众号(必须要正式的公众号才行,而且后台支付相关的参数也要用正式,同时要用传入的openid的那个用户点击才能测试,一般是本人的),然后点击开始测试支付。

最后附上参考文章:https://www.cnblogs.com/chenziyu/p/9656267.html

微信公众号支付(记录)相关推荐

  1. 微信公众号支付JSAPI 详细记录

    刚刚调试通微信公众号支付,写个博客记录一下. jsapi必要的几个参数 微信公众号的账户密码,微信商户账号密码. 登陆微信公众号,左下角开发-基本配置,查看APPID 1.公众APPID(已经得到) ...

  2. vue 微信公众号支付接口_基于vue的h5项目之支付宝支付与微信支付

    本文仅记录基于vue开发h5项目过程中使用支付宝和微信支付过程中的重点与槽点,仅为前端部分,如有疏漏不正之处,请于文末评论探讨.注意:标红部分灰常重要,仔细阅读官方文档非常重要,耐心非常重要,细心非常 ...

  3. 微信公众号支付从前端到后台(小白教程)

    耗时一个星期终于搞定微信支付,对于第一次涉足前端.微信支付的我来说,这并非易事,闲话少说,下面我用最通俗的语言来描述一下: 第一部分 微信公众号后台 1.申请微信公众号(需要营业执照),开发者认证(3 ...

  4. 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。

    最近公司开发网站针对微信公众号的支付功能. 由于公司目前的这个项目网站是使用asp代码开发的,但是微信官方给出的demo中是没有asp版本的,所以楼主只有下载demo的php版本作为参考写了一个asp ...

  5. prepay id为空php,微信公众号支付踩坑笔记

    微信公众号支付,简单说主要分为如下几个步骤. 1.openId的获取 openId是微信用户与特定公众号对应关系的记录. 1.1设置回调域名 官方解释:用户在网页授权页同意授权给公众号后,微信会将授权 ...

  6. java开发微信公众号支付

    这篇文章主要给大家结合微信支付接口开发的实践,从获取用户授权到各主要接口的使用方法等方面介绍微信支付的关键点技术,有需要的小伙伴可以参考下 最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时 ...

  7. delphi XE关于微信公众号支付及微信零钱支付的便捷解决方案

    delphi XE关于微信公众号支付及微信零钱支付的便捷解决方案 https://download.csdn.net/download/pulledup/12683611 一.需求 因为微信公众号支付 ...

  8. 微信公众号支付 流程

    1.支付参数准备(图就不上了) 公众号的APPID.商户号MchID.商户API支付秘钥(商户平台的账户中心下:需要用户自行下载证书及安装). 2.平台配置 商户平台-->产品中心-->开 ...

  9. C#微信公众号支付接口对接

    这次是第二次对接微信公众号的支付了,第一次代码写的很乱,没有找现成的SDK,感觉里面乱七八糟的东西太多不够清爽,而我仅仅是做一个小功能,对接又不复杂干脆自己做. 不想重复做轮子的朋友可以参考一下:Se ...

最新文章

  1. Debian 陷入尴尬,社区或群龙无首
  2. 131、ThreadLocal (转载)
  3. 智能化的数据中心到底该如何建设?
  4. 抽象工厂模式_抽象工厂模式
  5. HTML使用vue的 event,vue-js 特殊变量$event常识
  6. leftjoin多表联合查询_leetcode-sql练习精讲系列文章——一、多表如何连接
  7. Sharepoint学习笔记—架构系列
  8. Kafka 优化参数 unclean.leader.election.enable
  9. Java怎么避免重复订单_javaEE高并发之如何产生唯一不重复订单号
  10. 在日常维护管理中对MySQL 日志的需求
  11. VB.NET工作笔记008---vs2017创建使用WCF服务_并调用服务demo
  12. 提高网页打开速度的一些小技巧
  13. ubuntu下从软件中心安装软件时的软件缓存目录
  14. Linux CAT与ECHO命令详解 <<EOF EOF
  15. C# WinForm技巧“将Form嵌入到Panel”
  16. Streamlit--python中的前端
  17. c语言ip地址转16进制,点分十进制形式的ip地址转化为十六进制数
  18. 【交易所相关】网关、席位、交易单元
  19. MATLAB角度转换
  20. centos8 配置 dns_上网慢?你可能要改一下DNS

热门文章

  1. 决策过程并举例_体外诊断产品立项与研发的过程管理之二:产品的设计开发(二)...
  2. 差分隐私 深度学习_深度学习中的差异隐私
  3. 中国网游公司上市突击大事记
  4. 学习下 BlackHat Asia 2021 大会议题
  5. 并查集(找祖先)(可以将集合当成网或无向图)
  6. Oracle 中scott 用户的解锁以及修改密码
  7. 苹果Usb连接linux,Mount iPhone in Linux using USB (ifuse, libiphone)
  8. 四个职场规则!弄不懂会吃大亏
  9. 给定一个链表,判断链表中是否有环
  10. 武汉本地三大门户网站的分析和比较!