欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot?對接支付寶實(shí)現(xiàn)掃碼支付功能

 更新時(shí)間:2025年03月03日 11:06:42   作者:專注寫bug  
本文介紹了如何在Spring?Boot項(xiàng)目中實(shí)現(xiàn)支付寶支付功能,包括沙箱環(huán)境配置、依賴引入、配置參數(shù)、訂單類定義、測試接口編寫等步驟,通過不同場景下的請求方式(PC端、二維碼、回調(diào)處理、定時(shí)查詢支付結(jié)果),展示了如何與支付寶API進(jìn)行交互,感興趣的朋友一起看看吧

前言

最近項(xiàng)目中需要對接支付模塊,需要考慮到微信支付與支付寶支付的實(shí)現(xiàn)。

由于微信支付的還在審核中,先預(yù)研demo做一個(gè)支付寶支付碼獲取的實(shí)現(xiàn)。

官方文檔以及說明

本次開發(fā)環(huán)境中編寫demo實(shí)現(xiàn),采用的是支付寶的沙箱方式,后續(xù)上線會重新申請正式的appid等信息。

支付寶開發(fā)平臺鏈接:https://open.alipay.com/

1、申請沙箱

進(jìn)入支付寶的開發(fā)平臺,用支付寶登錄后,在控制臺面板中找到沙箱,并創(chuàng)建第一個(gè)沙箱。

https://open.alipay.com/develop/manage

2、進(jìn)入沙箱獲取對應(yīng)的關(guān)鍵信息

對于像授權(quán)回調(diào)地址、應(yīng)用網(wǎng)關(guān)地址這些暫時(shí)不設(shè)置。

3、拿到系統(tǒng)生成的公鑰和密鑰

這里會有應(yīng)用公鑰、支付寶公鑰應(yīng)用私鑰。但這里通過個(gè)人實(shí)踐,只需要支付寶公鑰應(yīng)用私鑰

應(yīng)用公鑰在某些特定的場景中并不會生效還會出現(xiàn)各種奇怪的報(bào)錯。

注意事項(xiàng)

沙箱并不是所有的操作都能夠在其中進(jìn)行開發(fā)操作,詳情參考官方文檔說明。

https://opendocs.alipay.com/common/097jyi?pathHash=9fcbe0d0&highlight_field=%E6%B2%99%E7%AE%B1%E7%8E%AF%E5%A2%83

創(chuàng)建springboot項(xiàng)目

1、引入依賴

選用的是springboot 2.x 的版本,并且引用的依賴在官方文檔中有版本說明。

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.34.47.ALL</version>
</dependency>
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-easysdk</artifactId>
    <version>2.0.0</version>
</dependency>

參考官方文檔依賴版本規(guī)定:

https://opendocs.alipay.com/common/02n6z6?pathHash=f5e2a056

其中,針對通用版的版本要求,官方文檔中有做說明:

https://opendocs.alipay.com/common/02kkv2?pathHash=358ff034

2、配置連接參數(shù)

src/main/resources中新建一個(gè)application.yml文件,如果是nacos項(xiàng)目,可以在對應(yīng)的配置中心中新增配置項(xiàng)。

# 支付寶支付
alipay:
    # 應(yīng)用ID,標(biāo)識你的應(yīng)用
    appId: 
    # 應(yīng)用私鑰,用于簽名請求
    appPrivateKey:
    # 應(yīng)用公鑰,用于驗(yàn)證支付寶的響應(yīng)
    #alipayPublicKey: 沙箱頁面中的應(yīng)用公鑰
    # 支付寶公鑰(推薦使用這個(gè))
    alipayPublicKey: 支付寶公鑰
    # 支付通知的回調(diào)地址,支付寶會在支付完成后通知這個(gè)地址
    notifyUrl: 支付成功后的回調(diào)地址,必須要求公網(wǎng)能夠訪問
    # 頁面跳轉(zhuǎn)地址,支付完成后跳轉(zhuǎn)到此URL
    returnUrl: 場景一中登錄成功后的重定向頁面
    # 簽名類型,通常為RSA2
    signType: RSA2
    # 字符編碼,通常為utf-8
    charset: utf-8
    # 支付寶網(wǎng)關(guān)地址,用于發(fā)送請求
    gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do

3、創(chuàng)建配置類,用于接收這些參數(shù)

package cn.alipay.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * 支付寶 支付參數(shù)配置類
 */
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {
    /**
     * APPID
     */
    private String appId;
    /**
     * 應(yīng)用私鑰,就是工具生成的應(yīng)用私鑰
     */
    public String appPrivateKey;
    /**
     * 支付寶公鑰,對應(yīng)APPID下的支付寶公鑰
     */
    public String alipayPublicKey;
    /**
     * 支付寶會悄悄的給我們發(fā)送一個(gè)請求,告訴我們支付成功的信息
     */
    public String notifyUrl;
    /**
     * 同步通知,支付成功,一般跳轉(zhuǎn)到成功頁
     */
    public String returnUrl;
    /**
     * 簽名方式
     */
    private String signType;
    /**
     * 字符編碼格式
     */
    private String charset;
    /**
     * 支付寶網(wǎng)關(guān);https://openapi-sandbox.dl.alipaydev.com/gateway.do
     */
    public String gatewayUrl;
    /**
     * 訂單超時(shí)時(shí)間
     */
    private String timeout = "5m";
}

新建配置類,獲取對應(yīng)的配置參數(shù),并構(gòu)建連接對象

package cn.alipay.config;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
 * 支付寶支付 模板
 */
@Slf4j
@Data
@Component
public class AliPayTemplate {
    @Autowired
    private AlipayProperties alipayProperties;
    private AlipayClient alipayClient;
    @PostConstruct
    public void init() {
        log.info("APPID:" + alipayProperties.getAppId());
        log.info("應(yīng)用私鑰:" + alipayProperties.getAppPrivateKey());
        log.info("支付寶公鑰:" + alipayProperties.getAlipayPublicKey());
        log.info("支付寶會悄悄的給我們發(fā)送一個(gè)請求,告訴我們支付成功的信息:" + alipayProperties.getNotifyUrl());
        log.info("同步通知,支付成功,一般跳轉(zhuǎn)到成功頁:" + alipayProperties.getReturnUrl());
        log.info("簽名方式:" + alipayProperties.getSignType());
        log.info("字符編碼格式:" + alipayProperties.getCharset());
        log.info("訂單超時(shí)時(shí)間:" + alipayProperties.getTimeout());
        log.info("支付寶網(wǎng)關(guān):" + alipayProperties.getGatewayUrl());
        // 1. 根據(jù)支付寶的配置生成一個(gè)支付客戶端
        alipayClient = new DefaultAlipayClient(
                alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                "json",
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType()
        );
    }
}

4、中間類的定義(訂單類)

創(chuàng)建一個(gè)訂單類,主要用于一些基本信息的傳參處理。

package cn.alipay.config;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * 訂單表
 */
@Data
public class Order implements Serializable {
    /**
     * 訂單Id
     */
    private Long id;
    /**
     * 用戶Id
     */
    private Long userId;
    /**
     * 接口Id
     */
    private Long interfaceInfoId;
    /**
     * 支付金額
     */
    private Double money;
    /**
     * 支付方式
     */
    private String paymentMethod;
    /**
     * 0 - 未支付 1 - 已支付
     */
    private Integer status;
    /**
     * 創(chuàng)建時(shí)間
     */
    private Date createTime;
    /**
     * 更新時(shí)間
     */
    private Date updateTime;
    /**
     * 是否刪除
     */
    private Integer isDelete;
    private static final long serialVersionUID = 1L;
}

5、編寫測試接口

場景一、pc端請求后端后,生成支付寶的特制頁面(AlipayTradePagePayRequest)

在支付寶的PC端案例文檔中,有一個(gè)注意事項(xiàng)。

https://opendocs.alipay.com/open/00dn7o?pathHash=c1e36251

像這種傳遞訂單信息至后臺,后臺調(diào)用支付寶的對應(yīng)接口后,返回前端頁面樣式或者地址,前端再進(jìn)行渲染實(shí)現(xiàn)。可以參照以下的方式。

定義接口

package cn.alipay.controller;
import cn.alipay.config.AliPayTemplate;
import cn.alipay.config.Order;
import com.alipay.api.AlipayApiException;
import com.alipay.easysdk.factory.Factory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
 * 阿里支付寶支付與回調(diào)接口
 */
@Slf4j
@RestController
@RequestMapping("/alipay")
public class AliPayController {
    @Autowired
    private AliPayTemplate aliPayTemplate;
    /**
     * 獲取支付寶
     * post 請求 生成 frame 頁面
     * get 請求生成 頁面url
     * @param id
     * @return
     * @throws AlipayApiException
     */
    @GetMapping(value = "/pay", produces = MimeTypeUtils.TEXT_HTML_VALUE)
    @ResponseBody
    public String pay(@RequestParam long id) throws AlipayApiException {
        // 創(chuàng)建訂單對象并設(shè)置屬性
        Order order = createOrder(id);
        // 調(diào)用支付寶支付模板進(jìn)行支付
        return aliPayTemplate.pay(order);
    }
    /**
     * 偽造訂單數(shù)據(jù)
     * @param id
     * @return
     */
    private Order createOrder(long id) {
        Order order = new Order();
        order.setId(id);  
        order.setUserId(1111111L);  
        order.setInterfaceInfoId(294389472934L); 
        order.setMoney(1000.0);  
        order.setPaymentMethod("支付寶"); 
        return order;
    }
}

定義請求邏輯代碼

package cn.alipay.config;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
 * 支付寶支付 模板
 */
@Slf4j
@Data
@Component
public class AliPayTemplate {
    @Autowired
    private AlipayProperties alipayProperties;
    private AlipayClient alipayClient;
    @PostConstruct
    public void init() {
        log.info("APPID:" + alipayProperties.getAppId());
        log.info("應(yīng)用私鑰:" + alipayProperties.getAppPrivateKey());
        log.info("支付寶公鑰:" + alipayProperties.getAlipayPublicKey());
        log.info("支付寶會悄悄的給我們發(fā)送一個(gè)請求,告訴我們支付成功的信息:" + alipayProperties.getNotifyUrl());
        log.info("同步通知,支付成功,一般跳轉(zhuǎn)到成功頁:" + alipayProperties.getReturnUrl());
        log.info("簽名方式:" + alipayProperties.getSignType());
        log.info("字符編碼格式:" + alipayProperties.getCharset());
        log.info("訂單超時(shí)時(shí)間:" + alipayProperties.getTimeout());
        log.info("支付寶網(wǎng)關(guān):" + alipayProperties.getGatewayUrl());
        // 1. 根據(jù)支付寶的配置生成一個(gè)支付客戶端
        alipayClient = new DefaultAlipayClient(
                alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                "json",
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType()
        );
    }
    /**
     * 調(diào)用支付接口
     * @param order
     * @return
     * @throws AlipayApiException
     */
    public String pay(Order order) throws AlipayApiException {
        //2、創(chuàng)建一個(gè)支付請求,并設(shè)置請求參數(shù)
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayProperties.getReturnUrl());
        alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
        Long id = order.getId();
        Long interfaceInfoId = order.getInterfaceInfoId();
        Double money = order.getMoney();
        String paymentMethod = order.getPaymentMethod();
        // 設(shè)置業(yè)務(wù)內(nèi)容,包含必要的支付參數(shù)
        AlipayTradePagePayModel pagePayModel = new AlipayTradePagePayModel();
        pagePayModel.setOutTradeNo(String.valueOf(id));
        pagePayModel.setTotalAmount(String.valueOf(money));
        pagePayModel.setSubject(String.valueOf(interfaceInfoId));
        pagePayModel.setBody(paymentMethod);
        pagePayModel.setTimeoutExpress(alipayProperties.getTimeout());
        // 電腦支付場景下僅支持FAST_INSTANT_TRADE_PAY
        pagePayModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizModel(pagePayModel);
		// post 請求返回 frame 前端樣式
        AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest, "POST");
        // get 請求返回一個(gè)頁面地址url
        AlipayTradePagePayResponse response2 = alipayClient.pageExecute(alipayRequest, "GET");
        String result = response.getBody();
        //返回支付寶響應(yīng)的結(jié)果
        return result;
    }
}

啟動服務(wù),請求后的效果如下:

localhost:8080/alipay/pay?id=123456

post 請求生成的樣式如下所示:

<form  name="punchout_form" method="post" action="會有對應(yīng)的信息">
    <input  type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;支付寶&quot;,&quot;out_trade_no&quot;:&quot;125477&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;,&quot;subject&quot;:&quot;294389472934&quot;,&quot;timeout_express&quot;:&quot;5m&quot;,&quot;total_amount&quot;:&quot;1000.0&quot;}">
        <input  type="submit" value="立即支付" style="display:none" >
        </form>
        <script>document.forms[0].submit();</script>

如果是GET請求,則只會是上面action的地址。

場景二、前端請求后端,只返回對應(yīng)的二維碼地址(AlipayTradePrecreateRequest)

參照官方文檔中的案例實(shí)現(xiàn)

https://opendocs.alipay.com/open/8ad49e4a_alipay.trade.precreate?scene=2ae8516856f24a5592194d237f3f235d&pathHash=d18bff53

編寫對應(yīng)的接口和實(shí)現(xiàn)類

@GetMapping(value = "/pay3")
@ResponseBody
public String pay3(@RequestParam long id) throws AlipayApiException {
    // 創(chuàng)建訂單對象并設(shè)置屬性
    Order order = createOrder(id);
    // 調(diào)用支付寶支付模板進(jìn)行支付
    return aliPayTemplate.pay3(order);
}
package cn.alipay.config;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
 * 支付寶支付 模板
 */
@Slf4j
@Data
@Component
public class AliPayTemplate {
    @Autowired
    private AlipayProperties alipayProperties;
    private AlipayClient alipayClient;
    @PostConstruct
    public void init() {
        log.info("APPID:" + alipayProperties.getAppId());
        log.info("應(yīng)用私鑰:" + alipayProperties.getAppPrivateKey());
        log.info("支付寶公鑰:" + alipayProperties.getAlipayPublicKey());
        log.info("支付寶會悄悄的給我們發(fā)送一個(gè)請求,告訴我們支付成功的信息:" + alipayProperties.getNotifyUrl());
        log.info("同步通知,支付成功,一般跳轉(zhuǎn)到成功頁:" + alipayProperties.getReturnUrl());
        log.info("簽名方式:" + alipayProperties.getSignType());
        log.info("字符編碼格式:" + alipayProperties.getCharset());
        log.info("訂單超時(shí)時(shí)間:" + alipayProperties.getTimeout());
        log.info("支付寶網(wǎng)關(guān):" + alipayProperties.getGatewayUrl());
        // 1. 根據(jù)支付寶的配置生成一個(gè)支付客戶端
        alipayClient = new DefaultAlipayClient(
                alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                "json",
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType()
        );
    }
    public String pay3(Order order) throws AlipayApiException {
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();
        // 強(qiáng)制關(guān)閉 ssl 證書校驗(yàn)
        WebUtils.setNeedCheckServerTrusted(false);
        alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("out_trade_no",order.getId());// 商戶訂單號
        jsonObject.put("total_amount",order.getMoney());// 商品價(jià)格
        jsonObject.put("subject","這只是個(gè)商品標(biāo)題");// 商品標(biāo)題
        jsonObject.put("store_id","香蕉集團(tuán)");//組織或公司名
//            jsonObject.put("timeout_express","5m");// 訂單有效時(shí)間
        alipayRequest.setBizContent(jsonObject.toString());
        AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);
        System.out.println("創(chuàng)建訂單結(jié)果:"+response.getBody());
        System.out.println("訂單編號是"+response.getOutTradeNo());
        String qrCode = response.getQrCode();
//            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        return qrCode;
    }
}

請求后會得到一個(gè)支付的地址,使用ZXing框架,將其轉(zhuǎn)換為二維碼。

場景三、沙箱APP掃碼支付后回調(diào)處理

在每次請求AliPay的接口時(shí),都會傳遞一個(gè)回調(diào)接口參數(shù)。

alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());

這個(gè)參數(shù)主要是用于告知AliPay在支付操作中,各項(xiàng)信息的回調(diào)信息,是個(gè)異步的操作。

針對回調(diào),判斷是否是支付成功,可以參照如下邏輯:

/**
 * 支付寶 支付 異步回調(diào)接口  必須是 Post
 * @param request
 * @return
 * @throws Exception
 */
@PostMapping("/notify")  
public String payNotify(HttpServletRequest request) throws Exception {
    // 檢查交易狀態(tài)是否為成功
    if (!"TRADE_SUCCESS".equalsIgnoreCase(request.getParameter("trade_status"))) {
        // 如果狀態(tài)不是成功,則返回失敗
        return "failure"; 
    }
    log.info("=========支付寶異步回調(diào)========");
    // .... 此處省略部分業(yè)務(wù)邏輯
    aliPayServide.payNotify(request);
    return "success";
}

業(yè)務(wù)層中的代碼片段如下:

public void payNotify(HttpServletRequest request) throws AlipayApiException {
    // 創(chuàng)建一個(gè)存儲請求參數(shù)的Map
    Map<String, String> params = getRequestParams(request);
    String tradeNo = params.get("out_trade_no");
    // 驗(yàn)證支付寶返回的簽名
    if (!verifySignature(params)) {
        log.info("----驗(yàn)簽失敗----");
       return;
    }
    // 記錄交易詳情
    logTransactionDetails(params);
    // 其他業(yè)務(wù)邏輯
}
/**
 * 記錄交易詳情的方法
 * @param params
 */
private void logTransactionDetails(Map<String, String> params) {
    log.info("交易名稱: " + params.get("subject"));
    log.info("交易狀態(tài): " + params.get("trade_status"));
    log.info("支付寶交易憑證號: " + params.get("trade_no"));
    log.info("商戶訂單號: " + params.get("out_trade_no"));
    log.info("交易金額: " + params.get("total_amount"));
    log.info("買家在支付寶唯一id: " + params.get("buyer_id"));
    log.info("買家付款時(shí)間: " + params.get("gmt_payment"));
    log.info("買家付款金額: " + params.get("buyer_pay_amount"));
    // 記錄日志
    ChatAliPayDetailLog chatAliPayDetailLog = ChatAliPayDetailLog.builder()
            .id(IdUtil.getSnowflakeNextIdStr())
            .subject(params.get("subject"))
            .tradeStatus(params.get("trade_status"))
            .tradeNo(params.get("trade_no"))
            .outTradeNo(params.get("out_trade_no"))
            .totalAmount(new BigDecimal(params.get("total_amount")))
            .buyerId(params.get("buyer_id"))
            .gmtPayment(DateUtil.parseDate(params.get("gmt_payment")))
            .buyerPayAmount(new BigDecimal(params.get("buyer_pay_amount")))
            .createdTime(new Date())
            .build();
    chatAliPayDetailLogMapper.insert(chatAliPayDetailLog);
}
/**
 * 驗(yàn)證簽名
 * @param params
 * @return
 */
private boolean verifySignature(Map<String, String> params) throws AlipayApiException {
    String sign = params.get("sign");
    String content = AlipaySignature.getSignCheckContentV1(params);
    return AlipaySignature.rsa256CheckContent(content, sign, alipayProperties.getAlipayPublicKey(), "UTF-8");
}
/**
 * 提取請求參數(shù)的方法
 * @param request
 * @return
 */
private Map<String, String> getRequestParams(HttpServletRequest request) {
    Map<String, String> params = new HashMap<>();
    Map<String, String[]> requestParams = request.getParameterMap();
    for (String name : requestParams.keySet()) {
        params.put(name, request.getParameter(name));
    }
    return params;
}

但回調(diào)處理是一個(gè)異步,如果前端界面中需要實(shí)時(shí)獲取支付成功狀態(tài),可以使用輪訓(xùn)的方式,定時(shí)去查詢支付結(jié)果。

場景四、定時(shí)查詢支付結(jié)果

在官方文檔中,其中提供有一個(gè)alipay.trade.query(統(tǒng)一收單交易查詢),專門提供查詢操作。

https://opendocs.alipay.com/open/217dd591_alipay.trade.query?scene=common&pathHash=62ae74aa

代碼片段如下所示:

AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(chatUserPayOrder.getOrderNo());
request.setBizModel(model);
try {
    AlipayTradeQueryResponse response = alipayClient.execute(request);
    if ("TRADE_SUCCESS".equalsIgnoreCase(response.getTradeStatus())) {
        // 成功支付  則進(jìn)行后續(xù)處理
        insertLog(response);
        // 根據(jù) response.getOutTradeNo() 修改對應(yīng)的支付信息
        updatePayOrderStatus(response);
    }
} catch (AlipayApiException e) {
    throw new RuntimeException(e);
}

也可以考慮定時(shí)任務(wù)xxl-job定時(shí)去獲取所有未收到支付狀態(tài)的數(shù)據(jù),請求獲取最終結(jié)果?;蛘叱^限定時(shí)間表示失效等邏輯。

到此這篇關(guān)于Springboot 對接支付寶實(shí)現(xiàn)掃碼支付的文章就介紹到這了,更多相關(guān)Springboot 掃碼支付內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論