Java后端对接微信支付(小程序、APP、PC端扫码)包含查单退款

首先我们要明确目标,我们点击微信支付官网,我们主要聚焦于这三种支付方式,其中JSPAI与APP主要与uniapp开发微信小程序与APP对接,而NATIVE主要与网页端扫码支付对接

1.三种支付统一准备工作

建议导入这个jar,里面一些提供map和xml互转以及生成签名的函数,使用非常方便。

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

ps:下面代码涉及到的WXPayUtil下面的函数都是这个工具包里来的,所以不要再问这个函数代码在哪

商户号与支付结果通知回调地址

回调url配置途径:

微信商户平台(pay.weixin.qq.com)-->产品中心-->开发配置-->支付配置

既然涉及到维信小程序和app,那么它们的app_id是必须的

统一下单、查单、退款的API地址,去官方文档找即可,我这里直接写好了

/**
 * 统一下单接口
 */
public static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

/**
 * 查询订单接口
 */
public static final String ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

 /**
  * 订单退款接口
  */
public static final String ORDER_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
 

API密钥

用于签名算法

获取途径

微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->设置API密钥

 2.JSAPI统一下单

这种支付的使用场景,我们这里是对接uniapp开发的微信小程序

我们仔细阅读文档并提取信息,其实访问接口的很多参数都不是必填的,我们尽量去关注必填参数

归纳如下:

appid微信小程序app_idmch_id商户号nonce_str随机字符串,可以调用WXPayUtil下generateNonceStr方法生成sign

可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

appid 微信小程序app_id
mch_id 商户号
nonce_str 随机字符串,可以调用WXPayUtil下generateNonceStr方法生成
sign
可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

body 商品描述,建议软件名字+产品操作,例如天天爱消除-游戏充值
out_trade_no 我们自己生成的订单号,保证同一商号下唯一即可
total_fee 金额,注意单位是分
spbill_create_ip 用户客户端ip
notify_url 支付结果通知回调地址
trade_type 交易类型,我们这里填JSAPI
openid 因为是JSAPI方式,所以必传,openid其实很好获取,参考地址如何获取openid

但是下完单之后,怎么样才能让前端调用微信支付呢?这里需要查看uniapp官方文档微信小程序支付

我们发现其实主要是拿到预支付id prepay_id以及签名

代码实现:

    public Map<String, String> unifiedOrderByJsp(Order order, String clientIp) throws Exception {
        long begin = System.currentTimeMillis();
        //使用map封装微信支付需要的固定参数
        Map<String, String> m = new HashMap<>();
        //设置支付参数
        m.put("appid", OrderUtils.WX_APP_ID);
        m.put("mch_id", OrderUtils.MCH_ID);
        m.put("nonce_str", WXPayUtil.generateNonceStr());
        //商品描述 例如:天天爱消除-游戏充值
        m.put("body", "换芯易-" + order.getGoodsModel() + "购买");
        //订单号
        m.put("out_trade_no", order.getOrderSn());
        m.put("total_fee", order.getActualPrice().multiply(new BigDecimal("100")).longValue() + "");
        m.put("spbill_create_ip", clientIp);
        m.put("notify_url", OrderUtils.NOTIFY_URL);
        m.put("trade_type", "JSAPI");
        //trade_type=JSAPI时(即JSAPI支付),必须要openid
        UserThreeDao userThreeDao = new UserThreeDaoImpl();
        UserThree userThree = userThreeDao.queryOpenid(order.getUserId());
        if (userThree == null) {
            return null;
        }
        m.put("openid", userThree.getThreeOpenid());
        //生成签名
        m.put("sign", WXPayUtil.generateSignature(m, OrderUtils.APP_KEY));

        //发送请求,请求路径:UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"
        HttpClient client = new HttpClient(OrderUtils.UNIFIED_ORDER_URL);
        //设置xml格式的参数,要把map转为xml
        client.setXmlParam(WXPayUtil.mapToXml(m));
        //设置支持https
        client.setHttps(true);
        //执行请求发送
        client.post();

        //xml转为map接受结果
        Map<String, String> response = WXPayUtil.xmlToMap(client.getContent());
        long end = System.currentTimeMillis();
        System.out.println("请求https://api.mch.weixin.qq.com/pay/unifiedorder耗时:" + (end - begin) + "ms");
        System.out.println("请求结果:" + JSON.toJSONString(response));

        if ("SUCCESS".equals(response.get("return_code")) && "SUCCESS".equals(response.get("result_code"))) {

            Map<String, String> param = new HashMap<>();
            //返回结果格式参照https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment
            //随机字符串
            //时间戳,但是单位为s,不是毫秒
            param.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            param.put("nonceStr", WXPayUtil.generateNonceStr());

            param.put("package", "prepay_id=" + response.get("prepay_id"));
            param.put("signType", "MD5");

            param.put("paySign", WXPayUtil.generateSignature(param, OrderUtils.APP_KEY));
            return param;
        }
        //为空代表下单失败
        return null;
    }

3.NATIVE统一下单

主要应用场景是PC端扫码支付

必填参数归纳如下:

appid 微信小程序app_id
mch_id 商户号
nonce_str 随机字符串,可以调用WXPayUtil下generateNonceStr方法生成
sign
可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

body 商品描述,建议软件名字+产品操作,例如天天爱消除-游戏充值
out_trade_no 我们自己生成的订单号,保证同一商号下唯一即可
total_fee 金额,注意单位是分
spbill_create_ip 用户客户端ip
notify_url 支付结果通知回调地址
trade_type 交易类型,我们这里填NATIVE
product_id trade_type=NATIVE时,此参数必传。此参数为二维码中包含的商品ID,我们可以自行定义。

代码如下:

    public Map<String, String> unifiedOrderByNative(Order order,  String clientIp) throws Exception {
        long begin = System.currentTimeMillis();
        //使用map封装微信支付需要的固定参数
        Map<String, String> m = new HashMap<>();
        //1、设置支付参数
        m.put("appid", OrderUtils.WX_APP_ID);
        m.put("mch_id", OrderUtils.MCH_ID);
        m.put("nonce_str", WXPayUtil.generateNonceStr());
        //商品描述 例如:天天爱消除-游戏充值
        m.put("body", "换芯易-" + order.getGoodsModel() + "购买");
        //订单号
        m.put("out_trade_no", order.getOrderSn());
        m.put("total_fee", order.getActualPrice().multiply(new BigDecimal("100")).longValue() + "");
        m.put("spbill_create_ip", clientIp);
        m.put("notify_url", OrderUtils.NOTIFY_URL);
        m.put("trade_type", "NATIVE");
        //trade_type=NATIVE时,此参数必传
        m.put("product_id", order.getId());
        //生成签名
        m.put("sign", WXPayUtil.generateSignature(m, OrderUtils.APP_KEY));

        //发送请求,请求路径:UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"
        HttpClient client = new HttpClient(OrderUtils.UNIFIED_ORDER_URL);
        //设置xml格式的参数,要把map转为xml
        client.setXmlParam(WXPayUtil.mapToXml(m));
        //设置支持https
        client.setHttps(true);
        //执行请求发送
        client.post();

        //xml转为map接受结果
        Map<String, String> response = WXPayUtil.xmlToMap(client.getContent());
        long end = System.currentTimeMillis();
        System.out.println("请求https://api.mch.weixin.qq.com/pay/unifiedorder耗时:" + (end - begin) + "ms");
        System.out.println("请求结果:" + JSON.toJSONString(response));

        if ("SUCCESS".equals(response.get("return_code")) && "SUCCESS".equals(response.get("result_code"))) {

            Map<String, String> param = new HashMap<>();
            //二维码地址
            param.put("code_url", response.get("code_url"));
            param.put("order_sn", order.getOrderSn());
            param.put("order_id", order.getId());
            param.put("total_fee", order.getActualPrice().multiply(new BigDecimal("100")).longValue() + "");
            return param;
        }
        //为空代表下单失败
        return null;
    }

 上面代码中最重要的返回结果就是code_url。即生成的支付二维码地址,然后用微信扫码并付款即可。

4.APP统一下单

应用场景是APP端调用微信支付,对接uniapp开发的app

归纳如下:

appid APP的app_id
mch_id 商户号
nonce_str 随机字符串,可以调用WXPayUtil下generateNonceStr方法生成
sign
可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

body 商品描述,建议软件名字+产品操作,例如天天爱消除-游戏充值
out_trade_no 我们自己生成的订单号,保证同一商号下唯一即可
total_fee 金额,注意单位是分
spbill_create_ip 用户客户端ip
notify_url 支付结果通知回调地址
trade_type 交易类型,我们这里填APP

但是下完单之后,怎么样才能让前端调用微信支付呢?这里需要查看uniapp官方文档微信小程序支付:

我们可以看到常规的比如appid、商户号需要,充要的是预支付id prepayid和签名

代码实现如下: 

    public Map<String, String> unifiedOrderByApp(Order order, String clientIp) throws Exception {
        long begin = System.currentTimeMillis();
        //使用map封装微信支付需要的固定参数
        Map<String, String> m = new HashMap<>();
        //1、设置支付参数
        m.put("appid", OrderUtils.APP_APP_ID);
        m.put("mch_id", OrderUtils.MCH_ID);
        m.put("nonce_str", WXPayUtil.generateNonceStr());
        //商品描述 例如:天天爱消除-游戏充值
        m.put("body", "换芯易-" + order.getGoodsModel() + "购买");
        //订单号
        m.put("out_trade_no", order.getOrderSn());
        m.put("total_fee", order.getActualPrice().multiply(new BigDecimal("100")).longValue() + "");
        m.put("spbill_create_ip", clientIp);
        m.put("notify_url", OrderUtils.NOTIFY_URL);
        m.put("trade_type", "APP");
        //生成签名
        m.put("sign", WXPayUtil.generateSignature(m, OrderUtils.APP_KEY));

        //发送请求,请求路径:UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"
        HttpClient client = new HttpClient(OrderUtils.UNIFIED_ORDER_URL);
        //设置xml格式的参数,要把map转为xml
        client.setXmlParam(WXPayUtil.mapToXml(m));
        //设置支持https
        client.setHttps(true);
        //执行请求发送
        client.post();

        //xml转为map接受结果
        Map<String, String> response = WXPayUtil.xmlToMap(client.getContent());
        long end = System.currentTimeMillis();
        System.out.println("请求https://api.mch.weixin.qq.com/pay/unifiedorder耗时:" + (end - begin) + "ms");
        System.out.println("请求结果:" + JSON.toJSONString(response));

        if ("SUCCESS".equals(response.get("return_code")) && "SUCCESS".equals(response.get("result_code"))) {

            Map<String, String> param = new HashMap<>();
            param.put("appid", OrderUtils.APP_APP_ID);
            //随机字符串
            param.put("noncestr", WXPayUtil.generateNonceStr());
            //固定值
            param.put("package", "Sign=WXPay");
            param.put("partnerid", OrderUtils.MCH_ID);
            param.put("prepayid", response.get("prepay_id"));

            //时间戳,但是单位为s,不是毫秒
            param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
            //param.put("package", response.get("sign"));
            param.put("sign", WXPayUtil.generateSignature(param, OrderUtils.APP_KEY));
            return param;
        }
        //为空代表下单失败
        return null;
    }

按照uniapp官方要求的格式封装返回结果给前端。

5.三种支付方式返回结果

对于上面三种支付方式,他们的返回结果我都没有细细分析,因为官方文档写得很详细,我们非常需要关注的也就预支付id这个返回结果。所以贴一下官方文档,有兴趣可以仔细看看(重要的我会标注)

共有

其中APP和JSAPI得着重关注预支付id

 

native扫码支付主要关注code_url

 

6.查单

我们实际业务中,过于依赖微信支付的回调结果来判断订单状态显然是不太合适的,所以自己去查单这种操作十分常见。查单需要的必填参数归纳如下:

appid app_id
mch_id 商户号
nonce_str 随机字符串,可以调用WXPayUtil下generateNonceStr方法生成
sign
可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

out_trade_no 我们自己生成的订单号,保证同一商号下唯一即可,这个订单号需要和我们当时调用统一下单传过去的单号一致

ps:这里的out_trade_no可以用transaction_id代替,但是一般我们查单的时候可能还没有transaction_id,所以只能用我们自己程序业务订单号out_trade_no去查,因为transaction_id需要调查单接口才能得到,也就是说如果我们以后"二次查单"可以用这个参数。

代码实现入下:

    public Map<String, String> queryOrderStatus(String orderSn) throws Exception {
        long beginTime = System.currentTimeMillis();
        //1、封装参数
        Map<String, String> m = new HashMap<>();
        m.put("appid", OrderUtils.APP_APP_ID);
        m.put("mch_id", OrderUtils.MCH_ID);
        m.put("out_trade_no", orderSn);
        m.put("nonce_str", WXPayUtil.generateNonceStr());

        //生成签名
        m.put("sign", WXPayUtil.generateSignature(m, OrderUtils.APP_KEY));

        //发送请求,请求路径:UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery"
        HttpClient client = new HttpClient(OrderUtils.ORDER_QUERY_URL);
        client.setXmlParam(WXPayUtil.mapToXml(m));
        client.setHttps(true);
        client.post();
        //3、返回第三方的数据
        Map<String, String> result = WXPayUtil.xmlToMap(client.getContent());
        long endTime = System.currentTimeMillis();
        System.out.println("请求https://api.mch.weixin.qq.com/pay/orderquery耗时:" + (endTime - beginTime) + "ms");
        System.out.println("请求结果:" + JSON.toJSONString(result));
        return result;
    }

返回结果参数部分如下,重要的标注起来:

 一般情况下主要是利用trade_state来判断用户是否支付成功从而更新订单或记录交易成功物流等业务操作。

Map<String, String> map = orderDao.queryOrderStatus(orderSn);
if (map == null) {
    return ApiResponse.createApiResponse(ApiResponse.HTTP_STATE_400_ERROR_10001, "微信支付出错");
}
 //微信
if ("SUCCESS".equals(map.get("trade_state"))) {
    //更新订单或记录交易成功物流等业务操作
}

7.退款

言简意赅,就是方便(rnm,退钱)

重要参数

appid app_id
mch_id 商户号
nonce_str 随机字符串,可以调用WXPayUtil下generateNonceStr方法生成
sign
可以调用WXPayUtil下generateSignature方法生成,这个方法需要用到准备工作中的商户API密钥(APP_KEY)来加密。

out_trade_no 我们自己生成的订单号,保证同一商号下唯一即可,这个订单号需要和我们当时调用统一下单传过去的单号一致
transaction_id 和上面的out_trade_no二选一,官方推荐transaction_id
out_refund_no 其实和统一下单的时候的订单号原理差不多,我们自己随机生成一个,保证同一商户系统下唯一即可
total_fee 要退款的订单的金额
refund_fee 实际要退款的金额

代码实现如下:

    public Map<String, String> refundOrder(RefundTrace refundTrace, Order order) throws Exception {
        long begin = System.currentTimeMillis();
        //使用map封装微信支付需要的固定参数
        Map<String, String> m = new HashMap<>();
        //1、设置支付参数
        m.put("appid", OrderUtils.WX_APP_ID);
        m.put("mch_id", OrderUtils.MCH_ID);
        m.put("nonce_str", WXPayUtil.generateNonceStr());
        //微信支付订单号
        m.put("transaction_id", order.getPayId());
        //商户退款单号
        m.put("out_refund_no", refundTrace.getRefundSn());
        //订单金额
        m.put("total_fee", order.getActualPrice().multiply(new BigDecimal("100")).longValue() + "");
        //退款金额 即实际退款金额
        m.put("refund_fee", refundTrace.getRefundAmount().multiply(new BigDecimal("100")).longValue() + "");
        //退款原因
        m.put("refund_desc", refundTrace.getRefundReason());

        m.put("notify_url", OrderUtils.NOTIFY_URL);
        //生成签名
        m.put("sign", WXPayUtil.generateSignature(m, OrderUtils.APP_KEY));

        发送请求,请求路径:ORDER_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"
        String content = HttpRequestUtils.refundRequest(WXPayUtil.mapToXml(m));

        //xml转为map接受结果
        Map<String, String> response = WXPayUtil.xmlToMap(content);
        long end = System.currentTimeMillis();
        System.out.println("请求https://api.mch.weixin.qq.com/secapi/pay/refund耗时:" + (end - begin) + "ms");
        System.out.println("请求结果:" + JSON.toJSONString(response));

        if ("SUCCESS".equals(response.get("return_code")) && "SUCCESS".equals(response.get("result_code"))) {

            Map<String, String> param = new HashMap<>();
            param.put("refund_id", response.get("refund_id"));
            param.put("refund_fee", response.get("refund_fee"));
            return param;
        }
        //为空代表退款失败
        return null;
    }

这里注意一下!!!!因为操作涉及到把商户方的钱转回到买方的操作,所以安全系数比较高,调用退款api官方要求证书

证书申请途径如下:

 微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->申请API证书

申请到证书,需要放到项目下:

那么我们这里的http请求就不能用之前的了,需要配置该证书

 上面代码中使用的refundRequest函数细节如下:

    public static String refundRequest(String order) throws Exception {
        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            // 读取项目存放的PKCS12证书文件
            FileInputStream instream = new FileInputStream("apiclient_cert.p12");
            try {
                // 指定PKCS12的密码(商户ID)
                clientStore.load(instream, OrderUtils.MCH_ID.toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(clientStore, OrderUtils.MCH_ID.toCharArray()).build();
            // 指定TLS版本
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            // 设置httpclient的SSLSocketFactory
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            try {
                HttpPost httpost = new HttpPost(OrderUtils.ORDER_REFUND_URL); // 设置响应头信息
//                httpost.addHeader("Connection", "keep-alive");
//                httpost.addHeader("Accept", "*/*");
//                httpost.addHeader("Content-Type", CONTENT_TYPE_FORM.toString());
//                httpost.addHeader("X-Requested-With", "XMLHttpRequest");
//                httpost.addHeader("Cache-Control", "max-age=0");
//                httpost.addHeader("User-Agent", DEFAULT_USER_AGENT);
                httpost.setEntity(new StringEntity(order, "UTF-8"));
                CloseableHttpResponse response = httpclient.execute(httpost);
                try {
                    HttpEntity entity = response.getEntity();
                    String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                    EntityUtils.consume(entity);
                    return jsonStr;
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

8.补充

我所使用的HttpClient工具类源码,我这里使用主要用于发送带xml参数的post请求

public class HttpClient {
    private String url;
    private Map<String, String> param;
    private int statusCode;
    private String content;
    private String xmlParam;
    private boolean isHttps;

    public boolean isHttps() {
        return isHttps;
    }

    public void setHttps(boolean isHttps) {
        this.isHttps = isHttps;
    }

    public String getXmlParam() {
        return xmlParam;
    }

    public void setXmlParam(String xmlParam) {
        this.xmlParam = xmlParam;
    }

    public HttpClient(String url, Map<String, String> param) {
        this.url = url;
        this.param = param;
    }

    public HttpClient(String url) {
        this.url = url;
    }

    public void setParameter(Map<String, String> map) {
        param = map;
    }

    public void addParameter(String key, String value) {
        if (param == null) {
            param = new HashMap<String, String>();
        }
        param.put(key, value);
    }

    public void post() throws ClientProtocolException, IOException {
        HttpPost http = new HttpPost(url);
        setEntity(http);
        execute(http);
    }

    public void put() throws ClientProtocolException, IOException {
        HttpPut http = new HttpPut(url);
        setEntity(http);
        execute(http);
    }

    public void get() throws ClientProtocolException, IOException {
        if (param != null) {
            StringBuilder url = new StringBuilder(this.url);
            boolean isFirst = true;
            for (String key : param.keySet()) {
                if (isFirst) {
                    url.append("?");
                    isFirst = false;
                } else {
                    url.append("&");
                }
                url.append(key).append("=").append(param.get(key));
            }
            System.out.println("请求的url:" + url.toString());
            this.url = url.toString();
        }
        HttpGet http = new HttpGet(url);
        execute(http);
    }

    /**
     * set http post,put param
     */
    private void setEntity(HttpEntityEnclosingRequestBase http) {
        if (param != null) {
            List<NameValuePair> nvps = new LinkedList<NameValuePair>();
            for (String key : param.keySet())
                nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
            http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
        }
        if (xmlParam != null) {
            http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
        }
    }

    private void execute(HttpUriRequest http) throws ClientProtocolException,
            IOException {
        CloseableHttpClient httpClient = null;
        try {
            if (isHttps) {
                SSLContext sslContext = new SSLContextBuilder()
                        .loadTrustMaterial(null, new TrustStrategy() {
                            // 信任所有
                            @Override
                            public boolean isTrusted(X509Certificate[] chain,
                                                     String authType)
                                    throws CertificateException {
                                return true;
                            }
                        }).build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslContext);
                httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                        .build();
            } else {
                httpClient = HttpClients.createDefault();
            }
            CloseableHttpResponse response = httpClient.execute(http);
            try {
                if (response != null) {
                    if (response.getStatusLine() != null)
                        statusCode = response.getStatusLine().getStatusCode();
                    HttpEntity entity = response.getEntity();
                    // 响应内容
                    content = EntityUtils.toString(entity, Consts.UTF_8);
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
    }

    public int getStatusCode() {
        return statusCode;
    }

    public String getContent() throws ParseException, IOException {
        return content;
    }

}

到此这篇关于Java后端对接微信支付(小程序、APP、PC端扫码)包含查单退款的文章就介绍到这了,更多相关Java 对接微信支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java后端对接微信支付(小程序、APP、PC端扫码)包含查单退款

    首先我们要明确目标,我们点击微信支付官网,我们主要聚焦于这三种支付方式,其中JSPAI与APP主要与uniapp开发微信小程序与APP对接,而NATIVE主要与网页端扫码支付对接 1.三种支付统一准备工作 建议导入这个jar,里面一些提供map和xml互转以及生成签名的函数,使用非常方便. <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId

  • Python3 微信支付(小程序支付)V3接口的实现

    起因: 因公司项目需要网上充值功能,从而对接微信支付,目前也只对接了微信支付的小程序支付功能,在网上找到的都是对接微信支付V2版本接口,与我所对接的接口版本不一致,无法使用,特此记录下微信支付完成功能,使用Django完成后端功能,此文章用于记录使用, 以下代码仅供参考,如若直接商用出现任何后果请自行承担,本人概不负责. 功能: 调起微信支付,微信回调 代码: 1.准备工作: mchid = "xxxxxx" # 商户号 pay_key = "xxxxxx" # 商

  • springboot对接微信支付的完整流程(附前后端代码)

    展示图: 对接的完整流程如下 首先是配置 gzh.appid=公众号appid wxPay.mchId=商户号 wxPay.key=支付密钥 wxPay.notifyUrl=域名回调地址 常量: /**微信支付统一下单接口*/ public static final String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; public static String SUCCESSxml = &q

  • 微信小程序App生命周期详解

    微信小程序App生命周期: onLaunch--当小程序初始化完成时,会触发 onLaunch(全局只触发一次) onShow --当小程序启动,或从后台进入前台显示,会触发 onShow onHide --当小程序从前台进入后台,会触发 onHide onError --当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 //app.js App({ /** *当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: fun

  • 微信小程序 增、删、改、查操作实例详解

    微信小程序 增.删.改.查操作实例详解 1.以收货地址的增删改查为例 2.文件目录 js文件是逻辑控制,主要是它发送请求和接收数据, json 用于此页面局部 配置并且覆盖全局app.json配置, wxss用于页面的样式设置, wxml就是页面,相当于html <form bindsubmit="addSubmit"> <view class="consignee"> <text class="consignee-tit&q

  • 微信小程序 自动登陆PHP源码实例(源码下载)

    微信小程序 自动登陆PHP源码实例 app.js 初始化APP自动登陆 您也可以在任何地方进行用户登陆验证 用法:首先在js文件中定义 var app = getApp(); app.getUserDataToken(); App({ onLaunch: function () { /*初始化APP自动登陆 * 您也可以在任何地方进行用户登陆验证 *用法:首先在js文件中定义 var app = getApp(); app.getUserDataToken(); */ this.getUserD

  • Java后台实现微信支付和微信退款

    微信支付流程 都是我自己工作中开发的,亲测可用,不喜勿喷. controller中我是这么写的,你们需要根据自己的业务需求改动.ResponseBean是我自己封装的,你们可以改成你们想要的形式. /** * 微信统一下单接口 * @return */ @RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST) public ResponseBean doUnifiedOrder(@RequestBod

  • 产制造追溯系统之通过微信小程序实现移动端报表平台

    前言 前两篇文章主要梳理了一下在生产过程中如何更高效.更稳定的实现条码打印,有不少园子里的朋友私信我,互相讨论了一些技术方面的问题,双方都各有收获,再此感谢博客园提供的这个交流平台,让五湖四海的朋友能够汇聚在一起,互相学习.互相进步!! 生产制造追溯系统-条码打印 生产制造追溯系统-再说条码打印 突破,将报表延伸至移动端 最近几年手机应用的发展速度大家有目共睹,就拿移动支付来说,放在十年前根本不敢想象现如今出门完全不用带现金,一部手机足够了,甚至有的地方可以刷脸支付,忘了带手机也没关系:随着科技

  • 基于Java SSM的健康管理小程序的实现

    目录 一.系统的简介 二.系统实现的主要功能 三.系统的界面演示 四.核心代码展示 一.系统的简介 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器:谷歌浏览器 二.系统实现的主要功能 (1)用户管理.主要实现了健康管理小程序的用户管理功能. (2)登录注册.小程序端可以登录注册. (

  • Java编程调用微信支付功能的方法详解

    本文实例讲述了Java编程调用微信支付功能的方法.分享给大家供大家参考,具体如下: 微信开发文档地址:https://mp.weixin.qq.com/wiki/home/ 从调用处开始 我的流程: 1.点击"支付"按钮,去后台 --> 2.后台生成支付所需数据返回页面 --> 3.页面点击"确认支付"调用微信支付js.完成支付功能. 支付按钮 <div class="button" id="pay" onc

随机推荐