java+uniapp对接app微信支付

java+uniapp对接app微信支付

1.准备工作

注册app

APP接入微信支付,需要先将商户APP在微信开放平台进行注册,登记APP开发参数以生成APPID。具体操作步骤如下:

一、登录微信开放平台,进入【管理中心 → 移动应用 → 创建移动应用】;

img

二、完成基本信息的录入,商户需要在本步骤提交APP对应的下载地址,应用官网,应用水印,icon等业务信息;

img

三、完成平台信息的录入,商户需要在本步骤提交APP在Android及iOS端对应的开发参数,包括Android端应用的包名,应用签名,iOS端应用的bundle ID, universal link等;

img

注意:

四、以上信息全部提交完成后,即完成APP的注册,商户可在【管理中心 → 移动应用】中,选择具体的应用查看其APPID及已获得的接口能力;

img

五、获取到APP的APPID后,需要将该APPID与商户的收款mch_id进行绑定,商户可登录商户平台后前往【产品中心 -> AppID账号管理】界面中进行AppID的绑定及管理,界面如图所示:

img

2.业务流程

img

重点步骤说明:

步骤3:用户下单发起支付,商户可通过微信支付APP下单API创建支付订单。

商户调用APP下单API后,分正常返回和异常返回情况:

  • 正常返回:返回prepay_id,商户可根据返回的prepay_id来生成调用OpenSDK的签名以执行下一步。
  • 异常返回:返回http code或错误码,商户可根据http code列表错误码说明来排查原因并执行下一步操作

步骤8: 商户通过APP调起支付OpenSDK调起微信支付,发起支付请求,有关OpenSDK调起支付的详细说明,请参考2.2.2部分的说明

步骤15-19: 用户支付成功后,商户可通过以下两种方式获取订单状态

我们通过以下接口将用户确认订单信息回调通知给商户系统:

*方法一:*支付结果通知。用户支付成功后,微信支付会将支付成功的结果以回调通知的形式同步给商户,商户的回调地址需要在调用APP下单API时传入notify_url参数。

*方法二:*当因网络抖动或本身notify_url存在问题等原因,导致无法接收到回调通知时,商户也可主动调用查询订单API 查询订单API来获取订单状态

3.工具类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PrePayVo {
    private String appid;
    private String partnerid;
    private String prepayid;
//    private String package;
    private String noncestr;
    private long timestamp;
    private String sign;

}

签名工具类

package com.jdzh.enterprise.admin.controller.pay;

/**
 * @author Heb
 * @version 1.0
 * @description: TODO
 * @date 2023/2/21 14:33
 */
import java.security.MessageDigest;
import java.util.*;

public class WechatPaySignUtil {

    /**
     * 对参数进行签名
     * @param params 待签名的参数
     * @param key API密钥
     * @return 签名结果
     */
    public static String sign(Map<String, String> params, String key) {
        // 按照参数名ASCII码从小到大排序
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        // 拼接参数名和参数值
        StringBuilder sb = new StringBuilder();
        for (String k : keys) {
            String v = params.get(k);
            if (v != null && !"".equals(v.trim())) {
                sb.append(k).append("=").append(v.trim()).append("&");
            }
        }
        sb.append("key=").append(key);

        // 对字符串进行MD5加密
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(sb.toString().getBytes("UTF-8"));
            String sign = bytesToHexString(bytes).toUpperCase();
            return sign;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将字节数组转换为十六进制字符串
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                sb.append("0");
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
       Map<String, String> params = new HashMap<String, String>();
        params.put("appid", "");
        String key = "";//api2秘钥
        /**
         * 一次签名
         * ------------------------------
         */
//        params.put("nonce_str", "");
//        params.put("attach","");
//        params.put("body", "");
//        params.put("mch_id", "");
//        params.put("notify_url", "");
//        params.put("out_trade_no", "");
//        params.put("total_fee", "");
//        params.put("spbill_create_ip", "");
//        params.put("trade_type", "");

///**
// * 二次签名
// * ------------------------------
// */
        params.put("partnerid","");
        params.put("prepayid","");
        params.put("package","Sign=WXPay");
        params.put("noncestr", "FOBvoTUvG8sM5lMvYrYofUdhmYUSDGRw");
        params.put("timestamp","1677135129641");


        String sign = WechatPaySignUtil.sign(params, key);
        System.out.println("sign = " + sign);
        params.put("sign", sign);
    }

}
package com.jdzh.enterprise.admin.controller.pay;

import org.springframework.stereotype.Component;

/**
 * @author Heb
 * @version 1.0
 * @description: TODO
 * @date 2023/2/23 9:25
 */
@Component
public class WxPayConfig {
    /**
     * 统一下单地址
     */
    public static final String API_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * appid
     */
    public static String APP_ID = "";
    /**
     * 商户id
     */
    public static String MCH_ID = "";
    /**
     * 附加数据
     */
    public static String ATTCH="";
    /**
     * 发起请求的服务器ip
     */
    public static String SPBILL_CREATE_IP="";
    /**
     *     apiv2key
     */
    public static String MCH_KEY = "";
//    public static String APP_SECRET = "xxxxxx";
    /**
     * 通知回调地址
     */
    public static String NOTIFY_URL = "http://example.com/wechatpay/notify";
    public static String TRADE_TYPE = "APP";

    /**
     *    生成随机字符串
     * @return
     */
    public static String getNonceStr() {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            sb.append(str.charAt((int) (Math.random() * str.length())));
        }
        return sb.toString();
    }

    /**
     *  生成商户订单号
     * @return
     */
    public static String getOutTradeNo() {
        return MCH_ID + System.currentTimeMillis();
    }
}

4.后端代码
package com.jdzh.enterprise.admin.controller.pay;

import com.jdzh.enterprise.framework.entity.*;
import com.jdzh.enterprise.framework.entity.vo.PrePayVo;
import com.jdzh.enterprise.framework.service.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Heb
 * @version 1.0
 * @description: TODO
 * @date 2023/2/23 9:03
 */
@RestController
@RequestMapping("/wxPay")
public class WxPayController {

    @Autowired
    IQbbcommodityService iQbbcommodityService;
    @Autowired
    IUserService iUserService;
    @Autowired
    IEnterpriseService iEnterpriseService;
    @Autowired
    IBusinessService iBusinessService;
    @Autowired
    IIndividualService iIndividualService;
    /**
     *
     *  total_fee 下单金额:单位(分)
     *  body  商品描述
     *  
     * @return
     */
    @PostMapping("/pay")
    public RespBean Pay(String total_fee, String body) throws IOException {
        //生成随机字符串
        String nonce_str= WxPayConfig.getNonceStr();
        //生成订单号
        String out_trade_no=WxPayConfig.getOutTradeNo();
        //获取当前系统时间戳
        Timestamp sysTime = new Timestamp(System.currentTimeMillis());
        long timestamp = sysTime.getTime();

        //调用微信统一下单接口
        String prePayMsg=this.prePay(total_fee,body,nonce_str,out_trade_no);

        //获得prePayId
        String prePayId= null;
        try {
            prePayId = prePayMsg.substring(prePayMsg.indexOf("<prepay_id><![CDATA[")+20,prePayMsg.indexOf("]]></prepay_id>"));
        } catch (Exception exception) {
            return RespBean.error("生成预订单失败");
        }
        //对数据进行二次签名
        PrePayVo prePayVo = this.SecondsSign(prePayId, nonce_str, timestamp);
        return RespBean.ok("请求成功",prePayVo);
    }

    /**
     * 预下单获取prepayiD,第一次签名
     */
    public String  prePay(Integer total_fee,String body,String nonce_str,String out_trade_no) throws IOException {

        WxPayConfig wxPayConfig = new WxPayConfig();
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", wxPayConfig.APP_ID);
        params.put("nonce_str", nonce_str);
        params.put("attach",wxPayConfig.ATTCH);
        params.put("body", body);
        params.put("mch_id", wxPayConfig.MCH_ID);
        params.put("notify_url", wxPayConfig.NOTIFY_URL);
        params.put("out_trade_no", out_trade_no);
        params.put("total_fee", String.valueOf(total_fee));
        //发起请求的服务器ip
        params.put("spbill_create_ip", wxPayConfig.SPBILL_CREATE_IP);
        params.put("trade_type", wxPayConfig.TRADE_TYPE);
        //生成签名
        String key = wxPayConfig.MCH_KEY;//api2秘钥
        String sign = WechatPaySignUtil.sign(params, key);
       //存入签名
        params.put("sign", sign);
        // //封装请求参数
                String xml = "<xml>" +
                                "<appid>" + wxPayConfig.APP_ID + "</appid>" +
                                 "<attach>" + wxPayConfig.ATTCH + "</attach>" +
                                "<body>" + body + "</body>" +
                                "<mch_id>" + wxPayConfig.MCH_ID + "</mch_id>" +
                                "<nonce_str>" + nonce_str + "</nonce_str>" +
                                 "<notify_url>" + wxPayConfig.NOTIFY_URL + "</notify_url>" +
                                "<out_trade_no>" +out_trade_no + "</out_trade_no>" +
                                "<spbill_create_ip>" + wxPayConfig.SPBILL_CREATE_IP + "</spbill_create_ip>" +
                                 "<total_fee>" + total_fee + "</total_fee>" +
                                "<trade_type>" + wxPayConfig.TRADE_TYPE + "</trade_type>" +
                                "<sign>" + sign + "</sign>" +
                            "</xml>";
        //发送请求到微信统一下单接口,获取prepayId

        // 发送HTTP POST请求
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(wxPayConfig.API_URL);
        httpPost.setHeader("Content-Type", "application/xml;charset=UTF-8");
        httpPost.setEntity(new StringEntity(xml.toString(), "UTF-8"));
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        String result = "";
        if (httpEntity != null) {
            result = EntityUtils.toString(httpEntity, "UTF-8");
        }
        return result;
    }
    /**
     * 通过prePayId.进行二次签名
     */
    public PrePayVo SecondsSign(String prePayId,String nonce_str,long  timestamp){
        WxPayConfig wxPayConfig = new WxPayConfig();
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", wxPayConfig.APP_ID);
        params.put("partnerid",wxPayConfig.MCH_ID);
        params.put("prepayid",prePayId);
        params.put("package","Sign=WXPay");
        params.put("noncestr", nonce_str);
        params.put("timestamp", String.valueOf(timestamp));
        //生成签名
        String key = wxPayConfig.MCH_KEY;//api2秘钥
        String sign = WechatPaySignUtil.sign(params, key);
//        params.put("sign", sign);
        //封装参数
        PrePayVo prePayVo = new PrePayVo();
        prePayVo.setAppid(wxPayConfig.APP_ID);
        prePayVo.setPartnerid( wxPayConfig.MCH_ID);
        prePayVo.setPrepayid(prePayId);
        prePayVo.setNoncestr(nonce_str);
        prePayVo.setTimestamp(timestamp);
        prePayVo.setSign(sign);
        return prePayVo;
    }

}

5.前端代码
<template>
	<view class="content">
		
		<view class="text-area">
			<button @click="wxPay">微信支付</button>
		</view>
	</view>
</template>

<script>
	export default {
		
		data() {
			return {
				title: 'Hello',
			}
			
		},
		onLoad() {

		},
		methods: {
			wxPay(){
				uni.request({
						    url: 'http://192.168.1.9:8085/wxPay/pay?total_fee=1&body=测试', //仅为示例,并非真实接口地址。
							method:'post',
						    data: {
						  
						    },
							 success: (res) => {
							  //       console.log(res.data);
							  //       this.text = 'request success';
							  var msg=res.data.data;
							   console.log(res.data);
							    console.log("appid="+msg.appid);
							  uni.requestPayment({
							      "provider": "wxpay", 
							      "orderInfo": {
							       "appid": msg.appid,  // 应用ID(AppID)
									 "partnerid": msg.partnerid,      // 商户号(PartnerID)
									 "prepayid": msg.prepayid, // 预支付交易会话ID
									 "package": "Sign=WXPay",        // 固定值
									 "noncestr": msg.noncestr, // 随机字符串
									 "timestamp": msg.timestamp,        // 时间戳(单位:秒)
									 "sign": msg.sign // 签名,这里用的 MD5 签名
							      },
							     success: function (res) {
							         var rawdata = JSON.parse(res.rawdata);
									//在这里可以根据自己的需求将支付信息存到数据库中,我这里就不演示了
									
							         console.log("支付成功");
							     },
							     fail: function (e) {
									//支付失败也可以根据自己的需求将支付信息存到数据库中,我这里也就不演示了
							         console.log('支付失败:' + JSON.stringify(e));
							     }
							  })
							    }
						    
						});
		
			
			},
			
		}
	}
</script>

<style>
</style>

6.将项目打包

点击发行-app原生打包
在这里插入图片描述

包名要和微信开放平台的一致,,证书别名,秘钥,证书,就是我们在微信开放平台设置的,填进去就行

然后真机运行,就可以支付了

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
uniapp中配置App微信支付,有两种方式可供选择:微信支付原生方式和uniappunipay方式(unicloud)。 1. 使用微信支付原生方式: - 首先,需要在微信开放平台注册一个应用,并获取到应用的AppID和AppSecret。 - 然后,在uniapp的manifest.json文件中配置微信支付相关的权限和参数,比如AppID和支付回调地址。 - 接下来,在uniapp的代码中使用wx.requestPayment()函数调用微信支付接口,并传入相关参数,如商品信息、订单号、支付金额等。 - 最后,根据微信支付结果进行相应的处理,比如支付成功后的跳转页面或展示支付成功的提示信息等。 2. 使用uniappunipay方式(unicloud): - 首先,需要在unicloud的控制台中进行微信支付的配置,包括AppID、AppSecret、商户号等信息。 - 接着,在uniapp的代码中使用unipay的API调用微信支付接口,传入相关参数,如商品信息、订单号、支付金额等。 - 最后,根据微信支付结果进行相应的处理,比如支付成功后的跳转页面或展示支付成功的提示信息等。 需要注意的是,对于uniapp配置微信支付,具体的实现方式还需要根据具体的项目需求和开发框架进行调整和配置。详细的配置步骤和代码示例可以参考uniappunicloud的官方文档,以及相关的开发者社区和论坛。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [uniapp微信支付方案](https://blog.csdn.net/weixin_43108539/article/details/124691959)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [2023年包更原生安卓影视app苹果CMS对接,原生JAVA影视APP源码支持PC+WAP+APP](https://download.csdn.net/download/weixin_36643308/88220311)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值