【微信支付】证书文件使用说明
(完整版)微信支付商户平台使用协议.docx

微信支付商户平台使用协议1、特别提示本协议由财付通支付科技有限公司(本协议和附属规则中均称“财付通”)为规范贵司使用微信支付商户平台(本协议和附属规则中均称“本平台”)的行为而制定,具有合同法律效力。
贵司应认真阅读并遵守本协议和《财付通服务协议》。
请贵司务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、争议解决和法律适用条款。
免除或者限制责任的条款可能以加粗字体显示,贵司应重点阅读。
除非贵司已阅读并接受本协议和《财付通服务协议》所有条款,否则贵司无权使用本平台。
贵司使用本平台即视为贵司已阅读并同意本协议和《财付通服务协议》的约束。
如贵司有任何疑问,应向财付通客服咨询。
2、定义如无特别说明,下列术语在本协议中的定义为:2.1微信公众帐号:指贵司在微信公众平台注册的,用于登录微信公众平台的帐号(以下或称“公众帐号”)。
2.2微信支付:指财付通依托微信及微信公众平台提供的第三方支付软件系统和服务。
2.3微信支付商户号:指财付通的支付系统为贵司配置的用来存储贵司的身份信息、交易信息并处理贵司的交易指令的账号。
微信支付商户号将直接与贵司提供的合法银行卡账户绑定,贵司的银行卡账户将根据微信支付商户号的交易情况做相应的资金扣划或归集。
2.4微信支付商户平台:指财付通提供和维护的商户管理软件系统,开通了微信支付的商户可以通过该系统享受微信支付商户号管理和营销推广等相关功能,具体功能以本平台实际提供的为准,且本平台将根据财付通的需要以及对贵司的资质、经营状况的评估对本平台中的功能做调整和增减。
2.5员工账号:指贵司在本平台“员工管理”模块创建的,能够登录贵司的商户管理系统并进行相关操作的帐号。
贵司只能向贵司的员工配置员工账号。
3、贵司的权利和义务3.1在使用本平台前,贵司应开通微信支付服务并获得财付通给贵司配置的微信支付商户号。
3.2贵司应妥善保管微信支付商户号、安全证书、密钥和登录密码等敏感信息,当发生信息泄露或密码遗失时,贵司应立即向客服申请挂失。
微信支付java版(含视频讲解)

微信⽀付java版(含视频讲解)1.背景实际开发中⽤到微信⽀付的概率⾮常⼤,⾄于为什么这⾥不必要我多少......微信⽀付⼤体需要对接的核⼼接⼝有其实⼤部分⽀付都是这些,就像上⼀节我们讲的⽀付宝⽀付⼀样这⾥以常⽤的H5⽀付为例,其他的都是差不多的....值得注意的时候,微信⽀付最常⽤的就是H5⽀付和JSAPI⽀付,这两者的主要区别在于H5⽀付必须在⾮微信浏览器打开;JSAPI⽀付只能在微信的浏览器打开;1.统⼀下单2.查询订单3.⽀付结果通知4.申请退款5.查询退款6.下载对账单2.需要准备的环境微信⽀付⽬前还没有沙箱测试环境,要开开发⽀付功能必须要有企业资质申请公众号和商户号才可以主要的是:公众号appid商户号商户号的apiSercet密码商户号的证书商户号上绑定好的回调域名3.开发步骤3.1.统⼀下单代码如下:package er.service.impl;import cn.hutool.core.date.DateUtil;import cn.hutool.core.util.NumberUtil;import cn.hutool.core.util.RandomUtil;import cn.hutool.core.util.StrUtil;import cn.hutool.http.HttpUtil;import com.alibaba.fastjson.JSON;import mon.constant.PayConstant;import mon.constant.PayEnum;import mon.constant.TestData;import mon.constant.WeChatConstant;import mon.exception.ParamException;import mon.exception.WeChatException;import mon.util.wechat.WXPayUtil;import er.entity.bo.PayBO;import er.entity.vo.PayVO;import er.service.IPayService;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service;import java.util.Date;import java.util.HashMap;import java.util.Map;/*** @Copyright (C) XXXXXX科技股份技有限公司* @Author: lidongping* @Date: 2021-01-07 18:47* @Description:*/@Service@Slf4jpublic class WeChatPayService implements IPayService {@Overridepublic String getPayType() {return PayConstant.WECHAT;}@Overridepublic PayVO getPayInfo(PayBO payBO) throws Exception {// 根据订单号查询订单数据和⽀付账号数据// 这⾥测试直接将数据写在代码⾥payBO.setAppId(TestData.WX_APP_ID).setMerchantId(TestData.WX_MERCHANT_ID).setApiSecretKey(TestData.WX_SECRET).setPayTitle("测试⽀付").setPayMoney(0.01).setProductNo("P001").setAsynchronousNotifyUrl("/api/async/wechat/payment").setOpenId("ozwLvwah3xtA93csvZTWr0wON_IU");// 以下是封装微信⽀付数据Map dic = new HashMap<String, String>();dic.put("appid", payBO.getAppId());dic.put("mch_id", payBO.getMerchantId());String nonceStr = RandomUtil.randomString(30);dic.put("nonce_str", nonceStr);dic.put("body", payBO.getPayTitle());dic.put("out_trade_no", payBO.getOrderNo());String amount = NumberUtil.roundStr(payBO.getPayMoney() * 100, 0);dic.put("total_fee", amount);dic.put("spbill_create_ip", payBO.getUserIp());dic.put("notify_url", payBO.getAsynchronousNotifyUrl());// ⽣成的⽀付信息⼀⼩时内有效dic.put("time_expire", DateUtil.format(DateUtil.offsetHour(new Date(), 1), "yyyyMMddHHmmss"));// 根据类型请求⽀付PayEnum payType = PayEnum.valueOf(payBO.getPayType());switch (payType) {case WECHAT_QR:dic.put("trade_type", "NATIVE");dic.put("product_id", payBO.getProductNo());break;case WECHAT_JSAPI:dic.put("trade_type", "JSAPI");if (StrUtil.isEmpty(payBO.getOpenId())) {throw new ParamException("openid 为空");}dic.put("openid", payBO.getOpenId());break;case WECHAT_H5:dic.put("trade_type", "MWEB");break;default:throw new ParamException("没有对应的⽀付⽅式");}("签名前:" + JSON.toJSONString(dic));dic.put("sign", WXPayUtil.generateSignature(dic, payBO.getApiSecretKey()));String dataXml = WXPayUtil.mapToXml(dic);("微信请求下单url:" + WeChatConstant.PAY_URL);("微信请求下单参数:" + dataXml);String resp = HttpUtil.post(WeChatConstant.PAY_URL, dataXml, 60 * 1000);("微信请求下单返回:" + resp);Map<String, String> resMap = WXPayUtil.xmlToMap(resp);// 请求失败if (!resMap.get("return_code").equalsIgnoreCase(WeChatConstant.SUCCESS)) {throw new WeChatException(resMap.get("return_msg"));}// 下单失败if (!resMap.get("result_code").equalsIgnoreCase(WeChatConstant.SUCCESS)) {throw new WeChatException(resMap.get("err_code_des"));}// 校验⽀付返回结果签名if (!checkSign(resMap, payBO.getApiSecretKey())) {throw new WeChatException("验证签名失败");}// 处理返回结果PayVO payVO = new PayVO();payVO.setOrderNo(payBO.getOrderNo());switch (payType) {case WECHAT_QR:payVO.setPayInfo(resMap.get("code_url"));break;case WECHAT_JSAPI:Map jsapi = new HashMap<String, String>();jsapi.put("appId", payBO.getAppId());// 当前时间秒jsapi.put("timeStamp", System.currentTimeMillis() / 1000 + "");jsapi.put("nonceStr", nonceStr);jsapi.put("package", "prepay_id=" + resMap.get("prepay_id"));jsapi.put("signType", "MD5");jsapi.put("paySign", WXPayUtil.generateSignature(jsapi, payBO.getApiSecretKey()));payVO.setPayInfo(jsapi);break;default:payVO.setPayInfo(resMap.get("mweb_url"));}return payVO;}/*** 微信响应数据签名检查** @param map* @param key* @return* @throws Exception*/private static boolean checkSign(Map<String, String> map, String key) throws Exception {String sign = map.get("sign");map.remove("sign");String orign = WXPayUtil.generateSignature(map, key);return orign.equalsIgnoreCase(sign);}}View Code3.2.异步通知代码如下:package er.controller;import cn.hutool.extra.servlet.ServletUtil;import com.alibaba.fastjson.JSON;import mon.constant.TestData;import mon.constant.WeChatConstant;import mon.util.RedisUtil;import mon.util.wechat.WXPayUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import java.util.Map;/*** @author姿势帝-博客园* @address https:///newAndHui/* @WeChat 851298348* @create 01/10 11:18* @description*/@RestController@Slf4jpublic class WeChatController {/*** 注意:* 1.这⾥是只⽀付宝微信xml的参数接收,微信最近也提供了json的⽅式,本质上都是⼀样的* 2.xml参数回调⽂档:https:///wiki/doc/api/H5.php?chapter=9_7&index=8** @param request* @return* @throws Exception*/@PostMapping("/async/wechat/payment")public String notifyPaymentResult(HttpServletRequest request) throws Exception {("wechat异步回调....");String paramXml = ServletUtil.getBody(request);Map<String, String> paramsMap = WXPayUtil.xmlToMap(paramXml);//解析参数String returnCode = paramsMap.get("return_code");String tradeStatus = paramsMap.get("result_code");String appid = paramsMap.get("appid");String totalFee = paramsMap.get("total_fee");String orderNo = paramsMap.get("out_trade_no");if (!WeChatConstant.SUCCESS.equals(returnCode)) {log.error("回调状态错误:returnCode={}", returnCode);return WeChatConstant.RETURN_FAIL;}// TODO 这⾥实际开发时根据订单号获取apiSecret秘钥String apiSecret = TestData.WX_SECRET;// 验签if (!WXPayUtil.isSignatureValid(paramsMap, apiSecret)) {log.error("验签失败");return WeChatConstant.RETURN_FAIL;}if (!WeChatConstant.SUCCESS.equals(tradeStatus)) {log.error("⽀付状态失败:tradeStatus={}", tradeStatus);return WeChatConstant.RETURN_FAIL;}// TODO 更新数据库订单数据和缓存 ... 这⾥略// 这⾥只是模拟⽅放⼊缓存,便于前端查询订单 60 * 60 * 2L 表⽰缓存2⼩时RedisUtil.set(orderNo, JSON.toJSON(paramsMap), 60 * 60 * 2L);("异步处理成功.............");return WeChatConstant.RETURN_SUCCESS;}}View Code3.3.测试获取微信⽀付信息@Testvoid getPayInfo() {String url = urlLocal + "/userOrder/payInfo";System.out.println("请求地址:" + url);HttpRequest request = HttpUtil.createRequest(Method.GET, url);Map<String, Object> map = new HashMap<>();map.put("orderNo", "NO" + System.currentTimeMillis());// 微信⽀付 wechat ⽀付宝 alipaymap.put("payCategory", "wechat");// 201 jsapi⽀付 , 202 微信H5 101⽀付宝H5map.put("payType", "202");request.form(map);System.out.println("请求参数:" + map);request.header("X-Real_IP", "192.168.5.195");request.setConnectionTimeout(60 * 1000);String respone = request.execute().body();System.out.println("响应结果:" + respone);}View Code测试结果请求地址:http://localhost:8080/api/userOrder/payInfo请求参数:{payCategory=wechat, orderNo=NO1610250837438, payType=202}响应结果:{"message":"success","code":100,"data":{"orderNo":"NO1610250837438","payInfo":"https:///cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx10115509234051b333adbe01d032b80000&package=2821154835"}}从响应的结果看,我们已经拿到了payInfo,也就是跳转到微信的url正常情况下,只要在⾮微信浏览器打开就可以了,但是微信那边对请求来源的域名做了校验,我们这⾥测试不是很⽅便,就不继续演⽰下去了因为实际开发中只要⾛到这⼀步,对于开发⼈员来说代码就已经合格了,如果只会⽀付不了,那多半是微信商户号上的配置有问题....学习我们就到这⾥,如果在实际开发中有问题可以咨询我,共同交流技术!4.总结1.这⾥只是给⼤家演⽰了统⼀下单和⽀付回调的代码,也是微信⽀付的核⼼代码,相信只要这调通了,其他的接⼝类似!2.为了更好让⼤家快速掌握微信⽀付,这篇博客已经做了配套的视频讲解,⼤家可以结合视频讲解学习,或者单独问我!完美!。
微信支付商户平台使用协议

微信支付商户平台使用协议1、特别提示本协议由财付通支付科技有限公司(为便于理解,下称“本公司”)为规范您(包括个人、个体工商户和企事业单位)使用微信支付商户平台(下称“本平台”)的行为而制定,具有合同法律效力。
您应认真阅读并遵守本协议、《微信支付违规商户处理规则》和《微信公众平台运营规范》。
请您务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、争议解决和法律适用条款。
免除或者限制责任的条款可能以加粗字体显示,您应重点阅读。
除非您已阅读并接受本协议和《微信公众平台运营规范》所有条款,否则您无权使用本平台。
您使用本平台即视为您已阅读并同意本协议和《微信公众平台运营规范》的约束。
如您有任何疑问,应向本公司客服咨询。
任何您之前与本公司签订的《微信支付服务协议》若与本协议有不一致之处,则不一致之处以本协议约定为准。
2、定义如无特别说明,下列术语在本协议中的定义为:2.1 微信公众帐号:指您在微信公众平台注册的,用于登录微信公众平台的帐号(以下或称“公众帐号”)。
2.2 微信支付服务:指本公司依托微信及微信公众平台为收付款人之间提供的货币资金转移服务。
2.3 微信支付商户号:指本公司为您配置的用来记载您的身份信息、交易信息、资金余额,您凭以发起交易指令的电子簿记。
微信支付商户号将与您提供的合法银行账户绑定,您的银行账户将根据您的交易指令和微信支付商户号的交易情况做相应的资金扣划和归集。
2.4 微信支付商户平台:指本公司提供和维护的商户管理软件系统,您应通过该系统提交相应资料和信息,进而开通微信支付。
成功开通后,您可以通过该系统使用微信支付商户号管理和营销推广等相关功能,具体功能以该系统实际提供的为准,且该系统将根据本公司的需要进行调整和增减。
2.5 商户平台登录账号:指您凭以登录本平台,操作微信支付商户号的账号,您成功申请微信支付商户号后,本公司将向您发送电子邮件,告知您的登录账号及初始密码,您可在本平台中修改该初始密码,您亦可在本平台的“员工管理”模块中为该登录账号设置多个附属登录账号及对应的登录密码,并为附属登录账号配置相应的操作权限。
如何正确使用微信支付?

如何正确使用微信支付?微信支付是一种方便快捷的支付方式,越来越多的人开始使用它来进行生活消费。
然而,有些人可能对如何正确使用微信支付感到困惑。
下面将详细介绍使用微信支付的步骤和注意事项,以帮助读者正确地使用微信支付。
一、绑定银行卡1. 打开微信,点击右上角的“我”,进入个人中心页面。
2. 在个人中心页面,点击“钱包”选项进入钱包界面。
3. 在钱包界面,点击“添加银行卡”按钮。
4. 根据提示,输入银行卡信息,包括卡号、姓名、身份证号等,并验证手机验证码。
5. 提交信息后,等待微信对银行卡进行验证,验证成功后,即可成功绑定银行卡。
二、充值微信钱包1. 打开微信,点击右上角的“我”,进入个人中心页面。
2. 在个人中心页面,点击“钱包”选项进入钱包界面。
3. 在钱包界面,点击“充值”按钮。
4. 根据提示,选择充值的金额,并选择需要使用的支付方式,如银行卡支付、支付宝支付等。
5. 根据支付方式的要求,输入相应的支付信息,如银行卡号、支付宝账号等。
6. 完成支付操作后,等待充值成功的提示即可。
三、使用微信支付1. 在商店购买商品或服务时,选择微信支付方式。
2. 商家会生成一个二维码,将其展示给你。
3. 打开微信,点击右上角的“扫一扫”按钮。
4. 使用微信扫描商家展示的二维码。
5. 根据支付页面提示,确认支付金额并输入支付密码或进行人脸识别等验证。
6. 确认支付后,等待支付成功的提示即可。
四、注意事项1. 在绑定银行卡时,务必确保输入的信息准确无误,以免影响后续使用。
2. 在充值微信钱包时,要选择可靠的支付方式,并注意支付安全。
3. 在使用微信支付时,要确保商家是正规合法的,避免信息泄露或被骗等问题。
4. 对于大额支付或重要支付,可以设置额外的支付密码或开启支付验证功能,提高支付安全性。
5. 定期查看微信支付账单,及时核实交易记录,防止出现异常情况。
通过以上步骤和注意事项的详细介绍,相信读者已经对如何正确使用微信支付有了清晰的认识。
如何正确使用微信支付

如何正确使用微信支付引言:随着移动支付的普及,微信支付成为了人们生活中常见的支付方式之一。
正确使用微信支付不仅可以提高支付效率,还能保障资金安全。
本文将介绍如何正确使用微信支付,以便用户在使用过程中能够更加方便快捷地完成支付。
一、绑定银行卡在使用微信支付之前,首先需要绑定银行卡。
具体操作步骤如下:1. 打开微信APP并登录自己的微信账号。
2. 在底部导航栏中找到并点击“支付”图标。
3. 在支付页面中,点击右上角的“银行卡”图标。
4. 点击“添加银行卡”。
5. 根据提示,输入自己的银行卡信息,并进行验证。
6. 完成验证后,绑定银行卡就成功完成了。
二、设置支付密码为了提高支付安全性,微信支付支持设置支付密码。
设置支付密码可以有效防止他人恶意使用自己的账号进行消费。
下面是设置微信支付密码的步骤:1. 打开微信APP并登录自己的微信账号。
2. 在底部导航栏中找到并点击“支付”图标。
3. 在支付页面中,点击右上角的“银行卡”图标。
4. 在银行卡页面中,选择“支付密码管理”。
5. 点击“设置支付密码”。
6. 根据提示,输入自己的密码,并进行验证。
7. 完成验证后,支付密码就设置成功了。
三、安全使用微信支付在使用微信支付时,为了确保资金的安全,我们需要注意以下几个方面:1. 保护账号安全:不要将微信账号和密码告诉他人,避免账号被盗用。
2. 定期修改支付密码:定期修改支付密码可以增加支付安全性。
3. 验证支付信息:在支付过程中,一定要仔细核对支付金额、商户信息等,以免被诈骗。
4. 拒绝陌生请求:不要随意点击陌生链接或扫描未知二维码,以免陷入损失。
5. 及时关注账单:定期查看自己的微信支付账单,如发现异常情况及时联系客服解决。
四、快捷支付功能微信支付还提供了一些方便快捷的支付功能,以提高用户的支付效率。
1. 付款码支付:在商家收银台出示自己的付款码,即可完成支付,无需输密码。
2. 公众号支付:在微信公众号中打开商家页面,选择商品后即可直接支付。
微信支付申请指引

微信支付申请指引微信公众号运营者:微信支付已正式开放申请。
已通过微信认证的服务号可登录微信公众平台,点击“服务”—“服务中心”—“商户功能”提交资料(详细指引请参考商户服务中心),申请公众号支付或App支付功能。
任何问题或意见请邮件联系“weixinpay@”。
微信商户服务中心1. 微信支付功能申请1.1 申请流程指引一、申请流程图:二、申请流程详细说明:(一)完成服务号认证:1、微信支付功能目前仅对完成微信认证的服务号开放申请(企业、媒体、政府及其他组织)。
若公众帐号符合开放申请要求,可直接进入第二步(微信公众平台提交资料);2、订阅号可先升级为服务号,升级方法:登录微信公众平台—设置—帐号信息—升级为服务号;3、未认证的服务号需先完成微信认证。
注:商户申请微信认证的主体与申请开通微信支付功能的主体需保持一致。
(二)完成申请资料审核:1、登录微信公众平台,进入:服务-服务中心-商户功能;2、提交商户基本资料请准确选择经营范围,并如实填写出售的商品/服务信息,此处填写的信息将作为日后运营监管的依据;3、提交业务审核资料商户提交的资料,主体需与微信认证主体保持一致,以保证运营主体即认证主体;4、提交财务审核资料商户提交的财务资料,主体需与业务审核资料主体一致,以保证结算主体即运营主体;商户提交的所有资料,需加盖公章。
5、资料审核:1)商户申请资料提交成功后,腾讯在7个工作日内反馈审核结果;2)审核结果将以电子邮件的形式告知商户。
商户也可登录微信公众平台,点击页面右上角小信封图标查看。
3)审核通过的通知邮件中,将包含非常重要的开发参数,请商户牢记申请时填写的“重要邮箱”地址,相关通知一经发送至“重要邮箱”地址,则视为腾讯已经向商户履行了通知义务。
重要邮箱”是商户在填写“业务审核资料”时设置的:(三)功能开发、合同签订:1、资料审核通过的商户可以进行功能开发工作:腾讯提供清晰的开发接口文档,帮助商户顺利完成功能开发工作。
微信支付v3版几个重难点(签名、验签、加密、解密)的python实现
微信⽀付v3版⼏个重难点(签名、验签、加密、解密)的python实现背景介绍v3版微信⽀付通过商户证书和平台证书加强了安全性,也⼤幅提⾼了开发难度,python版sdk包内部封装了安全性相关的签名、验签、加密和解密⼯作,降低了开发难度。
下⾯⼏个特性的实现,更⽅便了开发者。
1. 平台证书⾃动更新,⽆需开发者关注平台证书有效性,⽆需⼿动下载更新;2. ⽀持本地缓存平台证书,初始化时指定平台证书保存⽬录即可。
3. 敏感信息直接传⼊明⽂参数,SDK内部⾃动加密,⽆需⼿动处理。
在这⾥将sdk内部⼏个涉及到安全性的⽅法单独抽出来结合官⽅⽂档对照⼀下,⽅便⼤家更直观的理解,有兴趣探究sdk内部实现细节的同学可以了解⼀下,⼀般应⽤的⽆需关注,直接调⽤sdk包即可。
构造签名信息对应v3版微信⽀付api⽂档的部分。
def build_authorization(path,method,mchid,serial_no,mch_private_key,data=None,nonce_str=None):timeStamp = str(int(time.time()))nonce_str = nonce_str or ''.join(str(uuid.uuid4()).split('-')).upper()body = json.dumps(data) if data else ''sign_str = '%s\n%s\n%s\n%s\n%s\n' % (method, path, timeStamp, nonce_str, body)signature = rsa_sign(private_key=mch_private_key, sign_str=sign_str)authorization = 'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%s",serial_no="%s"' % (mchid, nonce_str, signature, timeStamp, serial_no) return authorization验证签名对应v3版微信⽀付api⽂档的部分。
微信支付第三方sdk使用
微信⽀付第三⽅sdk使⽤1、引⼊依赖:(对于依赖冲突⾃⾏解决)<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><!--<version>3.4.9.B</version>--><version>3.5.0</version><exclusions><exclusion><artifactId>httpclient</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion><exclusion><artifactId>commons-lang3</artifactId><groupId>mons</groupId></exclusion><exclusion><artifactId>commons-beanutils</artifactId><groupId>commons-beanutils</groupId></exclusion><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency>2、package com.dhht.wechat.controller;import com.dhht.wechat.VO.PayVO;import com.dhht.wechat.service.PayService;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;/** @Author: sh* @Description: WxPayController* @Date: 11:06 2019/7/17*/@RestController@RequestMapping("wechat/")public class WxPayController {@Resourceprivate PayService payService;/*** 微信⽀付统⼀下单接⼝(H5)* @param payVO* @param request* @return*/@PostMapping(value = "pay",produces = "application/json;charset=UTF-8")public String unifiedOrder(@RequestBody PayVO payVO, HttpServletRequest request){return payService.unifiedOrder(payVO,request);}/*** 微信⽀付接收通知接⼝(供微信服务调⽤)* @param xmlData* @return*/@PostMapping(value = "pay/notify",produces = "application/json;charset=UTF-8")public synchronized String payNotify(@RequestBody String xmlData){return payService.payNotifyCallBack(xmlData);}/*** 退款结果通知接⼝* @param xmlData* @return*/@PostMapping("/notify/refund")public synchronized String parseRefundNotifyResult(@RequestBody String xmlData) {return payService.parseRefundNotifyResult(xmlData);}}package com.dhht.wechat.service;import com.alibaba.fastjson.JSON;import com.dhht.wechat.VO.PayVO;import com.dhht.wechat.service.impservice.OrderRefundResultImplService; import com.dhht.wechat.service.impservice.SealOrderImplService;import com.dhht.wechat.service.impservice.SealOrderSealImplService; import com.dhht.wechat.util.ConstantUtil;import com.dhht.wechat.util.DateUtil;import com.dhht.wechat.wxpay.MyX509TrustManager;import com.dhht.wechat.wxpay.PayRespCodeMsg;import com.dhht.wechat.wxpay.PayResultVO;import com.dhht.wechat.wxpay.WechatPayConfigBean;import com.dhht.wechat.wxpay.config.WxPayProperties;import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.request.*;import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; import com.github.binarywang.wxpay.service.WxPayService;import net.sf.json.JSONObject;import ng3.StringUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import javax.annotation.Resource;import .ssl.HttpsURLConnection;import .ssl.SSLContext;import .ssl.SSLSocketFactory;import .ssl.TrustManager;import javax.servlet.http.HttpServletRequest;import java.io.*;import java.math.BigDecimal;import .ConnectException;import .URL;import java.security.MessageDigest;import java.text.MessageFormat;import java.util.*;/*** WxPayService*/@Servicepublic class PayService {@Resourceprivate WechatPayConfigBean wechatPayConfigBean;@Resourceprivate WxPayProperties wxPayProperties;// 第三⽅@Resourceprivate SealOrderImplService sealOrderImplService;@Resourceprivate WxPayService wxService;// 第三⽅sdk// @Resource// private OrderPayResultImplService orderPayResultImplService;@Resourceprivate OrderRefundResultImplService orderRefundResultImplService;@Value("${spbill_create_ip}")private String SPBILL_CREATE_IP;@Value("${appSecret}")private String appSecret;@ResourceWeiXinService weiXinService;@ResourceSealOrderSealImplService sealOrderSealImplService;/*** 微信⽀付统⼀下单接⼝(H5)** @param payVO* @param request* @return*/public String unifiedOrder(PayVO payVO, HttpServletRequest request) { try {String orderId = payVO.getOrderId();String code = payVO.getCode();if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(code)) {PayResultVO payResultVO = new PayResultVO(-1, "NO", null);return JSON.toJSONString(payResultVO);}WxPayOrderQueryResult payOrderQueryResult = wechatOrderQuery(orderId);// wxService.queryOrder(null, orderId);// 查询订单状态String payOrderQuery_return_code = payOrderQueryResult.getReturnCode();// SUCCESS/FAILif (ConstantUtil.PAY_RETURN_CODE_NO.equals(payOrderQuery_return_code)) {// 通信失败:FAILPayResultVO queryPayResultVO = new PayResultVO(-1, payOrderQueryResult.getReturnMsg(), null);return JSON.toJSONString(queryPayResultVO);// 订单查询接⼝通信失败,直接返回}// 订单查询通信成功:SUCCESS// 若业务成功/*** trade_state状态如下:* SUCCESS—⽀付成功* REFUND—转⼊退款* NOTPAY—未⽀付* CLOSED—已关闭* REVOKED—已撤销(刷卡⽀付)* USERPAYING--⽤户⽀付中* PAYERROR--⽀付失败(其他原因,如银⾏返回失败)商户订单⽀付失败需要⽣成新单号重新发起⽀付,要对原订单号调⽤关单,避免重复⽀付*/String trade_state = payOrderQueryResult.getTradeState();if (!ConstantUtil.PAY_TRADE_STATE_NOTPAY.equals(trade_state) && null != trade_state) {// ⾮未⽀付状态下(可以为null-代表还未⽣成订单,故需过滤掉)PayResultVO tradePayResultVO = new PayResultVO(-1, ConstantUtil.PAY_STATUS_MAP.get(trade_state), null);return JSON.toJSONString(tradePayResultVO);}// 以下转⼊订单未⽀付处理或还没有⽣成订单(trade_state==null)的处理逻辑//String openUrl = "https:///sns/oauth2/access_token?appid="+wxPayProperties.getAppId()+"&secret="+appSecret+"&code="+code+"&grant_type=authorization_code"; String openId = weiXinService.getOpenId(code);//SendMsgUtil.httpRequest(openUrl,"GET","{}").getString("openid");// 获取openid// 更新订单openId--2019-09-17Map<String, Object> paMap = new HashMap<>();paMap.put("orderId", orderId);paMap.put("userOpenId", openId);sealOrderImplService.updateOrderInfo(paMap);// 获取本系统印章订单信息Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业⽹点扩展信息表中的⼦商户号-20190910if (StringUtils.isEmpty(SUB_MCH_ID)) {// 若⽆配置⼦商户号退出PayResultVO payResultVO = new PayResultVO(-1, "NO-SUB_MCH_ID", null);return JSON.toJSONString(payResultVO);}String siteName = (String) orderDetails.get("siteName");// 营业⽹点名称(刻章店名称)float orderPrice = ((BigDecimal) orderDetails.get("ORDER_AMOUNT")).floatValue();// 订单总⾦额String bodyName = siteName + "-" + ConstantUtil.ADVANCE_PAY_GOODS_NAME;// 商品名称严格按照规范-公众号⽀付-例如(商家名称-销售商品类⽬)// 设置统⼀下单请求参数// 请求对象,注意⼀些参数如appid、mchid等不⽤设置,⽅法内会⾃动从配置对象中获取到(前提是对应配置中已经设置)WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();orderRequest.setAppid(wxPayProperties.getAppId());// 服务商appidorderRequest.setMchId(wxPayProperties.getMchId());// 商户号orderRequest.setSubMchId(SUB_MCH_ID);// ⼦商户号String nonceStr = DateUtil.get32UUIDMilli();orderRequest.setNonceStr(nonceStr);// 随机串,32位以内!orderRequest.setSignType(wxPayProperties.getSignType());// 签名类型orderRequest.setBody(bodyName);orderRequest.setOutTradeNo(orderId);orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(orderPrice + ""/*order.getTotalFee()*/));//元转成分orderRequest.setSpbillCreateIp(SPBILL_CREATE_IP);// 终端IPorderRequest.setNotifyUrl(wxPayProperties.getNotifyUrl());// ⽀付结果异步回调地址orderRequest.setTradeType(wxPayProperties.getTradeType());// 交易类型orderRequest.setOpenid(openId);// 设置openidWxPayMpOrderResult wxPayUnifiedOrderResult = wxService.createOrder(orderRequest);// 统⼀下单接⼝调⽤结果String appId = wxPayUnifiedOrderResult.getAppId();String timeStamp = create_timestamp();String package_ = wxPayUnifiedOrderResult.getPackageValue();// ConstantUtil.PACKAGE_SUFFIX + wxPayUnifiedOrderResult.getPackageValue();String paySign = wxPayUnifiedOrderResult.getPaySign();Map<String, Object> resultMapData = new HashMap<>();resultMapData.put("appId", appId);resultMapData.put("timeStamp", timeStamp);resultMapData.put("package", package_);resultMapData.put("paySign", paySign);resultMapData.put("nonceStr", wxPayUnifiedOrderResult.getNonceStr());resultMapData.put("signType", wxPayProperties.getSignType());PayResultVO paySucessResultVO = new PayResultVO(0, "OK", resultMapData);return JSON.toJSONString(paySucessResultVO);} catch (Exception e) {Map map = new HashMap();map.put("data", e.getMessage());PayResultVO payResultVO = new PayResultVO(-1, "NO", map);return JSON.toJSONString(payResultVO);}}/*** ⽀付回调** @param xmlData* @return*/public synchronized String payNotifyCallBack(String xmlData) {try {WxPayOrderNotifyResult wxPayOrderNotifyResult = wxService.parseOrderNotifyResult(xmlData);// 解析xml字符串String return_code = wxPayOrderNotifyResult.getReturnCode();// SUCCESS/FAILif (ConstantUtil.PAY_RETURN_CODE_NO.equals(return_code)) {// ⽀付通信失败return WxPayNotifyResponse.fail("FAIL");}// 以下通信成功操作String out_trade_no = wxPayOrderNotifyResult.getOutTradeNo();// 商户系统内部订单号(即本系统印章订单号)// 内部订单⽀付情况Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(out_trade_no);if (null != orderDetails) {String paySta = (Integer) orderDetails.get("PAY_STATUS") + "";if ((ConstantUtil.ORDER_PAYSTATUS_1_ + "").equals(paySta)) {// 已⽀付直接返回return WxPayNotifyResponse.success("OK");}}if (ConstantUtil.PAY_RETURN_CODE_OK.equals(return_code)) {// ⽀付接⼝通信成功String result_code = wxPayOrderNotifyResult.getResultCode();// SUCCESS/FAIL 是否真实⽀付成功if (ConstantUtil.PAY_RETURN_CODE_OK.equals(result_code)) {// ⽀付成功// 检查本库是否已经插⼊⽀付成功记录// orderPayResultImplService.deleteByOrderId(out_trade_no);//orderPayResultImplService.add(wxPayOrderNotifyResult);//orderPayResultImplService.insertSelective(wxPayOrderNotifyResult);sealOrderImplService.updateOrderPaySta(out_trade_no, ConstantUtil.ORDER_PAYSTATUS_1_);// 更新⽀付状态 // 推送微信内容-2019-09-18sealOrderSealImplService.sendWXMsgToSite(out_trade_no);}if (ConstantUtil.PAY_RETURN_CODE_NO.equals(result_code)) {// ⽀付失败closePayOrder(out_trade_no);// ⽀付失败的话,需要关闭订单,才能重新⽀付sealOrderImplService.upOrderRelation(out_trade_no);// 更新该订单的id,主要⽤于重新⽀付sealOrderImplService.updateOrderPaySta(out_trade_no, ConstantUtil.ORDER_PAYSTATUS_2_);// 更新⽀付状态 }return WxPayNotifyResponse.success("OK");} else {// ⽀付结果通信失败return WxPayNotifyResponse.fail("FAIL");}} catch (Exception e) {return WxPayNotifyResponse.fail("FAIL");}}/*** 查询订单状态** @param orderId* @return*/public WxPayOrderQueryResult wechatOrderQuery(String orderId) {try {if (StringUtils.isEmpty(orderId)) {return null;}Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业⽹点扩展信息表中的⼦商户号-20190910WxPayOrderQueryRequest wxPayOrderQueryRequest = new WxPayOrderQueryRequest();wxPayOrderQueryRequest.setAppid(wxPayProperties.getAppId());wxPayOrderQueryRequest.setMchId(wxPayProperties.getMchId());wxPayOrderQueryRequest.setSubMchId(SUB_MCH_ID);// ⼦商户好最终通过orderId从本系统获取wxPayOrderQueryRequest.setOutTradeNo(orderId);// 微信内部订单号与本系统订单号⼆选⼀wxPayOrderQueryRequest.setNonceStr(DateUtil.get32UUIDMilli());wxPayOrderQueryRequest.setSignType(wxPayProperties.getSignType());WxPayOrderQueryResult wxPayOrderQueryResult = wxService.queryOrder(wxPayOrderQueryRequest);return wxPayOrderQueryResult;} catch (Exception e) {WxPayOrderQueryResult wxPayOrderQueryResult = new WxPayOrderQueryResult();wxPayOrderQueryResult.setReturnCode(ConstantUtil.PAY_RETURN_CODE_OK);wxPayOrderQueryResult.setResultCode(ConstantUtil.PAY_RETURN_CODE_OK);wxPayOrderQueryResult.setTradeState(null);return wxPayOrderQueryResult;}}/*** 关闭订单(关闭订单之后,重新提交⽀付需要更新订单号!)** @param orderId* @return*/public WxPayOrderCloseResult closePayOrder(String orderId) {if (StringUtils.isEmpty(orderId)) {return null;}try {Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业⽹点扩展信息表中的⼦商户号-20190910WxPayOrderCloseRequest wxPayOrderCloseRequest = new WxPayOrderCloseRequest();wxPayOrderCloseRequest.setAppid(wxPayProperties.getAppId());wxPayOrderCloseRequest.setMchId(wxPayProperties.getMchId());wxPayOrderCloseRequest.setSubMchId(SUB_MCH_ID);// 从本系统获取通过orderDetailswxPayOrderCloseRequest.setOutTradeNo(orderId);wxPayOrderCloseRequest.setNonceStr(DateUtil.get32UUIDMilli());wxPayOrderCloseRequest.setSignType(wxPayProperties.getSignType());WxPayOrderCloseResult wxPayOrderCloseResult = wxService.closeOrder(wxPayOrderCloseRequest);return wxPayOrderCloseResult;} catch (Exception e) {return null;}}/*** 订单退款(接⼝请求并⾮退款结果)** @param orderId* @return*/public PayResultVO refundPayOrder(String orderId) {try {if (StringUtils.isEmpty(orderId)) {return null;}Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息 // 查询微信⽀付订单信息WxPayOrderQueryResult wxPayOrderQueryResult = wechatOrderQuery(orderId);String order_return_code = wxPayOrderQueryResult.getReturnCode();// 订单查询⽹络状态if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(order_return_code)) {PayResultVO returnPayResultVO = new PayResultVO(-1, ConstantUtil.PAY_NETWORK_EXCEP, null);return returnPayResultVO;}String order_result_code = wxPayOrderQueryResult.getResultCode();// 订单查询业务状态if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(order_result_code)) {PayResultVO resultPayResultVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);return resultPayResultVO;}String order_trade_state = wxPayOrderQueryResult.getTradeState();// 订单状态(已⽀付、未⽀付等等)if (!ConstantUtil.PAY_TRADE_STATE_SUCCESS.equals(order_trade_state)) {// 未⽀付成功,直接返回PayResultVO tradePayResultVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);}// 以下为订单已⽀付后续操作(只有order_trade_state为SUCCESS可获取如下参数)String transaction_id = wxPayOrderQueryResult.getTransactionId();// 微信内部⽀付订单号int total_fee = wxPayOrderQueryResult.getTotalFee();// 订单总⾦额String sub_mch_id = wxPayOrderQueryResult.getSubMchId();// 订单⼦商户号String out_trade_no = wxPayOrderQueryResult.getOutTradeNo();WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();wxPayRefundRequest.setAppid(wxPayProperties.getAppId());wxPayRefundRequest.setMchId(wxPayProperties.getMchId());wxPayRefundRequest.setSubMchId(sub_mch_id);// 从本系统通过orderId获取wxPayRefundRequest.setNonceStr(DateUtil.get32UUIDMilli());wxPayRefundRequest.setSignType(wxPayProperties.getSignType());wxPayRefundRequest.setTransactionId(transaction_id);wxPayRefundRequest.setOutTradeNo(out_trade_no);// 商户内部订单号String refundNo = DateUtil.get32UUIDMilli();// ⽣成商户内部退款单号wxPayRefundRequest.setOutRefundNo(refundNo);// 商户内部退款单号wxPayRefundRequest.setTotalFee(total_fee);wxPayRefundRequest.setRefundFee(total_fee);// 申请退款⾦额????wxPayRefundRequest.setNotifyUrl(wxPayProperties.getRefundNotifyUrl());// 退款结果通知urlWxPayRefundResult wxPayRefundResult = wxService.refund(wxPayRefundRequest);// 订单退款接⼝String refund_return_code = wxPayRefundResult.getReturnCode();// 退款接⼝⽹络状态if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(refund_return_code)) {PayResultVO refundExPayVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);return refundExPayVO;}String refund_result_code = wxPayRefundResult.getResultCode();// 退款接⼝结果状态if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(refund_result_code)) {PayResultVO refundFailPayVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);return refundFailPayVO;}// 以下为退款成功操作PayResultVO refundSuceesResultVO = new PayResultVO(0, "OK", wxPayRefundResult);Map<String, Object> paramMap = new HashMap<>();paramMap.put("refundNo", refundNo);// 内部退款单号sealOrderImplService.updateOrderInfo(paramMap);return refundSuceesResultVO;} catch (Exception e) {return null;}}/*** 退款回调通知地址** @param xmlData* @return*/public synchronized String parseRefundNotifyResult(String xmlData) {try {WxPayRefundNotifyResult result = wxService.parseRefundNotifyResult(xmlData);String return_code = result.getReturnCode();if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(return_code)) {// 通信失败return WxPayNotifyResponse.fail("FAIL");}// 以下为通信成功返回的字段信息WxPayRefundNotifyResult.ReqInfo reqInfo = result.getReqInfo();// 获取结果中的加密信息/*** SUCCESS-退款成功* CHANGE-退款异常* REFUNDCLOSE—退款关闭*/String refund_status = reqInfo.getRefundStatus();// 退款状态if (ConstantUtil.REFUND_STATUS_0.equals(refund_status)) {// 成功refund_status = ConstantUtil.ORDER_PAYSTATUS_3_ + "";}if (ConstantUtil.REFUND_STATUS_1.equals(refund_status)) {// 异常refund_status = ConstantUtil.ORDER_PAYSTATUS_4_ + "";}if (ConstantUtil.REFUND_STATUS_2.equals(refund_status)) {// 关闭refund_status = ConstantUtil.ORDER_PAYSTATUS_4_ + "";}String out_trade_no = reqInfo.getOutTradeNo();// 内部订单号Map<String, Object> paramMap = new HashMap<>();paramMap.put("refundNo", out_trade_no);// 内部退款单号paramMap.put("payStatus", refund_status);// 更新⽀付状态sealOrderImplService.updateOrderInfo(paramMap);orderRefundResultImplService.deleteByOrderdId(out_trade_no);// 删除订单orderRefundResultImplService.addRefundInfo(result);// 添加退款记录return WxPayNotifyResponse.success("OK");} catch (Exception e) {return WxPayNotifyResponse.fail("FAIL");}}//******************************************************************************************************************/*** 获取微信签名信息(预⽀付订单信息)** @param payVO* @param request* @return*/public synchronized String getWxPaySign(PayVO payVO, HttpServletRequest request) {try {if (null == payVO) {return null;}String orderId = payVO.getOrderId();String wxCode = payVO.getCode();if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(wxCode)) {return null;}// 获取openIdJSONObject openIdJson = getAccess_tokenByCode(wxCode);int errcode_openId = openIdJson.getInt("errcode");if (errcode_openId != 0) {// 调⽤获取openId接⼝不成功PayRespCodeMsg payRespCodeMsg = new PayRespCodeMsg(errcode_openId, openIdJson.getString("errmsg"));PayResultVO payResultVO = new PayResultVO(payRespCodeMsg, null);return JSON.toJSONString(payResultVO);}String openid = openIdJson.getString("openid");// ⽤户唯⼀标识String session_key = openIdJson.getString("session_key");// 会话秘钥// 获取本地订单相关信息Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);String siteName = (String) orderDetails.get("siteName");// 营业⽹点名称(刻章店名称)int orderPrice = ((BigDecimal) orderDetails.get("ORDER_AMOUNT")).intValue() * 100;String bodyName = siteName + "-" + ConstantUtil.ADVANCE_PAY_GOODS_NAME;// 商品名称严格按照规范-公众号⽀付-例如(商家名称-销售商品类⽬)String orderno = orderId;// "1234567890";Integer total_fee = orderPrice;// "8.88";// 订单总费⽤,不能有⼩数点,以分为单位String nonce_str = create_nonce_str();String timestamp = create_timestamp();// 获取预⽀付订单prepayIdSortedMap<Object, Object> parameters = new TreeMap<Object, Object>();String prepayIdResult = getPrepayId(request, bodyName, orderno, total_fee, openid);// 获取预⽀付订单id⽅法,返回的xml字符串结果Map<String, String> prepayIdResultMap = doXMLParse(prepayIdResult);// xml字符串转mapString prepayId_return_code = prepayIdResultMap.get("return_code");// SUCCESS/FAIL,此字段是通信标识,⾮交易标识,交易是否成功需要查看result_code来判断 if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(prepayId_return_code)) {// 获取prepayId接⼝通信异常PayRespCodeMsg preRespCodeMsg = new PayRespCodeMsg(-1, ConstantUtil.WECHAT_INTERFACE_EX_MSG);//PayResultVO preResultVO = new PayResultVO(preRespCodeMsg, null);return JSON.toJSONString(preResultVO);}// 获取prepayId的接⼝调⽤通信成功后String prepayId_result_code = prepayIdResultMap.get("result_code");// SUCCESS/FAIL,业务结果if (ConstantUtil.PAY_RETURN_CODE_NO.equals(prepayId_result_code)) {// 获取prepayId失败PayRespCodeMsg preNo = new PayRespCodeMsg(-1, "NO");PayResultVO preNoVO = new PayResultVO(preNo, null);return JSON.toJSONString(preNoVO);}// 微信预⽀付接⼝通信成功且业务结果成功// 重新⽣成签名parameters.put("appId", wechatPayConfigBean.getAppId());parameters.put("timeStamp", timestamp);parameters.put("nonceStr", nonce_str);parameters.put("package", "prepay_id=" + prepayIdResultMap.get("prepay_id"));parameters.put("signType", "MD5");String sign = createSign("UTF-8", parameters);parameters.put("prepay_id", "prepay_id=" + prepayIdResultMap.get("prepay_id"));parameters.put("paySign", sign);PayResultVO okResult = new PayResultVO(0, "OK", parameters);return JSON.toJSONString(okResult);} catch (Exception e) {PayResultVO resultVO = new PayResultVO(-1, "FALSE", null);return JSON.toJSONString(resultVO);}}public SortedMap<Object, Object> WapSignSignatureAction (HttpServletRequest request)throws Exception {SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();String code = request.getParameter("code");System.out.println("code-------------" + code);// code作为换取access_token的票据,每次⽤户授权带上的code将不⼀样,code只能使⽤⼀次,5分钟未被使⽤⾃动过期。
微信支付-H5网页支付开通流程
微信⽀付-H5⽹页⽀付开通流程
简介
H5 ⽀付是指商户在微信客户端外的移动端⽹页展⽰商品或服务,⽤户在前述页⾯确认使⽤微信⽀付时,商户发起本服务呼起微信客户端进⾏⽀付。
主要⽤于触屏版的⼿机浏览器请求微信⽀付的场景。
可以⽅便的从外部浏览器唤起微信⽀付。
微信商户开通后,想在⽹页端直接发起微信⽀付的话,需要在微信商户号中开通H5⽀付,以下是开通H5的流程。
登录【】,在【产品中⼼->产品⼤全->我的产品->H5⽀付】可以查看H5⽀付的开通状态。
点击申请开通页⾯会来到微信⽀付H5⽀付的申请开通界⾯。
⽀付域名:此处填写的域名需要提供⼀份域名授权书。
例如,以下是本⼈公司在腾讯云备案的域名,⽀付域名可以填写:,⼀定需要备案过的域名,然后需要备案域名公司填写域名授权书给需要开通微信⽀付H5⽀付的企业或者个⼈。
售卖产品/使⽤场景:此处需要填写⼀项需要开通微信⽀付H5⽀付企业或者个体户的营业范围。
产品对应⽹站域名:此处填写⽀付域名下的⽹页链接,⽹页的内容应该为售卖产品的商城内容。
例如,售卖产品我填写的是家具出售,则需要在⽹页链接中做⼀个对应的商城信息。
在最后的补充材料中则是提交⼀份域名证书和域名授权书。
如果对微信⽀付/H5⽀付申请有问题,可以加微信进⾏咨询,本⼈很长⾼兴为⼤家提供在微信⽀付⽅⾯的技术⽀持。
附上⼀张我们每天代理他⼈或企业申请通过的商户图⽚。
微信支付服务协议完整版本
微信支付效劳协议特别提示:本协议由深圳市腾讯计算机系统〔下称“腾讯〞〕、财付通支付科技〔下称“财付通〞〕和你共同签订,具有合同法律效力。
在使用微信支付效劳〔下称“本效劳〞〕前,你应当认真阅读并遵守本协议、?财付通效劳协议?和?微信公众平台效劳协议补充规那么〔一〕?〔下称“?补充规那么〔一〕?〞〕。
?财付通效劳协议?和?补充规那么〔一〕?是本协议不可分割的一局部,具有同等法律效力,与本协议相冲突的,以本协议为准。
请你务必审慎阅读并充分理解各条款内容,特别是免除或者限制责任的条款、争议解决和法律适用条款。
免除或者限制责任的条款可能以加粗字体显示,你应重点阅读。
除非你已阅读并接受本协议所有条款,否那么你无权使用本效劳。
你使用本效劳即视为你已阅读并同意本协议的约束。
如你对本协议有任何疑问的,应向客服咨询。
一、定义如无特别说明,以下术语在本协议中的定义为:1.1 微信:指腾讯提供的跨平台通讯工具,支持单人、多人参与,发送语音、短信、视频、图片和文字等即时通讯效劳,由关系链拓展工具、便捷工具、微信公众帐号、开放平台等软件系统和效劳组成。
1.2 微信公众平台:指腾讯向你提供的用来发布信息,让你与用户进行沟通、互动的互联网技术效劳平台〔〕。
1.3 微信公众帐号:指你在微信公众平台注册的,用于登录微信公众平台的帐号。
〔以下或称“公众帐号〞〕。
1.4 微信支付效劳:指财付通依托微信及微信公众平台为收付款人之间提供的货币资金转移效劳。
〔下称“本效劳〞〕1.5 用户:指使用微信支付效劳向你购置商品或效劳的自然人。
1.6 微信支付商户号:指财付通为你配置的用来记载你的身份信息、交易信息、资金余额,你凭以发起交易指令的电子簿记,属于?财付通效劳协议?中的一种财付通账户类型。
微信支付商户号将与你提供的合法银行账户绑定,财付通将根据你的交易指令和相关协议对你的银行账户做相应的资金扣划和归集。
1.7 微信支付商户平台〔下称“商户平台〞〕:指财付通提供和维护的商户管理软件系统〔〕,你应通过该系统提交相应资料和信息,进而开通本效劳。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HTTPS双向认证使用说明
现在邮件发出的文件有四个,分别是apiclient_cert.p12、apiclient_cert.pem、
apiclient_key.pem、rootca.pem。
apiclient_cert.p12
包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身
份,请妥善保管不要泄漏和被他人复制
部分安全性要求较高的API需要使用该证书来确认您的调用身份
windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的
商户ID(如:10010000)
apiclient_cert.pem
从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复
制
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已
为您直接提供;您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in
apiclient_cert.p12 -out apiclient_cert.pem
apiclient_key.pem
从apiclient_cert.p12中导出密钥部分的文件,为pem格式,请妥善保管不要泄漏和被他人复
制
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已
为您直接提供;您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in
apiclient_cert.p12 -out apiclient_key.pem
rootca.pem
微信支付api服务器上也部署了证明微信支付身份的服务器证书,您在使用api进行调用时
也需要验证所调用服务器及域名的真实性,该文件为签署微信支付证书的权威机构的根证
书,可以用来验证微信支付服务器证书的真实性
某些环境和工具已经内置了若干权威机构的根证书,无需引用该证书也可以正常进行验证,
这里提供给您在未内置所必须根证书的环境中载入使用
https双向认证上述文件使用说明:
问:什么是双向认证?
答:双向认真顾名思义,就是指服务器与客户端进行通信的时候,两者相互进行签名校验,
以确保双方身份,映射到上述四个文件,既服务器验证客户端的时候通过客户端证书和签名
(既:apiclient_cert.p12 或者 apiclient_cert.pem和apiclient_key.pem),客户端验证服务器通
过ca的根证书进行(rootca.pem),根证书有些操作系统上或者开发环境中已经包含,此时
不需要导入,但如果找不到跟证书时则需要使用rootca.pem。
1、如果基于curl调用https访问接口,(如:c++、php等语言使用libcurl访问)
需要使用到上述的piclient_cert.pem、apiclient_key.pem文件,当找不到ca根证书的时候还
需要rootca.pem文件。
使用如下:(php,c++类似)
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false)
curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/apiclient_cert.pem);
curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/apiclient_key.pem');
curl_setopt($ch,CURLOPT_CAINFO,'rootca.pem');
2、JAVA使用证书文件
JAVA只需要使用apiclient_cert.p12即可,如果使用JAVA语言进行开发的可以忽略其余三个
pem格式的文件。
使用如下:
//指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//读取本机存放的PKCS12证书文件
FileInputStream instream = new FileInputStream(new File("D:/apiclient_cert.p12"));
try {
//指定PKCS12的密码(商户ID)
keyStore.load(instream, "10010000".toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, "10010000".toCharArray()).build();
//指定TLS版本
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,new String[] { "TLSv1" },null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
//设置httpclient的SSLSocketFactory
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
3、C#使用证书
C#使用证书默认使用操作系统以导入的证书,即在操作系统上按装apiclient_cert.p12即可。
C#也可以忽略其他三个pem文件。
使用如下:
string cert = @"R:\apiclient_cert.p12";
string password = "10010000";
ServicePointManager.ServerCertificateValidationCallback=new
RemoteCertificateValidationCallback(CheckValidationResult);
X509Certificate cer = new X509Certificate(cert, password);
HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
webrequest.ClientCertificates.Add(cer);
webrequest.Method = "post";
HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
Stream stream = webreponse.GetResponseStream();
/*CheckValidationResult的定义*/
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain
chain, SslPolicyErrors errors)
{
if (errors == SslPolicyErrors.None)
return true;
return false;
}
注意:
C#有一点需要注意,除了在代码中使用apiclient_cert.p12之外还需要将该证书导
入操作系统才能使用,1、代码中使用、;2、导入操作系统,二者缺一不可。.NET版本需要
大于2.0