POS与支付

  • 首页
  • 支付资讯
  • 支付政策
  • POS专栏
POS And Pay
关注POS与支付
  1. 首页
  2. 支付资讯
  3. 正文

第三方支付(支付宝、微信)Java服务端实现

2022年9月7日 694点热度 0人点赞 0条评论

说句走心的话,这篇文章是给自己看的,以后再做第三方支付的时候可以少踩坑。

目标读者:Java 服务器后端开发者;需要实现第三方支付接口调用功能的开发者;需要 APP 支付功能实现者;

故事发生在几天前的一个午后,我们终于申请到了微信和支付宝的支付功能,或得了如下信息:

微信:

wxpay.appid=wx0c341ac12e3a8ce1 wxpay.mchid=1439182322 wxpay.key=192006250b4c09247ec02edce69f6a2d wxpay.notify_url=http://api.woliegequ.com/api/payment/wxpay/notify

支付宝:

alipay.appId=2018011503899539 alipay.publicKey=MIIBIjANBgkqhkiG92133EFAAOCAQ8AMIIBCgKCAQEAlDGp9uLXtdaxXeH0jAQ3KuWzAK9wtvURoHNRUz41m9IbVm+mqx0v/9YRvXTZtRAPwB46K4cnJj3vXm5ugPO8VyShw30cJHtZiL1H1pW297Rqm+n7owgkjL8V1ylIKR9GxTe3hhQ4oPOk8JWYdUEMHItd3RUUQ4bnTxAAjqo8R1LyKnhTNQ4BwCoe3tXWntnEXSK32323iINA4yyTXNuk5Qv515fpjjfNUyslnMKW/q329guF8TzBKRe/i/OvPDeYIe7wxdbSNqAFYxd4hNyIjoPnq12cVpeYT1215Bjtj+UBuwsQV//322IDAQAB alipay.privateKey=MIIE212BADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCUMan24te11rFd4fSMBDcq5bMAr3C29RGgc1FTPjWb0htWb6arHS//1hG9dNm1EA/AHjorhycmPe9ebm6A87xXJKHDfRwke1mIvUfWlbb3tGqb6fujCCSMvxXXKUgpH0bFN7eGFDig86TwlZh1QQwci13dFRRDhudPEACOqjxHUvIqeFM1DgHAKh7e1dae2cRdIqlgtCdDvJ435456TlC/nXl+mON81TKyWcwpb+q2eFZoWGoD2C4XxPMEpF7+L8688N5gh7vD3245hPjfOPy/H8rkGO2P5QG7CxBX/8Np0fAgMBAAECggEAE6E0e1B29E449k+c3gMc76C3gkq66nEx4YgE6LrfzQEav+tQL3BRUFkhxm+4+sPi4jbey68+X1Fq6J5GIuymMQDYMJXc6XQxWux/nIv+TXdne7mVrHXC43678D6Y0+CtJ+ML1Prb8iCKWvGYF95Oj7LZBpmm6fMR2PJhghIhROkrIFJngewerwfIeaJFRxW/rmzfg1V5N2F3+WRnStu7nD0KOz7S7PZjieymA/Blgrewgerg78ENVMXp2BmZuu3mPOyiiGMBz5pgwree9s9y9Y1/7aZ5SXIQgrewregyNeAP6KXohsPFyulqNN+bpxrVxSjFq2EXYq1tyhr/LVZ13ab4vzFTq4z4x87QfNlar34fw/Fo9acUL41ivSPwl6r4xoXgbQ462TIxCRCXhS7OJYtCx1CKcQKBgQCzXCWH0mc/sD1TQHNKDCvNfZGgSQnBferfrCK10klFx6W98uqKv3+j6DLzlL+iyyx4Fnpsd22PE0U0NNTI0l2lYIOdTCoKeZ3/7w7KJqP3sbHsZnr+vRzR+eOreKjZuaHIjwKBgQCfOQCRv7Qg alipay.notifyUrl=http://api.woliegequ.com/api/payment/alipay/notify

当然啦,这些信息是假的,怎么可能公开嘛。。我们切入正题!

先贴代码,思路好讲:

微信:

/**** @param oid 订单号* @param price 价格* @param body 理解为:备注* @param ipAddress* @param deviceInfo 默认为:"WEB"* @return* @throws ActionParameterException 参数异常* @throws IOException IO 异常(网络请求可能会抛出)*/publicStringcreateOrder(Stringoid,BigDecimalprice,Stringbody,StringipAddress,StringdeviceInfo)throwsActionParameterException,IOException{StringplaceUrl="https://api.mch.weixin.qq.com/pay/unifiedorder";SortedMap<String,Object>parameters=newTreeMap<String,Object>();parameters.put("appid",appid);parameters.put("mch_id",mch_id);parameters.put("device_info","WEB");parameters.put("body",body);parameters.put("nonce_str",wxUtils.gen32RandomString());// 32 位随机字符串,26 个字母的大小写组成parameters.put("notify_url",notifyUrl);parameters.put("out_trade_no",oid);// parameters.put("total_fee", price.multiply(BigDecimal.valueOf(100)).intValue());parameters.put("total_fee",1);// 测试环境,设定为 1 分钱parameters.put("spbill_create_ip",ipAddress);parameters.put("trade_type","APP");parameters.put("sign",wxUtils.createSign(parameters));// 必须在最后returnwxUtils.executePost(placeUrl,parameters);// 网络请求}

支付宝:

/*** 返回支付宝订单ID** @param oid 订单号* @param price* @param body 备注信息* @param subject 备注信息* @return* @throws ActionParameterException 参数异常*/publicStringcreateOrder(Stringoid,BigDecimalprice,Stringsubject,Stringbody)throwsActionParameterException{//实例化客户端AlipayClientalipayClient=newDefaultAlipayClient("https://openapi.alipay.com/gateway.do",APP_ID,APP_PRIVATE_KEY,"json","utf-8",ALIPAY_PUBLIC_KEY,"RSA2");//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.payAlipayTradeAppPayRequestrequest=newAlipayTradeAppPayRequest();//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。AlipayTradeAppPayModelmodel=newAlipayTradeAppPayModel();model.setBody(body);model.setSubject(subject);model.setOutTradeNo(oid);model.setTimeoutExpress(TIMEOUT_EXPRESS);// model.setTotalAmount("" + price.doubleValue());model.setTotalAmount("0.01");// 测试环境,设定为 1 分钱model.setProductCode("QUICK_MSECURITY_PAY");request.setBizModel(model);request.setNotifyUrl(NOTIFY_URL);try{//这里和普通的接口调用不同,使用的是sdkExecuteAlipayTradeAppPayResponseresponse=alipayClient.sdkExecute(request);System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。returnresponse.getBody();}catch(AlipayApiExceptione){e.printStackTrace();}returnnull;}

对比可发现一个小细节,微信的价格单位是「分」,支付宝是「元」;微信是自己写的 HTTP 客户端进行请求,支付宝是用的 SDK 进行的请求,虽然本质上没差。

其中支付宝用到的第三方 sdk 是这个人的,贴一下 maven:

com.github.1991wangliang alipay-sdk 1.0.0

安全性暂且不考虑了,不相信会有什么恶意代码在里面。实在不行也建议自己重新实现一下也是不错的。阿里也在文档里面给了 .jar 的 sdk 可以使用,但一直没有找到对应的 maven 源算是个小遗憾的消息。

翻篇,我们讲一下官方文档的流程。

适用场景为普通的手机 APP 消费,使用微信支付操作。可参考:

【微信支付】APP支付开发者文档​pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1

先贴微信给出的 API 列表:

微信开放平台官方文档 API 列表

根据这个列表我们可以隐约知道流程大概是这样子的:

Server 端下单 --> APP 调用支付操作(会跳转到微信 APP 进行支付流程然后支付完成后跳转回自己的 APP)--> APP 查询支付结果

之后的查询订单和关闭订单都是后话了,就不展开讨论。上述第一步可以细细拆开一下变成:

APP 调用下单接口(可能包含很多业务,比如:购买衣服的种类等) --> Server 得到下单消息,访问微信平台进行下单(只包含支付业务)--> 微信平台返回成功信息 --> Server 将该信息直接返回给客户端 APP 即可

这是微信官方的流程图,参考一下:

微信开放平台「微信支付」流程图

所以,Server 服务器端需要有三个接口:

APP 下单接口(可能不止一个,但支付的 Service 走的一条线)微信平台将数据发回 Server 的接口(一般称为回调接口)APP 查询订单接口(查看订单状态、交易额等)

APP 下单接口就不展开了,其中业务服务层的代码在文章开篇已经示例出,这里就贴上接口回调的 Controller 作为补充:

@RequestMapping(value="/wxpay/callback",method={RequestMethod.POST,RequestMethod.GET})publicStringwx(WxPayTradeModelwxPayTradeModel){returnwxPayService.callBack(wxPayTradeModel);}

其中 Service 对应方法如下:

publicStringcallBack(WxPayTradeModelmodel){Stringsign=model.getSign();booleansignSucess=false;// 验证签名if(signSucess){if(model.getReturn_code().equals("SUCCESS")){if(model.getResult_code().equals("SUCCESS")){wxPayTradeService.save(model);orderService.finishOrder(model.getOut_trade_no());}else{wxPayTradeService.save(model);orderService.failOrder(model.getOut_trade_no());}}return"\n"+" \n"+" \n"+"";}return"\n"+" \n"+" \n"+"";}

这里只是简单地持久化了传回地数据,并未做过多处理,正常情况应该要根据传回的 model 信息选择性地更新自己的业务订单(不只是支付订单)信息。

便于浏览,我们再切一条分割线出来,此处记叙一下支付宝的操作流程。

支付宝开放平台文档中心「APP支付」接口列表

相较于「微信支付」,支付宝多了网页支付的能力,所以这里有一条「手机网站支付转APP支付」的栏目。其中 Android 和 iOS 集成同微信文档里的「调起支付接口」一致;「请求参数说明」同微信的「统一下单」一致;「通知参数说明」同微信的「支付结果通知」一致。

这是支付宝的适用场景:

开放平台文档中心​docs.open.alipay.com/204

自然的,原理和「微信支付」是一致的,所以此处就不啰嗦太多,先贴出接口回调的代码:

@RequestMapping(value="/alipay/callback",method={RequestMethod.POST,RequestMethod.GET})publicStringali(AliPayTradeModelaliPayTradeModel){try{returnaliPayService.callBack(aliPayTradeModel);}catch(AlipayApiExceptione){return"failure";}}

具体的 Service 类里的方法:

publicStringcallBack(AliPayTradeModelaliPayTradeModel)throwsAlipayApiException{//将异步通知中收到的所有参数都存放到map中JSONObjectjson=JSONObject.fromObject(aliPayTradeModel);booleansignVerified=AlipaySignature.rsaCheckV1(json,ALIPAY_PUBLIC_KEY,"UTF-8","RSA2");//调用SDK验证签名if(signVerified){//验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failureStringout_trade_no=aliPayTradeModel.getOut_trade_no();// 查询该订单是否已经完成交易,若否,则继续TradeModel.TRADE_STATUStrade_status=aliPayTradeModel.getTrade_status();// logger.info(out_trade_no1 + ":" + trade_status1);// 修改订单状态,判断是否完成交易switch(trade_status){caseWAIT_BUYER_PAY:// 交易创建,等待买家付款(该通知不可能拿到,支付宝默认不开启该通知)aliPayTradeService.save(aliPayTradeModel);// 更新支付状态break;caseTRADE_CLOSED:// 未付款交易超时关闭,或支付完成后全额退款aliPayTradeService.save(aliPayTradeModel);orderService.failOrder(out_trade_no);// 关闭订单,订单失败break;caseTRADE_SUCCESS:// 交易支付成功caseTRADE_FINISHED:// 交易结束,不可退款// 成功!aliPayTradeService.save(aliPayTradeModel);orderService.finishOrder(out_trade_no);// 关闭订单,订单成功break;}return"success";}else{//验签失败则记录异常日志,并在response中返回failure.return"failure";}}

此处的业务代码相对于微信那块较详细一些,可以参考一下。我们仍然贴出支付宝的流程图作为补充:

支付宝开放平台文档中心快速接入「支付流程」配图支付宝开放平台文档中心快速接入「支付流程」配图

支付宝和微信的流程可以对比着来看,其实都是一样的。最后附上一篇申请支付功能的流程介绍。

微信支付功能申请:

参考文档

【微信支付】普通商户接入文档​pay.weixin.qq.com/wiki/doc/api/index.html

第一步是需要申请一个微信商户平台的账号,账号里面会提供「商户ID」和「密钥 Key」值进行支付功能的实现。一般来说是先申请公众号/企业号/微信开发平台账号然后再进行绑定商户平台账号来操作支付功能的。开放平台链接如下:

微信开放平台​open.weixin.qq.com/

开发 APP 必然会有 APP ID,在开放平台申请移动应用创建就可以拿到「APP ID」了。配合商户平台的「商户 ID」和「密钥 Key」就可以参照此文进行微信支付功能的服务器端实现了。

再来看支付宝的申请流程:

这是官方指导页面

开放平台文档中心​docs.open.alipay.com/204/105297/

第一步:创建应用并获取APPID

第二步:配置应用

第三步:集成和开发

第四步:调用接口

第五步:调试应用

第六步:上线应用

上述六步直接来自于「支付宝开放平台文档中心」,其中第二步配置应用需要自己手动添加公钥信息,自己找个网站或者开源的包生成一下就好了,私钥自己存在服务器本地,公钥交给支付宝进行签名加密。

以上,踩坑的人若见此文便可少挖一坟,少废一时心机,少掉一根头发。

emmmmm,就这样吧。

标签: 暂无
最后更新:2022年9月7日

bianji

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >
最新 热点 随机
最新 热点 随机
如何完成个人支付接口申请? 2022年个人申请H5支付接口教程 我们怎么申请第三方支付的接口(支付通道)?三方支付的对接流程具体如何? 好消息!网上购药将可用社保卡买单了,看看咋回事? POS机将迎强监管!支付收单这些乱象将重点整治 警方发现神秘支付平台,背后竟是上百个涉嫌套路贷的App!超21万人受骗…
网联发文督促第三方支付接入:与银行直连将被切断 嘉友国际物流股份有限公司关于回购股份事项前十大股东和前十大无限售条件股东持股情况的公告 【第三方支付】叫价三亿起支付牌照缘何如此值钱? Java对接第三方支付渠道之微信支付APIV3版本 2021年中国移动支付十强榜公布平安壹钱包位列TOP3 顺丰旗下第三方支付平台顺丰恒通被打包上市
最近评论
标签聚合

COPYRIGHT © 2022 POS与支付. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang