赞
踩
微信支付开发
首先引入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; }
后台统一下单获取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 可以去这里查看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。