微信支付开发中遇到的问题以及注意事项和解决方案

来源:互联网 发布:百度大数据标注平台 编辑:程序博客网 时间:2024/05/21 17:22

自有封装公开了: https://git.oschina.net/zhuqiang/wx_sdk

统一下单支付:

不好分类的一些FQA

  1. 微信支付可以使用网页端打开微信支付的方式么? 答:不可以,某些网站可以是因为有合作,腾讯单独开发的接口。

统一下单支付:

  1. prepay_id 两小时过期
  2. 统一下单支付的订单可以用同一个订单号下单,相当于重新支付该订单,但是偶尔会出现 该笔订单没有付款,却又提示商户号订单号重复。
  3. 提示商户号订单号重复:原因是:之前使用这个商户号统一下单过,但是再次使用该商户号订单号下单的时候 里面的一些信息(已知的有:付款金额)和之前下单的不一致,就会提示这个
  4. 默认过期时间(2个小时 - 3小时(就以2小时为准))

二维码扫码支付

  1. 官方提供的是 刷卡的demo(但是也是以扫码的形式),别搞混淆了
  2. 二维码支付的原理流程是:
    1. 先调用统一下单api接口,下单后,
    2. 在回包数据中获取code_url,
    3. 然后使用第三方二维码生成包,把code_url为内容的生成二维码,微信端扫码(解析二维码的内容,发现是weixin(或则是自己的一个标识)通过这个标识处理相应的事件,比如这里是支付的url,就调用支付界面。),
    4. 支付成功后,微信服务器会回调统一下单里面提交的 回调地址。推送支付成功的结果。我们需要做得是,根据推送的数据,判断和处理是哪一笔订单支付的业务逻辑等,最后返回success。
  3. 二维码的过期时间也应该是随统一下单支付时间而过期。支付一般都是调用即生成二维码,所以,可以尝试 打开支付界面就生成一张二维码。(据测试,二维码过期时间是2小时-3小时之间)
  4. 根据官方的统一下单支付文档说明:只要是该订单未被关闭和支付,取消等操作。 都可以使用同一个订单号统一下单,相当于是重新支付。所以可以每次打开支付的时候,去统一下单然后生成二维码。

申请退款

  1. 直接访问退款地址是访问不了的,需要使用ssl证书apiclient_cert.p12 在商户api安全里面去下载
  2. 使用httpclient 携带 该证书信息去访问。才能访问到。
  3. httpclient携带证书访问官方demo有示例,而我自己使用的是谷歌的AsyncHttpClient
  4. AsyncHttpClient携带证书封装: 和 官方示例的差不多;下面贴出代码:
    private static AsyncHttpClient sslHttp; //证书    private static Log logger = new Log(LoggerFactory.getLogger(BaseService.class));    static{        try {            AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfigBean.Builder();            KeyStore keyStore = KeyStore.getInstance("PKCS12");            PublicAccount account = Configure.getAccount(""); //这里是获取 微信公众号相关的信息,自定义的            InputStream instream = BaseService.class.getResourceAsStream(account.getCertLocalPath()); //证书路径            try {                keyStore.load(instream, account.getCertPassword().toCharArray()); //证书密码,默认是商户id            } finally {                instream.close();            }            // Trust own CA and all self-signed certs            SSLContext sslcontext = SSLContexts.custom()                    .loadKeyMaterial(keyStore, account.getCertPassword().toCharArray())//证书密码,默认是商户id                    .build();            builder.setSSLContext(sslcontext);            AsyncHttpClientConfig config = builder.build();            sslHttp = new AsyncHttpClient(config);        } catch (Exception e) {            logger.e("构建证书失败");            throw new RuntimeException("****************************构建证书失败******************");        }    }
1 0