微信小程序支付案例

第一步:

申请小程序,然后在小程序管理后台,申请接入微信支付

第二步:

接入微信支付之后,配置支付相关秘钥以及下载商户证书

第三步: pom中添加如下依赖


    com.github.wechatpay-apiv3
    wechatpay-apache-httpclient
    0.2.2



    com.egzosn
    pay-java-common
    2.12.1
   


    com.egzosn
    pay-java-wx
    2.12.1

第四步: 创建微信请求工具类


public class WxHttpClient{
    public static String appid = "XX";                             // 小程序id
    public static String mchId = "XX";                             // 商户号
    public static String mchSerialNo = "XX";                       // 商户证书序列号
    private static String apiV3Key = "XX";                         // api密钥
    public static String notify_url="";                            //微信支付通知回调

    private static volatile CloseableHttpClient wxHttpClient;
    private static AutoUpdateCertificatesVerifier verifier;

    private WxHttpClient(){}
    public static CloseableHttpClient getWxHttpClient() {
       if(wxHttpClient==null){
           synchronized (WxHttpClient.class){
               if(wxHttpClient==null){
                   //加载私钥
                   PrivateKey merchantPrivateKey = loadPrivateKey();

                   //使用自动更新的签名验证器,不需要传入证书
                   try {
                       verifier = new AutoUpdateCertificatesVerifier(
                               new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
                               apiV3Key.getBytes("utf-8"));
                   } catch (UnsupportedEncodingException e) {
                       e.printStackTrace();
                       System.out.println("构建签名验证器失败!!!");
                   }

                   //构建HttpClient
                   wxHttpClient = WechatPayHttpClientBuilder.create()
                           .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                           .withValidator(new WechatPay2Validator(verifier))
                           .build();
               }
           }
       }
       return wxHttpClient;
    }

    public static PrivateKey loadPrivateKey(){
        PrivateKey merchantPrivateKey = null;
        try {
            merchantPrivateKey = PemUtil.loadPrivateKey(
                    new FileInputStream("apiclient_key.pem"));
        } catch (FileNotFoundException e) {
            System.out.println(DateUtil.getCurrentDate()+"商户私钥加载异常");
            e.printStackTrace();
        }
        return merchantPrivateKey;
    }

    //第三方工具类需要的配置
    public static WxPayConfigStorage getWxPayConfigStorage(){
        WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
        wxPayConfigStorage.setMchId(mchId);//支付商户号
        wxPayConfigStorage.setAppid(appid);//小程序appid
        // wxPayConfigStorage.setKeyPublic("转账公钥,转账时必填");
        wxPayConfigStorage.setSecretKey("");// 商户支付密钥(之前设置的商户apiv3秘钥)
        wxPayConfigStorage.setSignType("MD5");
        wxPayConfigStorage.setInputCharset("utf-8");
        return wxPayConfigStorage;
    }
}
 

第五步:小程序调用下单获取预支付订单号及微信支付通知回调Controller

@RestController
@RequestMapping("/wxpay")
public class WxPayController {
    @Resource
    private UserService userService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private UserCreditService userCreditService;

    private com.egzosn.pay.wx.api.WxPayService wxUserPayService=new com.egzosn.pay.wx.api.WxPayService(WxHttpClient.getWxPayConfigStorage());

    /**
     * @Desc 统一下单
     * @Date 2021/5/22 13:38
     */
    @RequestMapping("/unifiedOrder")
    @SysLog(name="统一下单")
    public ResultVO unifiedOrder(@RequestBody UserCredit userCredit) throws IOException {
        //校验参数是否为空
        BeanValidator.validate(userCredit, Creation.class);

        //判断当前用户是否存在于系统中
        User user=new User();
        user.setId(userCredit.getUserId());
        user.setOpenId(userCredit.getOpenId());
        List users = userService.selectAllData(user);
        if(CollectionUtils.isEmpty(users)){
            throw new BusinessException(0,"非系统用户,拒绝访问");
        }
        String outTradeNo=WxPayUtil.getOutTradeNo(userCredit.getUserId()+"");
        userCredit.setAddTime(DateUtil.getCurrentDate());
        userCredit.setOutTradeNo(outTradeNo);
        userCredit.setTradeStatus(0);

        //调用微信下单接口
        String prepay_id_str = wxPayService.unifiedOrder(userCredit);

        JSONObject rsobject=JSONObject.parseObject(prepay_id_str);
        return ResultVOUtil.success(rsobject,"下单成功");
    }


    /**
     *
     * 微信用户支付回调接口
     */
    @RequestMapping("/userPayCallBack")
    public String wxUserPaycallback(HttpServletRequest request) {
        try {
            Map params = wxUserPayService.getParameter2Map(request.getParameterMap(),
                    request.getInputStream());
            if (null == params) {
                throw new Exception("回调参数为空");
            }
            // 校验
            if (!wxUserPayService.verify(params)) {
                throw new Exception("校验失败");
            }
            payDone(params);//支付处理
            return wxUserPayService.getPayOutMessage("SUCCESS", "成功").toMessage();

        } catch (Exception e) {
            e.printStackTrace();
            return wxUserPayService.getPayOutMessage("FALL", "失败").toMessage();
        }
    }

    /**
     * 支付结果处理
     */
    private void payDone(Map dataMap) throws Exception {
        System.out.println("支付回调:" + JSON.toJSONString(dataMap));
        String result_code = dataMap.get("result_code").toString();   //支付结果code
        String out_trade_no = dataMap.get("out_trade_no").toString(); //商户交易订单id,此为支付记录id

        if (!result_code.equals("SUCCESS")) {
            throw new Exception("支付回调失败:" + JSON.toJSONString(dataMap));
        }
        UserCredit userCredit=new UserCredit();
        userCredit.setOutTradeNo(out_trade_no);
        List userCredits = userCreditService.selectAllData(userCredit);//获取打赏记录
        if (CollectionUtils.isEmpty(userCredits)) {
            throw new Exception("无支付记录,回调处理失败!!!");
        }
        userCredit.setTradeStatus(result_code.equals("SUCCESS") ? 1 : 2);
        userCredit.setOutTradeNo(out_trade_no);
        int updateFlag=userCreditService.updateCredit(userCredit);//根据回调结果更改支付结果状态
        if(updateFlag==0){
            throw new Exception("更新用户打赏表状态失败!!!");
        }
    }
}

第六步:创建微信支付服务类

@Service
public class WxPayServiceImpl implements WxPayService {
    @Autowired
    private UserCreditService userCreditService;

    private CloseableHttpClient wxHttpClient=WxHttpClient.getWxHttpClient();

    /**
     * @Desc 统一下单接口
     * @Date 2021/5/22 15:39
     */
    @Override
    public String unifiedOrder(UserCredit userCredit)  throws IOException {
        //添加微信下单记录
        userCreditService.insertUserCredit(userCredit);

        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid", WxHttpClient.mchId)
                .put("appid", WxHttpClient.appid)
                .put("description", "Image形象店-深圳腾大-QQ公仔")
                .put("notify_url", WxHttpClient.notify_url)
                .put("out_trade_no", userCredit.getOutTradeNo());
        rootNode.putObject("amount")
                .put("total", userCredit.getAmount());
        rootNode.putObject("payer")
                .put("openid", userCredit.getOpenId());

        objectMapper.writeValue(bos, rootNode);

        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = wxHttpClient.execute(httpPost);

        String prepay_id_str = EntityUtils.toString(response.getEntity());
        JSONObject object=JSONObject.parseObject(prepay_id_str);
        Object code = object.get("code");
        if(code!=null){
            if(code.toString().equals("PARAM_ERROR")){
                throw new BusinessException(0,"下单失败:"+object.get("message"));
            }
        }
        return prepay_id_str;
    }
}

你可能感兴趣的:(小程序,java)