package com.gxwebsoft.shop.controller; import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.utils.RedisUtil; import com.gxwebsoft.common.core.utils.WxNativeUtil; import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.shop.entity.Order; import com.gxwebsoft.common.system.entity.Payment; import com.gxwebsoft.common.system.param.SettingParam; import com.gxwebsoft.shop.service.OrderService; import com.gxwebsoft.common.system.service.SettingService; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.service.payments.nativepay.NativePayService; import com.wechat.pay.java.service.payments.nativepay.model.Amount; import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest; import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.Map; @Api(tags = "微信Native支付接口") @RestController @RequestMapping("/api/shop/wx-native-pay") public class WxNativePayController extends BaseController { @Value("${spring.profiles.active}") String active; public static String merchantId = "1246610101"; public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_key.pem"; public static String merchantSerialNumber = "48749613B40AA8F1D768583FC352358E13EB5AF0"; public static String apiV3Key = "zGufUcqa7ovgxRL0kF5OlPr482EZwtn9"; @Resource private RedisUtil redisUtil; private Config wxPayConfig; @Resource private ConfigProperties config; @Resource private SettingService settingService; @Resource private OrderService orderService; @ApiOperation("生成付款码") @PostMapping("/codeUrl") public ApiResult getCodeUrl(@RequestBody Order order) { final User loginUser = getLoginUser(); if(loginUser == null){ return fail("请先登录"); } String key = "Payment:wxPay:".concat(getTenantId().toString()); final Payment payment = redisUtil.get(key, Payment.class); if (payment == null) { return fail("微信支付未配置"); } // 获取微信小程序配置信息 final String string = redisUtil.get("mp-weixin:".concat(getTenantId().toString())); if(string == null){ return fail("微信小程序未配置"); } final JSONObject jsonObject = JSONObject.parseObject(string); final String appId = jsonObject.getString("appId"); // 处理订单数据 order.setTenantId(loginUser.getTenantId()); order.setUid(loginUser.getUserId()); // order.setRealName(loginUser.getRealName()); order.setPhone(loginUser.getPhone()); // order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.MONTH, order.getTotalNum())); // 使用自动更新平台证书的RSA配置 // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错 // 构建service NativePayService service = new NativePayService.Builder().config(this.getWxPayConfig()).build(); // request.setXxx(val)设置所需参数,具体参数可见Request定义 PrepayRequest request = new PrepayRequest(); // 计算金额 order.setMoney(new BigDecimal("0.01")); // order.getPayPrice().toString() long orderNo = IdUtil.getSnowflakeNextId(); order.setOrderNo(Long.toString(orderNo)); BigDecimal decimal = order.getMoney(); final BigDecimal multiply = decimal.multiply(new BigDecimal(100)); // 将 BigDecimal 转换为 Integer Integer money = multiply.intValue(); Amount amount = new Amount(); amount.setTotal(money); request.setAmount(amount); request.setAppid(appId); request.setMchid(payment.getMchId()); request.setDescription(order.getComments()); request.setNotifyUrl("https://modules.gxwebsoft.com/api/shop/wx-native-pay/notify/" + getTenantId()); request.setOutTradeNo(order.getOrderNo()); // 调用下单方法,得到应答 PrepayResponse response = service.prepay(request); // 使用微信扫描 code_url 对应的二维码,即可体验Native支付 // System.out.println(response.getCodeUrl()); // 生成指定url对应的二维码到文件,宽和高都是300像素 // QrCodeUtil.generate(response.getCodeUrl(), 300, 300, FileUtil.file("/Users/gxwebsoft/Documents/uploads/wx-native-qrcode.jpg")); orderService.save(order); return success("生成付款码", response.getCodeUrl()); } private Config getWxPayConfig() { // 获取租户ID final Integer tenantId = getTenantId(); Config build = WxNativeUtil.getConfig(tenantId); if (build != null) { return build; } String key = "Payment:wxPay:".concat(tenantId.toString()); final Payment payment = redisUtil.get(key, Payment.class); System.out.println("payment = " + payment); String apiclientKey = config.getUploadPath().concat("/file").concat(payment.getApiclientKey()); // 开发环境配置 if(active.equals("dev")){ apiclientKey = privateKeyPath; } Config config = new RSAAutoCertificateConfig.Builder() .merchantId(payment.getMchId()) .privateKeyFromPath(apiclientKey) .merchantSerialNumber(payment.getMerchantSerialNumber()) .apiV3Key(payment.getApiKey()) .build(); System.out.println("config = " + config); WxNativeUtil.addConfig(tenantId, config); return config; } @ApiModelProperty("异步通知") @PostMapping("/notify/{tenantId}") public String wxNotify(@RequestHeader Map header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) { System.out.println("异步通知*************** = "); System.out.println("request header = " + header); System.out.println("request body = " + body); System.out.println("tenantId = " + tenantId); // 获取支付配置信息用于解密 final SettingParam param = new SettingParam(); param.setSettingKey("payment"); param.setTenantId(tenantId); final String uploadPath = config.getUploadPath(); // 服务器本地路径 return "fail"; } }