微信支付的实现

超详细的Java知识点汇总


电商支付流程

支付过程涉及的角色

  1. 用户
  2. 商户
  3. 电商平台
  4. 微信

用户支付流程

  1. 下单
  2. 选择支付方式
  3. 扫码
  4. 支付
  5. 跳转订单页面

微信支付开发流程

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
在这里插入图片描述
开发过程

  1. 生成订单
  2. 将订单插入平台数据库中(未支付状态)
  3. 在微信下单订单,微信返回付款url
  4. 将url包装到二维码
  5. 用户扫码,支付
  6. 微信收到钱后,通知平台,调用平台的接口
  7. 平台收到支付成功消息后,更新订单状态,修改库存
  8. 页面进行跳转

位置支付案例

下载微信支付的SDK
https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA.zip

配置微信支付

/**
 * 微信支付配置
 */
public class MyWXConfig extends WXPayConfig {

    //账户的APPID
    public String getAppID() {
        return "wx307113892f15a42e";
    }

    //商户ID
    public String getMchID() {
        return "1508236581";
    }

    //秘钥
    public String getKey() {
        return "HJd7sHGHd6djgdgFG5778GFfhghghgfg";
    }

    public InputStream getCertStream() {
        return null;
    }

    public IWXPayDomain getWXPayDomain() {
        return new WXPayDomain();
    }

    class WXPayDomain implements IWXPayDomain{

        public void report(String domain, long elapsedTimeMillis, Exception ex) {

        }

        public DomainInfo getDomain(WXPayConfig config) {
            return new DomainInfo("api.mch.weixin.qq.com",true);
        }
    }
}

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.21</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.3</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

下单、生成二维码

/**
 * 微信支付Service
 */
@Service
public class PayService {

    /**
     * 下单
     * @param goodsId 商品id
     * @param price 价格
     * @return 二维码的URL
     */
    public Map<String, String> makeOrder(String goodsId, Long price) throws Exception {
        //创建支付对象
        MyWXPayConfig config = new MyWXPayConfig();
        WXPay wxPay = new WXPay(config);
        Map<String,String> map = new HashMap<>();
        map.put("appid",config.getAppID());
        map.put("mch_id",config.getMchID());
        map.put("device_info","WEB");
        map.put("nonce_str", UUID.randomUUID().toString().replace("-",""));
        map.put("body","商城购物");
        String tradeNo = UUID.randomUUID().toString().replace("-", "");
        map.put("out_trade_no", tradeNo);
        map.put("fee_type","CNY");
        map.put("total_fee",String.valueOf(price));
        map.put("notify_url","http://n538ep.natappfree.cc/order/notify"); //微信对商户后台的回调接口
        map.put("trade_type","NATIVE");
        map.put("product_id",goodsId);
        //执行统一下单
        Map<String, String> result = wxPay.unifiedOrder(map);
        System.out.println("result:"+result);
        //保存订单号
        result.put("trade_no",tradeNo);
        return result;
    }

    /**
     * 生成二维码
     * @param url
     * @param response
     */
    public void makeQRCode(String url, HttpServletResponse response){
        //通过支付链接生成二维码
        HashMap<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 200, 200, hints);
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", response.getOutputStream());
            System.out.println("创建二维码完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 检查订单状态
     * @param tradeNo
     * @return
     * @throws Exception
     */
    public String checkOrder(String tradeNo) throws Exception {
        MyWXPayConfig config = new MyWXPayConfig();
        String str =
        "<xml>"+
           "<appid>"+config.getAppID()+"</appid>"+
            "<mch_id>"+config.getMchID()+"</mch_id>"+
            "<nonce_str>"+UUID.randomUUID().toString().replace("-","")+"</nonce_str>"+
            "<out_trade_no>"+tradeNo+"</out_trade_no>"+
            "<sign>5E00F9F72173C9449F802411E36208734B8138870ED3F66D8E2821D55B317078</sign>"+
        "</xml>";
        WXPay pay = new WXPay(config);
        Map<String,String> map = WXPayUtil.xmlToMap(str);
        Map<String, String> map2 = pay.orderQuery(map);
        String state = map2.get("trade_state");
        System.out.println("订单"+tradeNo+",状态"+state);
        return state;
    }

}

订单控制器

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private PayService payService;

    private String tradeNo;

    //二维码生成
    @GetMapping("/code")
    public void qrcode(@RequestParam("goodsId")String goodsId,
                       @RequestParam("price")Long price,
                       HttpServletResponse response){
        try {
            Map<String,String> map = payService.makeOrder(goodsId, price);
            payService.makeQRCode(map.get("code_url"),response);
            System.out.println("生成订单号:" + map.get("trade_no"));
            tradeNo = map.get("trade_no");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //支付后通知
    @PostMapping("/notify")
    public void notify(HttpServletRequest request,HttpServletResponse response) throws Exception {
        //获得微信传来的xml字符串
        String str = Streams.asString(request.getInputStream());
        //将字符串xml转换为Map
        Map<String, String> map = WXPayUtil.xmlToMap(str);
        //读取订单号
        String no = map.get("out_trade_no");
        //模拟修改商户后台数据库订单状态
        System.out.println("更新订单状态:"+no);
        //给微信发送消息
        response.getWriter().println("<xml>\n" +
                "   <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                "   <return_msg><![CDATA[OK]]></return_msg>\n" +
                "   <appid><![CDATA["+map.get("appid")+"]]></appid>\n" +
                "   <mch_id><![CDATA["+map.get("mch_id")+"]]></mch_id>\n" +
                "   <nonce_str><![CDATA["+map.get("nonce_str")+"]]></nonce_str>\n" +
                "   <openid><![CDATA["+map.get("openid")+"]]></openid>\n" +
                "   <sign><![CDATA["+map.get("sign")+"]]></sign>\n" +
                "   <result_code><![CDATA[SUCCESS]]></result_code>\n" +
                "   <prepay_id><![CDATA["+map.get("prepay_id")+"]]></prepay_id>\n" +
                "   <trade_type><![CDATA[NATIVE]]></trade_type>\n" +
                "</xml>");
    }

    //检查订单状态
    @PostMapping("checkOrder")
    public String checkOrder() throws Exception {
        System.out.println("trade_no:" + tradeNo);
        if(StringUtils.isEmpty(tradeNo)){
            return null;
        }
        String success = payService.checkOrder(tradeNo);
        System.out.println("check:" + success);
        return success;
    }
}

页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<!--二维码图片-->
    <div id="app">
        <img src="http://api.blb.com/api/order-api/order/code?goodsId=999&price=1">
    </div>

    <script type="text/javascript" src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        var interval;
        //定时查询订单状态
        interval = setInterval("checkOrder()",3000);
        function checkOrder(){
            axios.post("http://api.blb.com/api/order-api/order/checkOrder")
                .then(res => {
                    console.log(res.data);
                   if(res.data === "SUCCESS"){
                        location.href = "success.html";
                        clearInterval(interval);
                   }
                });
        }
    </script>
</body>
</html>
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒哥~Bingo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值