微信公众号代H5实现微信支付 V2密钥

原作者  https://blog.csdn.net/weixin_44142296/article/details/87078045 

使用 com.github.binarywang 包 

pom.xml支持   


        <!--微信支付包-->
       <!-- // 授权登录用到-->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>3.3.0</version>
        </dependency>

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

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


@Api("微信支付")
@Controller
@RequestMapping("/API/V1")
public class WXMpController {

    @Autowired
    WxMpService wxMpService;

    @Autowired
    WxPayService wxPayService;

    private static Logger log = LoggerFactory.getLogger(WXMpController.class);


/**
 *
 String baseUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
 "appid=微信那边给的appId&" +
 "redirect_uri=自己这面需要获得授权的页面地址&" +
 "response_type=code&scope=snsapi_userinfo&state=chuai#wechat_redirect";
 * 1、引导用户进入授权页面同意授权,获取code
 * @return
 */
    @ResponseBody
    @RequestMapping("/wechat/authorize")
    public String getWxMpCode(String returnUrl){
        if(returnUrl!=null) {
            returnUrl = URLEncoder.encode(returnUrl);
        }
        String baseUrl = wxMpService.oauth2buildAuthorizationUrl(
                "http://shanhuo.natappvip.cc/sell/wechat",
                WxConsts.OAuth2Scope.SNSAPI_USERINFO,
                returnUrl);
        logger.info("baseUrl打印:{}",baseUrl);

       return "redirect:"+baseUrl;
    }





    /**
     * 获取用户信息 openid 、accessToken等
     *
     * @param code
     * @param state
     * @return
     */

    @ResponseBody
    @RequestMapping("/wechat")
    public BaseResult getUser(String code, String state) {
        BaseResult baseResult = new BaseResult();
        WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken();
        try {
            accessToken = wxMpService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        String openId = accessToken.getOpenId();
        accessToken.getAccessToken();
        baseResult.setCode(200);
        baseResult.setData(openId);
        return baseResult;
    }








    /**
     * 唤醒支付
     *
     * @param orderId
     * @param openid
     * @return
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @ResponseBody
    @RequestMapping("/pay/create")
    public BaseResult parCreate(Model m, int orderId, String openid, String key, HttpServletRequest request) {
        log.info("进入pay/create方法。。。{}", wxPayService);
            //获取用户ID 写的很垃圾 原谅下我
        String ip = null;
        ip = request.getHeader("X-Forwarded-For");
        if (null == ip) {
            ip = request.getRemoteAddr();
        }
      

        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setAttach("携带的参数给回调接口  此处我写的是用户的ID  根据自己的业务");
        orderRequest.setOpenid(openid);
        orderRequest.setBody("center");
           //自己生成订单号 随机字符串 
        orderRequest.setOutTradeNo((PassWord.getRandom(24, PassWord.TYPE.LETTER))); 
        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(0.001));//元转成分
        orderRequest.setSpbillCreateIp(ip);
        orderRequest.setNotifyUrl("shejiaobang.xyz/notify/order"); //回调地址
        orderRequest.setTradeType("JSAPI"); //支付类型
        try {
            WxPayMpOrderResult wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
            BaseResult baseResult = new BaseResult();
            baseResult.setData(wxPayMpOrderResult);
            baseResult.setCode(200);
            return baseResult;
        } catch (WxPayException e) {
            log.info("微信支付失败!订单号:{},原因:{}", orderId, e.getMessage());
            e.printStackTrace();
            return BaseResult.invalidRequest();
        }

    }



    @RequestMapping("notify/order")
    public void PayResultNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("微信支付返回通知函数开始---------------------");

        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        boolean isPayOk = false;
        WxPayOrderNotifyResult wxPayOrderNotifyResult = null;

        // 此处调用订单查询接口验证是否交易成功
        try {
            wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(result);
            if ("SUCCESS".equals(wxPayOrderNotifyResult.getResultCode())) {
                isPayOk = true;
            }
            log.info("解析数据:" + wxPayOrderNotifyResult.toString());
        } catch (WxPayException e) {
            e.printStackTrace();
        }

        String noticeStr = "";


        // 支付成功,商户处理后同步返回给微信参数
        PrintWriter writer = response.getWriter();
        if (isPayOk) {
           //此处写自己的业务

            // 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口
            noticeStr = setXML("SUCCESS", "OK");
            writer.write(noticeStr);
            writer.flush();

        } else {

            // 支付失败, 记录流水失败
            noticeStr = setXML("FAIL", "");
            writer.write(noticeStr);
            writer.flush();
            System.out.println("===============支付失败==============");
        }


    }

    /**
     * 通知微信接收回调成功
     *
     * @return_code SUCCESS
     * @return_msg OK
     * @return
     */
    public static String setXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 微信参数工具类  
 */
@Configuration
//此处有可能会亮红色下划线  属于 idea 警告   可以忽视
@ConfigurationProperties(prefix = "wechat")
public class WxConfig {
    private String appid;
    private String appSecret;
    private String mchId;
    private String mchKey;
    private String keyPath;

    @Bean
    public WxMpInMemoryConfigStorage initStorage(){
        WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
        config.setAppId(appid);
        config.setSecret(appSecret);
        return  config;
    }

    @Bean
    public WxMpService initWxMpService(){
        WxMpService wxMpService= new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(initStorage());

        return  wxMpService;
    }

    @Bean
    public WxPayService initWxPayService(){
        WxPayService wxPayService= new WxPayServiceImpl();
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(appid);
        payConfig.setMchId(mchId);
        payConfig.setSignType(WxPayConstants.SignType.MD5);
        payConfig.setMchKey(mchKey);
//        payConfig.setKeyPath(keyPath);  此处是回调地址 上面写死了这个参数没用到我注释了
        wxPayService.setConfig(payConfig);
        return  wxPayService;
    }


    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getAppSecret() {
        return appSecret;
    }

    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }

    public String getMchId() {
        return mchId;
    }

    public void setMchId(String mchId) {
        this.mchId = mchId;
    }

    public String getMchKey() {
        return mchKey;
    }

    public void setMchKey(String mchKey) {
        this.mchKey = mchKey;
    }

    public String getKeyPath() {
        return keyPath;
    }

    public void setKeyPath(String keyPath) {
        this.keyPath = keyPath;
    }
}

yml  格式

wechat:
  appid: ********公众平台给的 
  appSecret: 公众平台给的 *******
  mchId: ******公众平台给的 
  mchKey: 商户平台给的

下面是我的订单号随机生成类



import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
/**
 * 字符随机生成类
 * @author ASUS
 *
 */
public class PassWord {

    /**
     * 密码类型枚举
     * @author ASUS
     */
    public static enum TYPE {
        /**
         * 字符型
         */
        LETTER,
        /**
         * 大写字符型
         */
        CAPITAL,
        /**
         * 数字型
         */
        NUMBER,
        /**
         * 符号型
         */
        SIGN,
        /**
         * 大+小字符 型
         */
        LETTER_CAPITAL,
        /**
         * 小字符+数字 型
         */
        LETTER_NUMBER,
        /**
         * 大+小字符+数字 型
         */
        LETTER_CAPITAL_NUMBER,
        /**
         * 大+小字符+数字+符号 型
         */
        LETTER_CAPITAL_NUMBER_SIGN
    }

    private static String[] lowercase = {
            "a","b","c","d","e","f","g","h","i","j","k",
            "l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};

    private static String[] capital = {
            "A","B","C","D","E","F","G","H","I","J","K",
            "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};

    private static String[] number = {
            "1","2","3","4","5","6","7","8","9","0"};

    private static String[] sign = {
            "~","!","@","#","$","%","^","&","*","(",")","_","+","`","-","=",
            "{","}","|",":","\"","<",">","?",
            "[","]","\\",";","'",",",".","/"};

    /**
     * 静态随机数
     */
    private static Random random = new Random();

   /* public static void main(String[] args) {
        System.out.println(PassWord.getRandom(24, PassWord.TYPE.LETTER));
    }*/

    /**
     * 获取随机组合码
     * @param num 位数
     * @param type 类型
     * @type
     * <br>字符型 LETTER,
     * <br>大写字符型 CAPITAL,
     * <br>数字型 NUMBER,
     * <br>符号型 SIGN,
     * <br>大+小字符型 LETTER_CAPITAL,
     * <br>小字符+数字 型 LETTER_NUMBER,
     * <br>大+小字符+数字 型 LETTER_CAPITAL_NUMBER,
     * <br>大+小字符+数字+符号 型 LETTER_CAPITAL_NUMBER_SIGN
     */
    public static String getRandom(int num,TYPE type){
        ArrayList<String> temp = new ArrayList<String>();
        StringBuffer code = new StringBuffer();
        if(type == TYPE.LETTER){
            temp.addAll(Arrays.asList(lowercase));
        }else if(type == TYPE.CAPITAL){
            temp.addAll(Arrays.asList(capital));
        }else if(type == TYPE.NUMBER){
            temp.addAll(Arrays.asList(number));
        }else if(type == TYPE.SIGN){
            temp.addAll(Arrays.asList(sign));
        }else if(type == TYPE.LETTER_CAPITAL){
            temp.addAll(Arrays.asList(lowercase));
            temp.addAll(Arrays.asList(capital));
        }else if(type == TYPE.LETTER_NUMBER){
            temp.addAll(Arrays.asList(lowercase));
            temp.addAll(Arrays.asList(number));
        }else if(type == TYPE.LETTER_CAPITAL_NUMBER){
            temp.addAll(Arrays.asList(lowercase));
            temp.addAll(Arrays.asList(capital));
            temp.addAll(Arrays.asList(number));
        }else if(type == TYPE.LETTER_CAPITAL_NUMBER_SIGN){
            temp.addAll(Arrays.asList(lowercase));
            temp.addAll(Arrays.asList(capital));
            temp.addAll(Arrays.asList(number));
            temp.addAll(Arrays.asList(sign));
        }
        for (int i = 0; i < num; i++) {
            code.append(temp.get(random.nextInt(temp.size())));
        }
        return code.toString();
    }

}

下面 前端吊起收营台 就可以了  

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>支付页面</title>
    <script>
        function onBridgeReady(){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":"${wxPayMpOrderResult.appId}",     //公众号名称,由商户传入
                    "timeStamp":"${wxPayMpOrderResult.timeStamp}",         //时间戳,自1970年以来的秒数
                    "nonceStr":"${wxPayMpOrderResult.nonceStr}", //随机串
                    "package":"${wxPayMpOrderResult.packageValue}",
                    "signType":"MD5",         //微信签名方式:
                    "paySign":"${wxPayMpOrderResult.paySign}" //微信签名
                },
                function(res){
                    // if(res.err_msg == "get_brand_wcpay_request:ok" ){
                        window.location.href="${returnUrl}";
                        // 使用以上方式判断前端返回,微信团队郑重提示:
                        //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();
        }
    </script>
</head>
<body>

</body>
</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值