• 微信小程序支付开发之申请退款


    微信小程序支付跟微信公众号支付类似,这里不另做记录,如果没有开发过支付,可以查看我关于微信支付的文章

    重点记录微信小程序申请退款开发过程中遇到一些坑。

    退款接口比支付接口接口多了一个 双向证书

    证书介绍:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

    由于这里是Java开发,所有下载apiclient_cert.p12文件,下面是官方给的demo

    /*
     * ====================================================================
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     * ====================================================================
     *
     * This software consists of voluntary contributions made by many
     * individuals on behalf of the Apache Software Foundation.  For more
     * information on the Apache Software Foundation, please see
     * <http://www.apache.org/>.
     *
     */
    package httpstest;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.security.KeyStore;
    
    import javax.net.ssl.SSLContext;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.conn.ssl.SSLContexts;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    /**
     * This example demonstrates how to create secure connections with a custom SSL
     * context.
     */
    public class ClientCustomSSL {
    
        public final static void main(String[] args) throws Exception {
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File("D:/10016225.p12"));
            try {
                keyStore.load(instream, "10016225".toCharArray());
            } finally {
                instream.close();
            }
    
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, "10016225".toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            try {
    
                HttpGet httpget = new HttpGet("https://api.mch.weixin.qq.com/secapi/pay/refund");
    
                System.out.println("executing request" + httpget.getRequestLine());
    
                CloseableHttpResponse response = httpclient.execute(httpget);
                try {
                    HttpEntity entity = response.getEntity();
    
                    System.out.println("----------------------------------------");
                    System.out.println(response.getStatusLine());
                    if (entity != null) {
                        System.out.println("Response content length: " + entity.getContentLength());
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
                        String text;
                        while ((text = bufferedReader.readLine()) != null) {
                            System.out.println(text);
                        }
                       
                    }
                    EntityUtils.consume(entity);
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }
        }
    
    }

    在上面代码进行微调

    private static void ClientCustomSSL(String xmlStr) throws  Exception{
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File("D:/apiclient_cert.p12"));
            try {
                keyStore.load(instream, WxPayConfig.MCH_ID.toCharArray());
            } finally {
                instream.close();
            }
    
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, WxPayConfig.MCH_ID.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            try {
    
                HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
                StringEntity entityStr = new StringEntity(xmlStr);
                entityStr.setContentType("text/xml");
                System.out.println("entityStr--------------"+entityStr);
                httpPost.setEntity(entityStr);
    
                CloseableHttpResponse response = httpclient.execute(httpPost);
                try {
                    HttpEntity entity = response.getEntity();
    
                    System.out.println("----------------------------------------");
                    System.out.println(response.getStatusLine());
                    if (entity != null) {
                        System.out.println("Response content length: " + entity.getContentLength());
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
                        String text;
                        while ((text = bufferedReader.readLine()) != null) {
                            System.out.println(text);
                        }
    
                    }
                    EntityUtils.consume(entity);
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
                return null;
            }
    
        }
    参数 String xmlStr 是传入的封装好的xml字符串(封装方法在我微信支付开发的文章里面有)
    然后测试结果

    这里面签名有个隐藏的坑,就是请求字段,和mic_id都正确,微信签名验证也正确,请求就是报签名错误
    原因是我的退款原因(refund_desc)参数是中文的,把它调成英文的

    不得不说微信支付开发文档很坑



  • 相关阅读:
    蔚来NIO Pilot 全球首试 终于摘掉半成品帽子
    这个机械手可精准灵活地接住一颗掉落的棉花糖并使其“安然无恙”
    谷歌已经领先 那么苹果的人工智能战略又在哪里
    你见过机器船吗?MIT新版ROBOAT可以自动组装
    谷歌、亚马逊、苹果三大语音助手发展现状 谁被甩在身后了
    Python中的十大图像处理工具
    测试用例设计理论
    Flask+Mysql搭建网站之数据库问题
    Flask+Mysql搭建网站之网页设计
    Flask+Mysql搭建网站之安装Mysql
  • 原文地址:https://www.cnblogs.com/SongG-blogs/p/9197735.html
Copyright © 2020-2023  润新知