微信支付之H5

微信支付之H5

申请用户授权

    @GetMapping("/getWxAuthCode")
    public String getWxAuthCode() throws UnsupportedEncodingException {
        // 这里重定向到微信授权服务器
        return "redirect:" + WxUtil.getWxAuthCode();
    }

服务器接收到用户授权的Code

根据用户授权code获取用户的openid,跳转到服务统一下单地址

/**
     * 根据授权码code 获取 用户的 opendId
     *
     * @param code  用户授权的code
     * @param state 传参返回的
     * @return 重定向到预支付地址
     */
    @GetMapping("/wx‐oauth‐code‐return‐url")
    public String wxOAuth2CodeReturn(@RequestParam String code, @RequestParam String state) {
        //申请openid
        ResponseEntity<String> exchange = new RestTemplate().exchange(WxUtil.getWxTokenURL(code), HttpMethod.GET, null, String.class);
        String response = exchange.getBody();
        String openid = JSONObject.parseObject(response).getString("openid");
        //携带openid跳转至统一下单地址 return "redirect:http://xfc.nat300.top/transaction/wxjspay?openid=" + openid;
        //携带openid跳转至统一下单地址
        return "redirect:http://xfc.nat300.top/transaction/wxjspay?openid=" + openid;
    }

统一下单地址请求微信服务器,发起预支付

==请求微信服务器形成预支付,得到微信服务器返回的预支付 “prepay_id”,把返回的请求与appid包装返回前端页面,在微信浏览器调起微信支付 ==

/**
     * 统一下单接口
     *
     * @param openid 用户openid
     * @return 返回下单界面,到微信客户端。然后调起微信客户端的JS-API调起微信支付
     */
    @GetMapping("/wxjspay")
    public ModelAndView wxjspay(@RequestParam String openid) {
        try {
            //微信支付渠道参数
            // 构造微信预支付客户端
            WXPay wxpay = new WXPay(WxUtil.getWXPayConfig(WxUtil.mchID));
            //按照微信统一下单接口要求构造请求参数
            // https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
            Map<String, String> requestParam = new HashMap<String, String>();
            //订单描述
            requestParam.put("body", "iphone8");
            //订单号
            requestParam.put("out_trade_no", "1234567");
            //人民币
            requestParam.put("fee_type", "CNY");
            //金额
            requestParam.put("total_fee", String.valueOf(1));
            //客户端ip
            requestParam.put("spbill_create_ip", "127.0.0.1");
            //微信异步通知支付结果接口,暂时不用
            requestParam.put("notify_url", "none");
            requestParam.put("trade_type", "JSAPI");
            requestParam.put("openid", openid);
            // 发起微信预支付
            //调用微信统一下单API
            Map<String, String> resp = wxpay.unifiedOrder(requestParam);
            // 得到微信预支付响应参数
            // 拼接微信响应参数到 H5 界面
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            Map<String, String> jsapiPayParam = new HashMap<>();
            jsapiPayParam.put("appId", resp.get("appid"));
            jsapiPayParam.put("package", "prepay_id=" + resp.get("prepay_id"));
            jsapiPayParam.put("timeStamp", timestamp);
            jsapiPayParam.put("nonceStr", UUID.randomUUID().toString());
            jsapiPayParam.put("signType", "HMAC‐SHA256");
            jsapiPayParam.put("paySign", WXPayUtil.generateSignature(jsapiPayParam, WxUtil.key, WXPayConstants.SignType.HMACSHA256));
            log.info("微信JSAPI支付响应内容:" + jsapiPayParam);
            // 返回H5 界面到浏览器
            return new ModelAndView("wxpay", jsapiPayParam);
            // 浏览器界面中调起JS-API进行支付
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

统一下单接口2 发起微信预支付



    /**
     * 统一下单接口2
     *
     * @param openid 用户openid
     * @return 返回下单界面,到微信客户端。然后调起微信客户端的JS-API调起微信支付
     */
    @GetMapping("/wxjspay2")
    public ModelAndView wxjspay2(@RequestParam String openid, HttpServletRequest request) {
        WxPayMpOrderResult payResult = null;
        try {
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            // 订单编号规则 yyMMddHHmmss+userId
            orderRequest.setOutTradeNo("11233321123");
            orderRequest.setOpenid(openid);
            orderRequest.setBody("手机");
            // 元转成分
            int fee = 0;
            BigDecimal actualPrice =new BigDecimal("10");
            fee = actualPrice.multiply(new BigDecimal(100)).intValue();
            orderRequest.setTotalFee(fee);
            // 设置设备
            orderRequest.setSpbillCreateIp(IPUtil.getIpAddr(request));
            // 根据商户id 和 秘钥请求预支付
            payResult = WxUtil.getWXPayService("***", "**").createOrder(orderRequest);
            // 返回H5 界面到浏览器
            return new ModelAndView("wxpay", "payResult", payResult);
            // 浏览器界面中调起JS-API进行支付
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


前端H5页面调起微信支付

H5页面发起微信支付并相应,支付成功或者失败

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Expires" content="0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>同步通知</title>
    <script>

        function onBridgeReady(){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId" : "${appId}", // 公众号名称,由商户传入
                    "timeStamp" : "${timeStamp}", // 时间戳,自1970年以来的秒数
                    "nonceStr" : "${nonceStr}", // 随机串
                    "package" : "${package}",
                    "signType" : "${signType}", // 微信签名方式:
                    "paySign" : "${paySign}" // 微信签名,paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。
                },
                function(res) {
                    if(res.err_msg == "get_brand_wcpay_request:ok" ) { // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                        alert('支付成功!');
                    } else {
                        alert('支付失败:' + res.err_msg);
                    }
                    WeixinJSBridge.call('closeWindow');
                }
            );
        }
        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>
<div id="app">

</div>
</body>
</html>

其他的一些工具类

import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.github.wxpay.sdk.IWXPayDomain;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayConstants;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * <p> 微信工具类 </p>
 *
 * @author: ZHT
 * @create: 2021-03-25 09:25
 **/
@Component
public class WxUtil {

    /**
     * appID 申请微信公众号时拥有
     */
    public static String appID = "***";

    /**
     * 设置的商户id
     */
    public static String mchID = "***";

    /**
     * 申请微信公众号时拥有
     */
    public static String appSecret = "**";

    /**
     * API调用时的秘钥,保密,商户秘钥Key
     */
    public static String key = "**";

    /**
     * 申请授权码地址
     */
    public static String wxOAuth2RequestUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";

    /**
     * 授权回调地址,此域名为前边设置的微信网页授权域名
     */
    public static String wxOAuth2CodeReturnUrl = "http://xfc.nat300.top/transaction/wx‐oauth‐code‐return‐url";

    /**
     * 请求code的带参,微信申请授权code会传回来
     */
    public static String state = "";

    /**
     * 根据商户id 获取微信支付配置
     *
     * @param mchID 商户id
     * @return 微信支付配置
     */
    public static WXPayConfig getWXPayConfig(String mchID) {
        return new WXPayConfig() {
            @Override
            protected String getAppID() {
                return appID;
            }

            @Override
            protected String getMchID() {
                return mchID;
            }

            @Override
            protected String getKey() {
                return key;
            }

            @Override
            protected InputStream getCertStream() {
                return null;
            }

            @Override
            protected IWXPayDomain getWXPayDomain() {
                return new IWXPayDomain() {
                    @Override
                    public void report(String s, long l, Exception e) {

                    }

                    @Override
                    public DomainInfo getDomain(WXPayConfig wxPayConfig1) {
                        return new DomainInfo(WXPayConstants.DOMAIN_API, true);
                    }
                };
            }
        };
    }

    /**
     * 微信授权码地址
     *
     * @return 微信授权码地址URL
     * @throws UnsupportedEncodingException 地址转码失败
     */
    public static String getWxAuthCode() throws UnsupportedEncodingException {
        return String.format("%s?appid=%s&scope=snsapi_base&state=%s&redirect_uri=%s", wxOAuth2RequestUrl, appID, state, URLEncoder.encode(wxOAuth2CodeReturnUrl, "UTF-8"));
    }

    /**
     *  获取微信openid地址
     *
     * @return  获取微信openid地址URL
     */
    public static String getWxTokenURL(String code) {
        return String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appID, appSecret, code);
    }


    /**
     *  获取微信openid地址
     * @param mchId 商户id
     * @param mchKey 商户秘钥key
     * @return  请求支付服务
     */
    public static WxPayService getWXPayService(String mchId, String mchKey) {
        WxPayService wxPayService = new WxPayServiceImpl();
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setAppId(appID);
        wxPayConfig.setMchId(mchId);
        wxPayConfig.setMchKey(mchKey);
        wxPayConfig.setSignType("MD5");
        wxPayConfig.setTradeType("JSAPI");
        wxPayConfig.setNotifyUrl("");
        wxPayConfig.setKeyPath("");
        wxPayService.setConfig(wxPayConfig);
        return wxPayService;
    }


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值