背景:

​ 由于公司业务需要想把支付宝和微信整合在一起,做一个统一的支付模块。其中经过了各种坑,因为之前也没搞过这个。所以这里记录下,同时,也让后面做相同业务的小伙伴们少走一些弯路。

支付宝

​ 接口:alipay.trade.precreate(统一收单线下交易预创建

​ 接口描述: 收银员通过收银台或商户后台调用支付宝接口,生成二维码后,展示给用户,由用户扫描二维码完成订单支付。 这里我要讲下,我们使用这个功能的前提是你的商户账号已经开通“当面付”功能;

这里我们不在贴出参数和响应参数的信息,这些信息在 alipay.trade.precreate(统一收单线下交易预创建 中都有很详细的介绍。我传递相应的参数就可得到一个二维码链接,前端或者后端都可以根据这个链接进行生成二维码;

这里有几个小细节需要注意:

  1. total_amount (订单总金额)为0,是不会返回二维码链接的;其实文档上也有写到,订单金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] ;

  2. notify_url(回调地址),这里的回调地址必须是外网可以直接访问的,本地想测试的话也可以内外网穿透下;这里推荐一个好用的工具utools,下载一个内外网穿透工具就行了;

  3. timeout_express 和 qr_code_timeout_express的区别:官网的详细介绍, 点击查看,这里要说下沙箱和真实商户账号的区别,沙箱中我们扫过码会在支付宝app上有一笔未支付订单信息,过期后还是可以继续支付,但是真实的商户账号,扫码后也会在app有一笔订单,但是在支付时间过期后,就不能再继续支付了;

  4. 沙箱环境回调通知和真实商户账号的回调通知的区别:

    1. 回调通知的次数不同: 沙箱只回调一次(偶尔还不回调,这里也是一个坑);真实的是会多次尝试的,所以可以很放心的使用;
    2. 回调通知的触发条件不同: 沙箱在用户扫码和支付完成都会触发回调通知,通知的状态码分别为:WAIT_BUYER_PAY(交易创建)、TRADE_SUCCESS(交易成功)
  5. 沙箱环境返回的qr_code和真实商户返回的qr_code的区别: 沙箱返回的qr_code是不带反斜杠的’\‘,但是真实的商户账号环境返回的qr_code是带反斜杠的,所以如果有小伙伴是在沙箱写完后再对接真实商户账号的话,就非常容易忽略这一点,如果没有处理掉这个反斜杠,生成的二维,用支付宝app扫码就是会是一片空白;这个时候就是一脸懵逼;

微信支付:

​ 背景:

​ 这里要说下,微信支付时分为v3和v2两个版本的,这里选用的v3版本,但是网上关于v3版本的demo很少,v3和v2版本的差别很大,所以路途很艰难;

​ 接口: 普通支付(直连模式)/ Native下单API)

​ 接口描述:除付款码支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按Native、JSAPI、APP等不同场景生成交易串调起支付。

​ 在 普通支付(直连模式)/ Native下单API)也有很详细的字段介绍,下面我要将的就是几个注意的点:

  1. 微信支付设置GET/POST 请求头和请求体要设置相应的格式:

    /*** 请求支付端(GET)** @param url 请求地址* @return 请求结果*/public static String sendGet(String url) {HttpGet request = new HttpGet(url);// 这个header是必须设置request.addHeader("Accept", "application/json");request.addHeader("Content-Type", "application/json");return builder(request);}/*** 请求支付端(POST)** @param url  请求地址* @param json 参数* @return 请求结果*/public static String sendPost(String url, JSONObject json) {String res = null;try {HttpPost request = new HttpPost(url);// 这个header和entity是必须设置 request.addHeader("Accept", "application/json");request.addHeader("Content-Type", "application/json");request.setEntity(new StringEntity(json.toString(), ContentType.create("application/json", "utf-8")));res = builder(request);} catch (UnsupportedCharsetException e) {LOG.error("调用WXPay接口失败:", e);}return res;}/*** 构建微信支付请求** @param request HttpURL* @return HttpResponse*/private static String builder(HttpUriRequest request) {CloseableHttpClient client = null;String res = null;try {// 获取支付客户端client = WechatPayHttpClientBuilder.create().withMerchant(MERCHANT_ID, serialNo, privatekey).withValidator(response -> true).build();// 处理请求结果HttpResponse response = client.execute(request);if (response.getEntity() != null) {res = EntityUtils.toString(response.getEntity());EntityUtils.consume(response.getEntity());}} catch (Exception e) {LOG.error("调用WXPay接口失败:", e);} finally {if (client != null) {try {client.close();} catch (IOException e) {LOG.error("调用WXPay接口失败:", e);}}}return res;}
    

    这里必须要在request中设置相应的header和entity请求格式;如果没有设置,请求过去微信也会返回给你一个二维码链接,但是这个链接生成二维码后,使用微信app扫码就会出现不停的跳转;这也是很坑的地方;

    1. 注意传给微信的对象的类型;例如:总金额(total)是int类型,本人就是传了一个BigDecimal也是可以拿到二维链接,但是同样出现了使用微信app扫码不停的跳转,最终弹出系统繁忙的信息;

    微信回调通知

    1. notify_url参数设置,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action”

      这个notify_url 一个商户账号只能设置一个回调地址;

    2. 设置完回调地址就可以正常接收到微信的回调,我们可以在request中读取到响应的信息;

    private String getWxParams(HttpServletRequest request) {InputStream inStream = null;ByteArrayOutputStream outStream = null;String result = null;try {inStream = request.getInputStream();outStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outStream.write(buffer, 0, len);}result = new String(outStream.toByteArray(), "utf-8");} catch (IOException e) {e.printStackTrace();} finally {try {if (null != inStream) {inStream.close();}if (null != outStream) {outStream.close();}} catch (IOException e) {e.printStackTrace();}}return result;}
    

    这里拿到是加密的json对象,具体的信息在resource中;例如:

    {"id":"EV-2018022511223320873","create_time":"2015-05-20T13:29:35+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","resource" : {                       "algorithm":"AEAD_AES_256_GCM","ciphertext": "...","nonce": "...","associated_data": ""},"summary":"支付成功"
    }
    

    下面我们就要在商户平台上设置的APIv3密钥【微信商户平台—>账户设置—>API安全—>设置APIv3密钥】,拿到一个key;然后通过微信提供的工具类(AesUtil)进行解密,大家可以具体看下,这里提供一个解密demo

    //  PayConstants.API_V3 就是上面我们设置APIv3拿到的key
    AesUtil aesUtil = new AesUtil(PayConstants.API_V3.getBytes(StandardCharsets.UTF_8));
    // 解密回调信息  associatedData,nonce,ciphertext 分别是上面resource中的对应值
    String decryptToString = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
    

    通过上面的解密后就可以拿到真实的回调支付信息了,例如:

    {"transaction_id": "1217752501201407033233368018","amount": {"payer_total": 100,"total": 100,"currency": "CNY","payer_currency": "CNY"},"mchid": "1230000109","trade_state": "SUCCESS","bank_type": "CMC","promotion_detail": [{"amount": 100,"wechatpay_contribute": 0,"coupon_id": "109519","scope": "GLOBALSINGLE","merchant_contribute": 0,"name": "单品惠-6","other_contribute": 0,"currency": "CNY","type": "CASHNOCASH","stock_id": "931386","goods_detail": [{"goods_remark": "商品备注信息","quantity": 1,"discount_amount": 1,"goods_id": "M1006","unit_price": 100}, {"goods_remark": "商品备注信息","quantity": 1,"discount_amount": 1,"goods_id": "M1006","unit_price": 100}]}, {"amount": 100,"wechatpay_contribute": 0,"coupon_id": "109519","scope": "GLOBALSINGLE","merchant_contribute": 0,"name": "单品惠-6","other_contribute": 0,"currency": "CNY","type": "CASHNOCASH","stock_id": "931386","goods_detail": [{"goods_remark": "商品备注信息","quantity": 1,"discount_amount": 1,"goods_id": "M1006","unit_price": 100}, {"goods_remark": "商品备注信息","quantity": 1,"discount_amount": 1,"goods_id": "M1006","unit_price": 100}]}],"success_time": "2018-06-08T10:34:56+08:00","payer": {"openid": "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"},"out_trade_no": "1217752501201407033233368018","appid": "wxd678efh567hg6787","trade_state_desc": "支付失败,请重新下单支付","trade_type": "MICROPAY","attach": "自定义数据","scene_info": {"device_id": "013467007045764"}
    }
    
    1. 由于微信通知规则,即用户在接收并处理完回调信息后,要相应的返回一个应答信息;不然微信会认为商户接收通知失败,微信会在一定时间内策略定期重发通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m);通知应答就是返回一个json字符串,例如:

       /***  微信-回调请求-成功*/public static final String RETURN_WECHAT = "{   \n" +"    \"code\": \"SUCCESS\",\n" +"    \"message\": \"交易成功\",\n" +"}";/*** <p>响应微信回调通知</p >** @param response*/public void responseNotification(HttpServletResponse response) {response.setCharacterEncoding("UTF-8");response.setContentType("application/xml; charset=utf-8");PrintWriter out = null;try {out = response.getWriter();out.print(PayConstants.RETURN_WECHAT);out.close();logger.info("响应微信回调通知成功, 无需重复回调");} catch (IOException e) {logger.info("响应微信回调通知报错");e.printStackTrace();}}
      

微信v3版本-native支付和支付宝支付接口对接相关推荐

  1. 一文带你学会微信V3版本下单支付、退款、关单流程代码实操

    目录 开篇介绍 一.微信支付-Maven依赖加入和代码参数准备 二.商户私钥证书代码读取 三.微信订单支付系列接口URL配置 四.快速验证统一下单接口 五.查询订单支付状态验证 六.关闭订单状态验证 ...

  2. springboot版本的微信支付和支付宝支付

    最近公司需要做一个在微信公众号中实现支付宝支付的项目 网上找了很多资料和问了好久的支付宝客服 终于整理出一份跑的通的项目 注意:微信支付和支付宝支付需要公司资质 微信公众号中使用微信支付是JSAPI进 ...

  3. 个人开发者只要一行代码接入微信支付和支付宝支付

    接入支付功能   对于个人开发者来说,我们很希望我们开发的App被广泛使用,同时可以获得一些额外收入,那就更好了.但是在微信开放平台或者支付宝开放平台申请支付功能,需要是企业才可以接入,对于我们个人开 ...

  4. 微信支付和支付宝支付整合(含设计模式1)

    微信支付和支付宝支付整合(含设计模式1) 1.说明: 设计模式:单例+策略模式+抽象 在开发中经常对接微信支付和支付宝支付,相对来说,阿里的文档比微信的接口文档清晰一点,这里用的第三方库(com.gi ...

  5. java实现微信支付与支付宝支付接口

    因为公司要求需要写支付宝支付与微信支付现在写完了,总结一下: 支付宝支付: 支付宝支付比较简单首先我说一下支付宝支付与微信支付大概的流程,就拿支付宝支付来说(微信同理) 首先去蚂蚁金服注册一下App ...

  6. “一码多付”,微信支付、支付宝支付

    写着写着,越写越多,思绪写不下了,回头写在前面的话.此系统属个人创业项目,历时3个月,主要实现自助按摩椅.娃娃机.自动换币器功能,主要流程就是用户扫码二维码->授权获取用户信息->弹出H5 ...

  7. 个人开发者微信支付和支付宝支付

    个人开发者是不能申请微信支付和支付宝支付的 很多第三方使用添加二维码监听转账操作来实现是否功能

  8. 微信支付及支付宝支付开发指南

    从开始学习android开始到现在还没搞过三方支付,感觉挺遗憾的.看到最近有几篇关于微信支付和支付宝支付的文章,稍微进行一下整合,供大家参考. ---------------------------- ...

  9. 关于微信支付,支付宝支付

    关于微信支付,支付宝支付 微信支付和支付宝支付属于第三方支付. 第三方支付是指具备一定实力和信誉保障的独立机构,通过与网联对接而促成交易双方进行交易的网络支付模式. 在第三方支付模式,买方选购商品后, ...

  10. vue支付宝html,vue 解决在微信内置浏览器中调用支付宝支付的情况

    我的思路大概是这样的 1. 验证是否是在微信内置浏览器中调用支付宝 2.给支付页面的url加上调用接口所需的参数(因为在微信里是不能直接调用支付宝的需要调用外部浏览器) 3.在外部浏览器中完成支付跳转 ...

最新文章

  1. 【python】使用python脚本将LFW数据中1672组同一个人多张照片拷贝出来
  2. 李永乐线性代数手写笔记-二次型
  3. 如何帮助谷歌鉴别内容重复的网页
  4. java真的是值传递么?
  5. 利用python爬虫(part4)--requests模块之requests.get方法
  6. 三星Galaxy Note 10渲染图曝光:前置打孔双摄+后置横排四摄
  7. 学习之法 —— 概念、名词、术语与定义的学习
  8. Linux堆内存管理深入分析 (上半部)【转】
  9. keepalived双机热备原理及实例部署LVS+keepalived
  10. scrapy 在迭代爬取时被拒 offsite 增加dont_filter=True
  11. 获取邮箱的DNS和MX 工具类
  12. echarts迁徙图 vue_vue中使用 echarts3.0 或 echarts2.0 (模拟迁徙图,折线图)
  13. Sourcemap是什么?Sourcemap的作用及用法概括
  14. Octet string 解析
  15. RabbitMQ None of the specified endpoints were reachable 错误 解决方案
  16. 《痞子衡嵌入式半月刊》 第 31 期
  17. docsify配置flowchart模块
  18. centos7查看磁盘io
  19. FL Studio最新20.9中文豪华顶配购买指南
  20. 计算机又坏了,第二次回家

热门文章

  1. [技术讨论]关于前几天发布的京东bug上的问题分析
  2. java爬虫爬取京东_java爬虫练习|爬取京东上的手机商品数据
  3. 用python在大麦网抢票_大麦网自动抢票工具
  4. OAuth 2.0授权框架详解
  5. 使用驱动器中的光盘之前需要将其格式化怎么弄
  6. 申报深圳市专精特新中小企业需要哪些条件,及有什么好处
  7. vim 设置配色方案
  8. 文件处理技巧,如何快速复制并覆盖已存在的文件
  9. 吉他入门教程之吉他音阶训练——运用方法
  10. 桂林理工大学 大学语文题库2021年春季学期