java 微信公众号微信支付

5 篇文章 0 订阅
1 篇文章 0 订阅

微信支付开发

一、引入需要的库


首先引入github 微信支付和公众号支持库

    <dependency>
        <groupId>com.github.binarywang</groupId>
        <artifactId>weixin-java-mp</artifactId>
        <version>4.1.0</version>
    </dependency>

    <dependency>
        <groupId>com.github.binarywang</groupId>
        <artifactId>weixin-java-pay</artifactId>
        <version>4.1.0</version>
    </dependency>

第二步
配置

代码如下(示例):

#公众号微信配置
application.wechat.mp.configs[0].appId=
application.wechat.mp.configs[0].secret=
application.wechat.mp.configs[0].token=
application.wechat.mp.configs[0].aesKey=
application.wechat.mp.useRedis=false
#公众号微信支付配置
application.wechat.pay.appId=
application.wechat.pay.mchId=
application.wechat.pay.mchKey=
#keyPath p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
application.wechat.pay.keyPath=

二、配置微信参数

代码如下(示例):
公众号的自行找demo配置

import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Binary Wang
 */
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
  private WxPayProperties properties;

  @Bean
  @ConditionalOnMissingBean
  public WxPayService wxService() {
    WxPayConfig payConfig = new WxPayConfig();
    payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
    payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
    payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
    payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
    payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
    payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));

    // 可以指定是否使用沙箱环境
    payConfig.setUseSandboxEnv(false);

    WxPayService wxPayService = new WxPayServiceImpl();
    wxPayService.setConfig(payConfig);
    return wxPayService;
  }

}


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * wxpay pay properties.
 *
 * @author Binary Wang
 */
@Data
@ConfigurationProperties(prefix = "application.wechat.pay")
public class WxPayProperties {
  /**
   * 设置微信公众号或者小程序等的appid
   */
  private String appId;

  /**
   * 微信支付商户号
   */
  private String mchId;

  /**
   * 微信支付商户密钥
   */
  private String mchKey;

  /**
   * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
   */
  private String subAppId;

  /**
   * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
   */
  private String subMchId;

  /**
   * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
   */
  private String keyPath;

}

3前端调用预订单获取

后台统一下单获取jsapi支付参数封装一些必要参数

  @ApiOperation(value = "原生的统一下单接口")
  @PostMapping("/unifiedOrder")
  public Result unifiedOrder(@RequestBody Object object) throws WxPayException {
    WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
    request.setDeviceInfo("WEB");
    request.setOpenid("111111");//必须要
    request.setSignType("MD5");
    request.setBody("测试1"); //必填项 产品信息
    request.setFeeType("CNY");//必填项  默认cny
    request.setTotalFee(1);//必填项 订单总金额,单位为分,详见支付金额
    return payService.createOrder(request);
  }

service处理订单信息

import com.alibaba.fastjson.JSONObject;

import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.AllArgsConstructor;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Service
@AllArgsConstructor
public class OrderService implements IOrderService {
    private final static Log logger  = LogFactory.getLog(OrderService.class);

    private WxPayService wxService;
    private WxPayProperties wxPayProperties;
    private SystemCfg systemCfg;
   


    @Override
    public Result createOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
        Result result = new Result();
        //生成订单号
        request.setNotifyUrl("127.0.0.1/pay/notify/order"); //回调地址
        request.setSpbillCreateIp("127.0.0.1");//服务器ip 必填
        request.setTradeType("JSAPI");   //必填JSAPI

        WxPayUnifiedOrderResult wxResult =this.wxService.unifiedOrder(request);
        logger.info("\n微信发起预订单接收到请求消息,内容:"+JsonUtils.toJson(wxResult));
        if(wxResult.getReturnCode().equals("SUCCESS")){
        	//   wxOrder.add
        	
            signOrder(result, wxResult);
        }else {
            result.setErrCode(1);
            result.setErrMsg("微信发起订单失败");
        }
        return result;
    }

    /**
     * 封装微信预订单生成成功后返回的方法
     * @param result
     * @param wxResult
     */
    private void signOrder(Result result, WxPayUnifiedOrderResult wxResult) {
    	//封装JSAPI调起支付需要的参数
        TreeMap<String, String> stringStringTreeMap = new TreeMap<>();
        String timeStamp = getSecondTimestampTwo(new Date());
        stringStringTreeMap.put("appId",wxResult.getAppid());
        stringStringTreeMap.put("timeStamp",timeStamp);
        stringStringTreeMap.put("nonceStr",wxResult.getNonceStr());
        stringStringTreeMap.put("package","prepay_id="+wxResult.getPrepayId());
        stringStringTreeMap.put("signType","MD5");
        String sign = MD5Utils.encodeSign(stringStringTreeMap, wxPayProperties.getMchKey());

        WxSignVo vo = new WxSignVo();
        vo.setAppId(wxResult.getAppid());
        vo.setTimeStamp(timeStamp);
        vo.setNonceStr(wxResult.getNonceStr());
        vo.setPrepay_id(wxResult.getPrepayId());
        vo.setSignType("MD5");
        vo.setPaySign(sign);
        String encode="";
        //这里是我加密的可以不用
        try {
             encode = EncodeUtil.encryptDES(JSONObject.toJSONString(vo),"12345");
        } catch (Exception e) {
            e.printStackTrace();
        }

        result.setData(encode);
    }


    /**
     * 获取精确到秒的时间戳
     * @param date
     * @return
     */
    public static String getSecondTimestampTwo(Date date){
        if (null == date) {
            return "";
        }
        String timestamp = String.valueOf(date.getTime()/1000);
        return timestamp;
    }
}

这里是需要用到的MD5UTILS

import org.apache.commons.lang3.StringUtils;

import java.security.MessageDigest;
import java.util.*;
 
public class MD5Utils {
 
    /**
     * sign 签名 (参数名按ASCII码从小到大排序(字典序)+key+MD5+转大写签名)
     * @param map
     * @return
     */
    public static String encodeSign(SortedMap<String,String> map, String key){
        if(StringUtils.isEmpty(key)){
            throw new RuntimeException("签名key不能为空");
        }
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        List<String> values =new ArrayList();
 
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            String k = String.valueOf(entry.getKey());
            String v = String.valueOf(entry.getValue());
            if (StringUtils.isNotEmpty(v) && entry.getValue() !=null && !"sign".equals(k) && !"key".equals(k)) {
                values.add(k + "=" + v);
            }
        }
        values.add("key="+ key);
        String sign = StringUtils.join(values, "&");
        return encodeByMD5(sign).toUpperCase();
    }
    /**
     * 通过MD5加密
     *
     * @param algorithmStr
     * @return String
     */
    public static String encodeByMD5(String algorithmStr) {
        if (algorithmStr==null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("md5");
            messageDigest.update(algorithmStr.getBytes("utf-8"));
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
 
    }
 
    private static String getFormattedText(byte[] digest){
        StringBuffer buffer = new StringBuffer();
        //把每一个byte,做一个与运算,0xff
        for (byte b :
                digest) {
            int number=b & 0xff;//加盐
            String str = Integer.toHexString(number);
            if (str.length() == 1){
                buffer.append("0");
            }
            buffer.append(str);
        }
        //标准的md5加密后的结果
        return buffer.toString();
    }

    public static void main(String[] args) {
 
        TreeMap<String, String> stringStringTreeMap = new TreeMap<>();
        stringStringTreeMap.put("appId","appId");
        stringStringTreeMap.put("timeStamp","timeStamp");
        stringStringTreeMap.put("nonceStr","nonceStr");
        stringStringTreeMap.put("package","prepay_id=111");
        stringStringTreeMap.put("signType","MD5");

 
        String s = MD5Utils.encodeSign(stringStringTreeMap, "111");
        System.out.println(s);
    }
}

附带前端唤起支付的js

function onBridgeReady(){
   WeixinJSBridge.invoke(
      'getBrandWCPayRequest', {
         "appId":"wx2421b1c4370ec43b",     //公众号ID,由商户传入     
         "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
         "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
         "package":"prepay_id=u802345jgfjsdfgsdg888",     
         "signType":"MD5",         //微信签名方式:     
         "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
      },
      function(res){
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
      // 使用以上方式判断前端返回,微信团队郑重提示:
            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      } 
   }); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了微信换气支付的使用 回显回调的话函数和方法自己出处理逻辑。

https://github.com/binarywang 微信支付和公众号demo 可以去这里查看

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值