微信支付对接


微信支付对接

前期准备工作
去官方申请账号并申请相关支付功能,并且生成对应的公钥与私钥。


一、如果对接微信支付

微信支付不用于支付宝支付,在传参上没有支付宝那么的傻瓜方式,需要我们自己按照他的要求拼装参数。

二、开始对接

1.申请交易

引入微信支付SDK

	<!-- 微信支付sdk -->
	<!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-pay -->
	<dependency>
		<groupId>com.github.binarywang</groupId>
		<artifactId>weixin-java-pay</artifactId>
		<version>4.1.0</version>
	</dependency>

创建调用工具类

public class ApiURLConsts {

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

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

}

下文中 OpenTM.XXXX 这个方法是我系统内自己的方法用来获取数据库中配置好的 Appid 商户号之类的,这个大家换成自己的就行。

@Override
public JSONObject getWXPayOrderInfoNative(OrderEntity entity){
    if (null != entity && PsopConstant.OrderStatus.INIT.equals(entity.getStatus())) {
        long money4wx = Long.valueOf(entity.getPrice());
        String openId="";
        Optional<MemberEntity> memberEntity = memberDao.findById(entity.getMemberId());
        if (memberEntity.isPresent()){
            openId = memberEntity.get().getOpenId();
        }
        SortedMap<String, String> params = new TreeMap<String, String>();
        params.put("mch_id", OpenTM.getWXpayMchid());
        params.put("appid", OpenTM.getWXpayAppid());
        params.put("device_info","WEB");
        params.put("nonce_str", RandomStringUtils.randomAlphanumeric(20));
        params.put("body", "充值备注");
        params.put("out_trade_no", entity.getId() + "");
        params.put("total_fee", money4wx + "00");// 单位 分
        params.put("spbill_create_ip", OpenTM.getWXPayIP());
        params.put("notify_url", OpenTM.getWXpayNotifyUrl());
        params.put("trade_type", "NATIVE");
//            params.put("openid", openId);
        //交易结束时间:订单产生多久后不支付订单失效,请求支付必传参数prepay_id只有两小时的有效期
        //Date endDate = DateUtil.getDateAfterHours(1);
        //String time_expire = DateUtil.getDateStr("yyyyMMddHHmmss", endDate);
        // params.put("time_expire",time_expire);
        params.put("sign", WechatPayUtil.createSign("UTF-8", params));
        String requestXML = WechatPayUtil.getRequestXml(params);
        logger.info(requestXML);
        String result = WechatPayUtil.httpsRequest(ApiURLConsts.UNIFIEDORDER, "POST", requestXML);
        logger.info(result);
        /**统一下单接口返回正常的prepay_id(预支付交易会话标识),再按签名规范重新生成签名后,将数据传输给APP。
         参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
         **/
        //调起支付接口
        try {
            Map<String, String> map = XMLUtil.doXMLParse(result);
            logger.info(JSONHelper.bean2JSONStr(map));
            SortedMap<String, String> parameterMap2 = new TreeMap<String, String>();

            parameterMap2.put("appId", OpenTM.getWXpayAppid());
            parameterMap2.put("nonceStr", RandomStringUtils.randomAlphanumeric(20));
            parameterMap2.put("package", "prepay_id=" + map.get("prepay_id"));
            parameterMap2.put("signType", "MD5");
            parameterMap2.put("timeStamp", (System.currentTimeMillis() + "").substring(0, 10));
            parameterMap2.put("code_url", map.get("code_url"));
            //parameterMap2.put("partnerid", OpenTM.getWXpayMchid());
            //parameterMap2.put("prepayid", map.get("prepay_id"));
            //本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下
            String sign2 = WechatPayUtil.createSign("UTF-8", parameterMap2);
            parameterMap2.put("paySign", sign2);

            return JSONHelper.map2JSONObj(parameterMap2);
        } catch (Exception e) {
            logger.error("读取微信返回结果异常");
            logger.error(e.getLocalizedMessage());
        }
    }
    return JSONHelper.success("");
}
以上是相关业务代码,需要注意的是微信传入钱的单位是以分位单位,传入 1 元支付 0.01 元,由于我们的最小充值单位是1元而且都是整数,所以我这里直接补了 00 前端就不做任何处理了。

2.微信回调方法

如果支付成功,微信官方会回调这个接口,带上相关支付信息。解析request获得对应的Map信息然后处理对应的业务即可。

@RequestMapping(value = "wechat/notify.json")
public void notify(HttpServletRequest request) {
    logger.info("微信支付回调参数");
    SortedMap<String, String> wxparams = new TreeMap<String, String>();
    try {
        String string = WechatPayUtil.inputStream2String(request.getInputStream(), "UTF-8");
        Map<String, String> map = XMLUtil.doXMLParse(string);
        wxparams.putAll(map);
    } catch (Exception e) {
        logger.error(e.getLocalizedMessage());
    }

    if (null == wxparams || wxparams.size() == 0) {
        logger.error("微信支付通知回调参数处理失败");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "参数格式校验错误"));
        return;
    }
    //1.验证签名
    boolean isWxpaySign = WechatPayUtil.isTenpaySign("utf-8", wxparams);
    if (!isWxpaySign) {
        logger.error("微信签名验证失败");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "签名验证失败"));
        return;
    }
    //2.验证appid
    if (!OpenTM.getWXpayAppid().equals(wxparams.get("appid"))) {
        logger.error("appid 错误");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "应用ID错误"));
        return;
    }
    //3.验证商户ID
    if (!OpenTM.getWXpayMchid().equals(wxparams.get("mch_id"))) {
        logger.error("mch_id 错误");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "商户ID错误"));
        return;
    }

    if ("SUCCESS".equals(wxparams.get("return_code")) && "SUCCESS".equals(wxparams.get("result_code"))) {
        logger.info("全部验证通过,处理自己的逻辑");
        //paymentService.saveWXpayNotify(wxparams);
        logger.info("微信支付回调只需要处理自己的逻辑,一切OK");
        try {
            String orderIdStr = wxparams.get("out_trade_no");
            String wxpayOrderIdStr = wxparams.get("transaction_id");
            String totalFee = wxparams.get("total_fee");

            logger.info("orderIdStr:{}  wxpayOrderIdStr:{}  totalFee:{} ", orderIdStr, wxpayOrderIdStr, totalFee);

            orderService.execReceiveWXPayNotify(orderIdStr, wxpayOrderIdStr, totalFee);
        } catch (Exception e) {
            e.printStackTrace();
        }
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("SUCCESS", "处理成功"));
        return;
    } else {
        //记录通知信息
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("SUCCESS", "处理成功"));
        return;
    }
}

总结

以上就是微信支付的相关代码,希望对大家有所帮助。

微信支付的 v3 版本相比较 v2 版本有了很多变化和升级,包括接口地址、签名方式、请求参数等等。在 Python 中对接微信支付 v3 接口,需要使用到官方提供的 SDK 和第三方库。 下面是一个简单的对接微信支付 v3 的示例代码: 1. 安装依赖库:需要安装 `wechatpay` 和 `requests` 两个库,可以通过 pip 命令进行安装: ```python pip install wechatpay requests ``` 2. 导入 SDK 和库: ```python import wechatpay import wechatpay.utils as utils import requests ``` 3. 配置商户证书和密钥: ```python merchant_id = '商户号' api_key = 'API密钥' cert_file = 'apiclient_cert.pem' key_file = 'apiclient_key.pem' ``` 4. 使用 SDK 创建支付订单: ```python url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi' nonce_str = utils.generate_random_string(32) timestamp = utils.get_current_timestamp() body = { "mchid": merchant_id, "appid": "应用ID", "description": "商品描述", "out_trade_no": "商户订单号", "amount": { "total": 1, "currency": "CNY" }, "payer": { "openid": "用户openid" } } headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'WECHATPAY2-SHA256-RSA2048 ' + wechatpay.get_authorization_header( method='POST', url=url, body=body, merchant_id=merchant_id, api_key=api_key, cert_file=cert_file, key_file=key_file, nonce_str=nonce_str, timestamp=timestamp ) } response = requests.post(url, headers=headers, json=body) ``` 5. 处理返回结果: ```python if response.status_code == 200: result = response.json() prepay_id = result.get('prepay_id') return_data = { 'appId': '应用ID', 'timeStamp': str(timestamp), 'nonceStr': nonce_str, 'package': 'prepay_id=' + prepay_id, 'signType': 'RSA', 'paySign': wechatpay.get_sha256withrsa_signature( timestamp + '\n' + nonce_str + '\n' + 'prepay_id=' + prepay_id + '\n', key_file=key_file ) } else: error_msg = response.json().get('message') return {'error': error_msg} ``` 以上是一个简单的微信支付 v3 对接示例,具体实现还需要根据自己的业务需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值