100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > java实现微信支付 提现

java实现微信支付 提现

时间:2018-06-21 07:22:02

相关推荐

java实现微信支付 提现

从准备工作讲起。

首先,想要做微信支付,需要的必备参数,appId,mchId,key,回调路径等等。然后还需要一个证书,要在电脑上配置。

这些几乎都是必备的参数,然后还有一些依赖于微信的sdk。

首先来看一看微信官网:

微信支付开放平台

大概讲一讲,微信支付有几种,其中包括:

扫码支付:就是用户提供二维码,商家扫码支付。(这种适合收银台模式,然后我还没有用过)JSAPI支付:这个就比较魔性了,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程。其实说起来真的很绕,反正就是类似于js的一种(这个是需要openId的)。Native支付:目前我觉得最简单的一种支付,就是生成一个二维码,用户扫码付款(钱数在生成二维码时生成,只适合在web端使用)APP支付:这个不用多说了吧?就是APP用来拉取微信授权跳转微信支付页面的。H5支付:这个主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付。和jsapi的区别就是是否在微信内部唤起吧。(我没实际用过,也不清楚)小程序支付: 没话讲,就这样。人脸支付: 高大上到让我从未接触过。

然后我这次业务使用的是Navite和APP支付两种方式。

SDK的使用

这个有两种方式,一种就是使用微信官网直接下载的SDK,然后以一个个文件的形式导到你的项目里。

还有一种是git上有一份用于这个的依赖(两种办法因为版本不同所以是有差异的。)

<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency>

然后懒惰如我,选择了直接用maven的jar包的导入(中间发生了一些故事,也把微信官方下载的SDK一个个引入了项目中,后来发现功能一样都跑起来了,所以又删除了)。

注意一点,以下的代码都是在引入上面的依赖的前提下实现的(中间涉及到版本的差异很大,所以千万不要弄混了,不然一点微小的区别能调N久)

开始真的实现啦!

1.**配置WXPayConfigImpl**public class WxPayConfigImpl implements WXPayConfig {public static String url = "你设置的回调接口";private static WxPayConfigImpl wxPayConfig;private byte[] certData = null;public static WxPayConfigImpl getInstance() {if (wxPayConfig == null) {synchronized (WxPayConfigImpl.class) {wxPayConfig = new WxPayConfigImpl();}}return wxPayConfig;}public WxPayConfigImpl() {try {//这个证书的位置不是瞎鸡儿填的,你要在这个路径真的有一个证书InputStream is = new FileInputStream("C:\\Windows\\System32\\cert\\apiclient_cert.p12");ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] bs = new byte[1024];int cnt = -1;while ((cnt = is.read(bs)) != -1) {baos.write(bs, 0, cnt);}is.close();certData = baos.toByteArray();} catch (Exception e) {e.printStackTrace();}}@Overridepublic String getAppID() {return "你自己的AppId";}@Overridepublic String getMchID() {return "你自己的设备码";}@Overridepublic String getKey() {return "你自己的key";}@Overridepublic InputStream getCertStream() {ByteArrayInputStream certBis;certBis = new ByteArrayInputStream(this.certData);return certBis;}@Overridepublic int getHttpConnectTimeoutMs() {// TODO Auto-generated method stubreturn 8000;}@Overridepublic int getHttpReadTimeoutMs() {// TODO Auto-generated method stubreturn 10000;}public String getPrimaryDomain() {return "api.mch.";}public String getNotifyUrl(){return url;}}

对,一个configImpl就这么简单的实现了。其中参数是证书路径,一个是appId,设备码,key,回调接口连接是必填项。

Native支付

刚我就说觉得这个是最简单的一种调用,反正我是一次成功的。下面是实现代码:

public R wxPay(String money, String mk, String title, HttpServletRequest request, HttpServletResponse response) {try {if (mk == null) {return R.error().put("msg", "缺少参数,请查证后再访问");} else {WXPayConfig config = WxWebPayConfigImpl.getInstance();SortedMap<String, String> paramMap = new TreeMap<String, String>();paramMap.put("body", title);paramMap.put("out_trade_no", "C" + System.currentTimeMillis());paramMap.put("fee_type", "CNY");paramMap.put("total_fee", "1");paramMap.put("notify_url", WxPayConfigImpl.url);paramMap.put("trade_type", "NATIVE");paramMap.put("sign_type", WXPayConstants.MD5);String ip = getIpAddr(request);paramMap.put("spbill_create_ip", ip);WXPay pay = new WXPay(config);// 1.统一下单Map<String, String> resultMap = pay.unifiedOrder(paramMap);String res = resultMap.get("return_code").toString().trim();System.out.println(">>>>res==" + res);System.out.println(resultMap);if ("SUCCESS".equalsIgnoreCase(res)) {return R.ok().put("data", resultMap);} else {return null;}}} catch (Exception e) {e.printStackTrace();return null;}}

上图是整理的一些我觉得的注意点,然后点击下单方法后会返回一个路径,这个路径可以打开一个二维码页面,因为我们是前后端分离,所以我走到这步确定res是SUCCESS就ok了。

对了,还要注意一点,这个钱数total_fee应该是前端传来的,不过我这为了demo效果,所以统一写了一分,正常应该写活。

一个完整的微信Navite支付就完成了。

APP支付

刚刚也说了,这个坑百分之七十都是前端的,因为需要什么什么什么配置之类的,我也不知道,反正就是总错,但是真正的java代码还是很简单的。

public R wxAppPay(String money, String mk, String title, HttpServletRequest request, HttpServletResponse response) {try {Double d = Double.parseDouble(money);Integer dd = (int) (d * 100);money = String.valueOf(dd);WXPayConfig config = WxPayConfigImpl.getInstance();SortedMap<String, String> paramMap = new TreeMap<String, String>();paramMap.put("body", title);paramMap.put("out_trade_no", "C" + System.currentTimeMillis());paramMap.put("fee_type", "CNY");paramMap.put("total_fee",dd);paramMap.put("notify_url", WxPayConfigImpl.url);paramMap.put("trade_type", "APP");paramMap.put("sign_type", WXPayConstants.MD5);String ip = getIpAddr(request);paramMap.put("spbill_create_ip", ip);WXPay pay = new WXPay(config);// 1.统一下单Map<String, String> resultMap = pay.unifiedOrder(paramMap);String res = resultMap.get("return_code").toString().trim();System.out.println(">>>>res==" + res);System.out.println(resultMap);if ("SUCCESS".equalsIgnoreCase(res)) {Map<String, String> paramMap1 = new HashMap<String, String>();paramMap1.put("appid", config.getAppID());// paramMap1.put("total", money);paramMap1.put("partnerid", config.getMchID());paramMap1.put("prepayid", (String) resultMap.get("prepay_id"));paramMap1.put("package", "Sign=WXPay");paramMap1.put("noncestr", WXPayUtil.generateNonceStr());// 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下paramMap1.put("timestamp", String.valueOf(System.currentTimeMillis()).toString().substring(0, 10));String sign2 = WXPayUtil.generateSignature(paramMap1, config.getKey(), SignType.MD5);paramMap1.put("sign", sign2);Gson gson = new GsonBuilder().disableHtmlEscaping().create();String xmlReq = gson.toJson(paramMap1);return R.ok().put("data", xmlReq);} else {return R.error();}} catch (Exception e) {e.printStackTrace();return R.error();}}

我个人觉得这个就比较良心了,起码金额是写活了。然后与上一个的区别就是交易类型app,不过这个前端要配置较多的东西(具体配置啥不太清楚,反正我们项目就这里因为前端少配置总卡住,卡了一天吧)。貌似配置文件,什么什么证书。什么什么包名要一致,还有不能本地测试,会报错-100,要打包测试(反正我们做完是这样的,如果有本地也能测的亲欢迎指点)

我这里郑重声明,app方式的微信支付,配置就这么多!再有任何报错百分之九十九都是前端的了。

这个恶心的一点就是报错不知道原因,很有可能莫名其妙就报个62000,如果两边信任度不高并且没有成功的例子,可能报错了就会两边找错误,前端改前端的,后台改后台的(对,就是我血淋淋的例子),结果改了一天多才发现最初的代码其实就一点问题没有。你能想到多崩溃么?所以希望以后或者别人对自己有点信心吧,反正我上面的代码是跑通了的。

JSAPI支付

这个还有个小问题,一开始我问领导咱们这个项目用的啥方式,跟我说是JSAPI,所以我傻傻的去找了这个方式的官方文档,不过因为后来我改了,所以并没有现成的demo,大概讲一下区别:

与APP方式比,也就是交易类型改一下,并且需要一个openId的参数。这个参数是微信授权获取的,用appid生成的,我反正是作为一个参数的形式从前台拿的,然后剩下别的就是一样的了。

反正两天的微信支付就这么痛苦的完成了,大多数错误犯得莫名其妙也解决的莫名其妙(因为我后端几乎一直都是返回success,都是前端在那 调啊调)

表白我前端,真的辛苦了,啥啥资料都没有,各种需要做的没有列出来,只能错一点改一点。。还有本地不能调试简直坑死了,反正我是真心心疼做微信支付这一块儿的前端,也有可能是因为我们app 是h5开发,没有用安卓或者微信?不太清楚。继续往下说吧。

微信提现

其实本质上微信的提现就是微信企业付款到个人用户

这个还蛮多要求的,大家可以自己看看官网;

微信提现介绍

然后如果以上要求都满足了的话,就可以测出效果了,因为我们项目中的提现涉及到很多,比如用户账户余额金额的对比,提现成功减去用户余额等代码,所以我这里就不完整的贴方法了。仅仅是把一些必要的步骤提出来:

WXPayConfig config = null;//这个也是与我做的业务相关的,因为我们这两个APP,也就是两个APPid啥的,如果你们没这么麻烦直接new WxPayConfigImpl()就ok 了。// 5是司机if (sysUserEntity.getUserType() == 5) {config = new WxDriverpayConfigImpl();// 不是司机就是企业} else {config = new WxPayConfigImpl();}SortedMap<String, String> paramMap = new TreeMap<String, String>();paramMap.put("mch_appid", config.getAppID());paramMap.put("mchid", config.getMchID());paramMap.put("nonce_str", WXPayUtil.generateNonceStr());paramMap.put("partner_trade_no", "C" + System.currentTimeMillis());paramMap.put("openid", openId);paramMap.put("check_name", "NO_CHECK");paramMap.put("amount", (money * 100) + "");paramMap.put("desc", "提现");paramMap.put("spbill_create_ip", getIpAddr(request));String sign = WXPayUtil.generateSignature(paramMap, config.getKey(), SignType.MD5);paramMap.put("sign", sign);WXPay pay = new WXPay(config);//Map<String,String> resMap = pay.transfer(paramMap);String url = " https://api.mch./mmpaymkttransfers/promotion/transfers";Map<String, String> resMap;resMap = pay.processResponseXml(pay.requestWithCert(url, paramMap, config.getHttpConnectTimeoutMs(),config.getHttpReadTimeoutMs()));String resultCode = resMap.get("result_code");if ("SUCCESS".equalsIgnoreCase(resultCode)) {//走到这里就是提现操作成功了,可以做你自己的业务逻辑了、} else {String err_code = resMap.get("err_code");if ("SYSTEMERROR".equalsIgnoreCase(err_code)) {return R.error().put("msg", err_code);} else if ("NOTENOUGH".equalsIgnoreCase(err_code)) {return R.error().put("msg", err_code);} else {//在这把两个常见的错提了出来,剩下的统一为未知错误了,如果做个更好一些可以直接传错误信息。return R.error().put("msg", "调用微信提现接口未知错误,请联系管理员!");}

至此,一个提现的功能也初步完成了。

原创:/p/4b9bc75f2343

希望能帮到你

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。