php 微信统一下单接口,微信公众号支付(二)实现统一下单接口
上一篇已经获取到了用户的OpenId
这篇主要是调用微信公众支付的统一下单API
API地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
看文档,主要流程就是把20个左右的参数封装为XML格式发送到微信给的接口地址,然后就可以获取到返回的内容了,如果成功里面就有支付所需要的预支付ID
请求参数就不解释了。
其中,随机字符串:我用的是UUID去中划线public static String create_nonce_str() {
return UUID.randomUUID().toString().replace("-","");
}
商户订单号:每个订单号只能使用一次,所以用的是系统的订单号加的时间戳。
总金额:不能为
通知地址:微信支付成功或失败回调给系统的地址
签名:import java.io.Serializable;
public class PayInfo implements Serializable{
private static final long serialVersionUID = L;
private String appid;
private String mch_id;
private String device_info;
private String nonce_str;
private String sign;
private String body;
private String attach;
private String out_trade_no;
private int total_fee;
private String spbill_create_ip;
private String notify_url;
private String trade_type;
private String openid;
//下面是get,set方法
}
/**
* 创建统一下单的xml的java对象
* @param bizOrder 系统中的业务单号
* @param ip 用户的ip地址
* @param openId 用户的openId
* @return
*/
public PayInfo createPayInfo(BizOrder bizOrder,String ip,String openId) {
PayInfo payInfo = new PayInfo();
payInfo.setAppid(Constants.appid);
payInfo.setDevice_info("WEB");
payInfo.setMch_id(Constants.mch_id);
payInfo.setNonce_str(CommonUtil.create_nonce_str().replace("-", ""));
payInfo.setBody("这里是某某白米饭的body");
payInfo.setAttach(bizOrder.getId());
payInfo.setOut_trade_no(bizOrder.getOrderCode().concat("A").concat(DateFormatUtils.format(new Date(), "MMddHHmmss")));
payInfo.setTotal_fee((int)bizOrder.getFeeAmount());
payInfo.setSpbill_create_ip(ip);
payInfo.setNotify_url(Constants.notify_url);
payInfo.setTrade_type("JSAPI");
payInfo.setOpenid(openId);
return payInfo;
}
获取签名:/**
* 获取签名
* @param payInfo
* @return
* @throws Exception
*/
public String getSign(PayInfo payInfo) throws Exception {
String signTemp = "appid="+payInfo.getAppid()
+"&attach="+payInfo.getAttach()
+"&body="+payInfo.getBody()
+"&device_info="+payInfo.getDevice_info()
+"&mch_id="+payInfo.getMch_id()
+"&nonce_str="+payInfo.getNonce_str()
+"¬ify_url="+payInfo.getNotify_url()
+"&openid="+payInfo.getOpenid()
+"&out_trade_no="+payInfo.getOut_trade_no()
+"&spbill_create_ip="+payInfo.getSpbill_create_ip()
+"&total_fee="+payInfo.getTotal_fee()
+"&trade_type="+payInfo.getTrade_type()
+"&key="+Constants.key; //这个key注意
MessageDigest md = MessageDigest.getInstance("MD");
md.reset();
md.update(signTemp.getBytes("UTF-"));
String sign = CommonUtil.byteToStr(md.digest()).toUpperCase();
return sign;
}
注意:上面的Constants.key取值在商户号API安全的API密钥中。
一些工具方法:获取ip地址,将字节数组转换为十六进制字符串,将字节转换为十六进制字符串/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
public static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = ; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param btyes
* @return
*/
public static String byteToHexStr(byte bytes) {
char[] Digit = { '', '', '', '', '', '', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[];
tempArr[] = Digit[(bytes >>> ) & XF];
tempArr[] = Digit[bytes & XF];
String s = new String(tempArr);
return s;
}
/**
* 获取ip地址
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
return request.getRemoteAddr();
}
byte[] ipAddr = addr.getAddress();
String ipAddrStr = "";
for (int i = ; i < ipAddr.length; i++) {
if (i > ) {
ipAddrStr += ".";
}
ipAddrStr += ipAddr[i] & xFF;
}
return ipAddrStr;
}
这样就获取了签名,把签名与PayInfo中的其他数据转成XML格式,当做参数传递给统一下单地址。PayInfo pi = pu.createPayInfo(bo,"...","");
String sign = pu.getSign(pi);
pi.setSign(sign);
对象转XML/**
* 扩展xstream使其支持CDATA
*/
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
//增加CDATA标记
boolean cdata = true;
@SuppressWarnings("rawtypes")
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
public static String payInfoToXML(PayInfo pi) {
xstream.alias("xml", pi.getClass());
return xstream.toXML(pi);
}
xml转Map@SuppressWarnings("unchecked")
public static Map parseXml(String xml) throws Exception {
Map map = new HashMap();
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
List elementList = root.elements();
for (Element e : elementList)
map.put(e.getName(), e.getText());
return map;
}
下面就是调用统一下单的URL了log.info(MessageUtil.payInfoToXML(pi).replace("__", "_"));
Map map = CommonUtil.httpsRequestToXML("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", MessageUtil.payInfoToXML(pi).replace("__", "_").replace("", ""));
log.info(map);
public static Map httpsRequestToXML(String requestUrl, String requestMethod, String outputStr) {
Map result = new HashMap<>();
try {
StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr);
result = MessageUtil.parseXml(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:"+ce.getMessage());
} catch (Exception e) {
log.error("https请求异常:"+ece.getMessage());
}
return result;
}
httpsRequest()这个方法在第一篇中
上面获取到的Map如果成功的话,里面就会有String return_code = map.get("return_code");
if(StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")){
String return_msg = map.get("return_msg");
if(StringUtils.isNotBlank(return_msg) && !return_msg.equals("OK")) {
return "统一下单错误!";
}
}else{
return "统一下单错误!";
}
String prepay_Id = map.get("prepay_id");
这个prepay_id就是预支付的ID。后面支付需要它。
更多微信公众号支付(二)实现统一下单接口相关文章请关注PHP中文网!
本文原创发布php中文网,转载请注明出处,感谢您的尊重!
php 微信统一下单接口,微信公众号支付(二)实现统一下单接口相关推荐
- php微信统一公众号支付接口,微信公众号支付怎么实现统一下单接口
微信公众号支付怎么实现统一下单接口 发布时间:2021-03-12 09:44:45 来源:亿速云 阅读:89 作者:小新 这篇文章将为大家详细讲解有关微信公众号支付怎么实现统一下单接口,小编觉得挺实 ...
- 公众号php支付接口开发,公众号支付接口的开发
这次给大家带来公众号支付接口的开发,公众号支付接口开发的注意事项有哪些,下面就是实战案例,一起来看一下. 公众号支付就是在微信里面的H5页面唤起微信支付,不用扫码即可付款的功能.做这个功能首先要明确的 ...
- 微信支付接口(公众号支付)+微信支付回调函数 附代码
前段时间做微信支付,微信浏览器填写金额商品名之后提交跳转付款页面确认然后返回界面判断,今天来详细说下 国际惯例先贴代码 mcontroller.java public void wxpay() {if ...
- 微信支付之公众号支付
经过近一周的敲代码,终于把公众号支付和H5支付实现完成并测试通过,特此分享一些流程,一方面自己记录另一方面给新入门的一点思路 [本文介绍普通商户的公众号支付] 一.基本信息和配置 公众号支付的前提是要 ...
- 微信公众号支付(JSAPI)对接备忘
0 说明 本文里说的微信公众号支付对接指的是对接第三方支付平台的微信公众号支付接口. 非微信支付官方文档里的公众号支付开发者文档那样的对接.不过,毕竟腾讯会把一部分渠道放给银行或有支付牌照的支付机构, ...
- 微信公众号支付,iframe跨域
官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6,即可看到h5调起支付需要的参数. 获取后台调 ...
- vue 微信公众号支付接口_基于vue的h5项目之支付宝支付与微信支付
本文仅记录基于vue开发h5项目过程中使用支付宝和微信支付过程中的重点与槽点,仅为前端部分,如有疏漏不正之处,请于文末评论探讨.注意:标红部分灰常重要,仔细阅读官方文档非常重要,耐心非常重要,细心非常 ...
- 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。
最近公司开发网站针对微信公众号的支付功能. 由于公司目前的这个项目网站是使用asp代码开发的,但是微信官方给出的demo中是没有asp版本的,所以楼主只有下载demo的php版本作为参考写了一个asp ...
- C#微信公众号支付接口对接
这次是第二次对接微信公众号的支付了,第一次代码写的很乱,没有找现成的SDK,感觉里面乱七八糟的东西太多不够清爽,而我仅仅是做一个小功能,对接又不复杂干脆自己做. 不想重复做轮子的朋友可以参考一下:Se ...
- 微信(jspai版本即公众号h5版)支付-微信下单支付及企业转账到零钱
微信(jspai版本即公众号h5版)支付-微信下单支付及企业转账到零钱 一.后端前置条件 二.配置h5 devServer 三.后端开发代码 四.前端开发代码(uniapp) 一.后端前置条件 准备好 ...
最新文章
- linux 编译链接过程,编译程序 一:linux程序编译过程(一)-编译和链接
- python生成10000个样本数据集_python产生随机样本数据
- 进击的 JavaScript(六) 之 this
- OpenJudge:熄灯问题
- Python的datetime
- mysql丢失数据_MySQL数据丢失问题
- php实现标签打印,标签打印软件怎么实现批量套打标签?
- 玛森:Python爬虫书籍推荐
- 人脸识别技术全面总结:从传统方法到深度学习
- required默认提示的修改
- 阅读代码时,用excel做笔记。
- C++ PDF文档相关操作
- [笔记] 关于KAG3中宏参数的类型
- 矢量数据向栅格数据的转换算法
- 相对定位 绝对定位 固定定位 粘性定位 居中的三种方法 calc函数标签的使用方法
- docker部署rabbitmq出错touch: cannot touch ‘/etc/rabbitmq/rabbitmq.conf‘: Permission denied
- 城市级智能网联示范区情况全扫描(2021版)
- 在ts文件中引入js模块,编写声明文件的方法
- 电子学会 全国青少年软件编程等级考试(三级--八级)
- 基于Flink的日志采集
热门文章
- Win系统 - 微星 GS65 笔记本电脑开机黑屏
- win7无法连接打印机拒绝访问_如何解决Win7共享打印机拒绝访问的问题?
- 引领IT大迁徙 Emulex持续优化应用交付
- 关于FeedSky话题广告
- Android自定义带搜索图标及删除按钮的搜索框SearchEditText
- 启动 Tomcat 遇到 Neither the JAVA_HOME nor the JRE_HOME environment variable is defined 问题,已解决
- layui upload 提示语
- 北京课改版三年级英语教案二-Leo老师
- PhD Debate-11 预告 | 回顾与展望神经网络的后门攻击与防御
- qq发的html文件打不开,Win10系统下QQ能上网页却无法打开的三种解决方案