电商(十)支付

本文详细介绍了电商支付系统的微信支付实现,从开发准备到支付状态的检测,涵盖支付二维码生成、订单状态操作、支付信息回调及MQ处理。通过HttpClient工具类调用微信支付接口,使用Redis存储订单信息,确保支付成功后订单状态的正确更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明:本文来源于网络,整理自本网站,如有侵权请联系删除。

学习目标

  • 能够说出微信支付开发的整体思路

  • 生成支付二维码

  • 查询支付状态

  • 实现支付日志的生成与订单状态的修改、删除订单

  • 支付状态回查

  • MQ处理支付回调状态

  • 定时处理订单状态

1 开发准备

1.1 开发文档

微信支付接口调用的整体思路:

按API要求组装参数,以XML方式发送(POST)给微信支付接口(URL),微信支付接口也是以XML方式给予响应。程序根据返回的结果(其中包括支付URL)生成二维码或判断订单状态。

在线微信支付开发文档:

https://pay.weixin.qq.com/wiki/doc/api/index.html

我们在本章中会用到”统一下单”和”查询订单”两组API

1. appid:微信公众账号或开放平台APP的唯一标识
2. mch_id:商户号  (配置文件中的partner)
3. partnerkey:商户密钥
4. sign:数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性

1.2 微信支付模式回顾

模式二

业务流程说明:

1.商户后台系统根据用户选购的商品生成订单。
2.用户确认支付后调用微信支付【统一下单API】生成预支付交易;
3.微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
4.商户后台系统根据返回的code_url生成二维码。
5.用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
6.微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
7.用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
8.微信支付系统根据用户授权完成支付交易。
9.微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
10.微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
11.未收到支付通知的情况,商户后台系统调用【查询订单API】。
12.商户确认订单已支付后给用户发货。

1.3 微信支付SDK

微信支付提供了SDK, 大家下载后打开源码,install到本地仓库。

使用微信支付SDK,在maven工程中引入依赖

<!--微信支付-->
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
</dependency>

我们主要会用到微信支付SDK的以下功能:

获取随机字符串

WXPayUtil.generateNonceStr()

MAP转换为XML字符串(自动添加签名)

 WXPayUtil.generateSignedXml(param, partnerkey)

XML字符串转换为MAP

WXPayUtil.xmlToMap(result)

为了方便微信支付开发,我们可以在shop-common工程下引入依赖

<!--微信支付-->
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
</dependency>

1.4 HttpClient工具类

HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

HttpClient通俗的讲就是模拟了浏览器的行为,如果我们需要在后端向某一地址提交数据获取结果,就可以使用HttpClient.

关于HttpClient(原生)具体的使用不属于我们本章的学习内容,我们这里这里为了简化HttpClient的使用,提供了工具类HttpClient(对原生HttpClient进行了封装)

HttpClient工具类代码:

public class HttpClient &#123;
    private String url;
    private Map<String, String> param;
    private int statusCode;
    private String content;
    private String xmlParam;
    private boolean isHttps;

    public boolean isHttps() &#123;
        return isHttps;
    &#125;

    public void setHttps(boolean isHttps) &#123;
        this.isHttps = isHttps;
    &#125;

    public String getXmlParam() &#123;
        return xmlParam;
    &#125;

    public void setXmlParam(String xmlParam) &#123;
        this.xmlParam = xmlParam;
    &#125;

    public HttpClient(String url, Map<String, String> param) &#123;
        this.url = url;
        this.param = param;
    &#125;

    public HttpClient(String url) &#123;
        this.url = url;
    &#125;

    public void setParameter(Map<String, String> map) &#123;
        param = map;
    &#125;

    public void addParameter(String key, String value) &#123;
        if (param == null)
            param = new HashMap<String, String>();
        param.put(key, value);
    &#125;

    public void post() throws ClientProtocolException, IOException &#123;
        HttpPost http = new HttpPost(url);
        setEntity(http);
        execute(http);
    &#125;

    public void put() throws ClientProtocolException, IOException &#123;
        HttpPut http = new HttpPut(url);
        setEntity(http);
        execute(http);
    &#125;

    public void get() throws ClientProtocolException, IOException &#123;
        if (param != null) &#123;
            StringBuilder url = new StringBuilder(this.url);
            boolean isFirst = true;
            for (String key : param.keySet()) &#123;
                if (isFirst) &#123;
                    url.append("?");
                &#125;else &#123;
                    url.append("&");
                &#125;
                url.append(key).append("=").append(param.get(key));
            &#125;
            this.url = url.toString();
        &#125;
        HttpGet http = new HttpGet(url);
        execute(http);
    &#125;

    /**
     * set http post,put param
     */
    private void setEntity(HttpEntityEnclosingRequestBase http) &#123;
        if (param != null) &#123;
            List<NameValuePair> nvps = new LinkedList<NameValuePair>();
            for (String key : param.keySet()) &#123;
                nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
            &#125;
            http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
        &#125;
        if (xmlParam != null) &#123;
            http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
        &#125;
    &#125;

    private void execute(HttpUriRequest http) throws ClientProtocolException,
            IOException &#123;
        CloseableHttpClient httpClient = null;
        try &#123;
            if (isHttps) &#123;
                SSLC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值