支付寶沙箱服務 (結合springboot實現,這裡對接的是easy版本,工具用的是IDEA,WebStrom)

来源:https://www.cnblogs.com/zsbb/archive/2022/09/29/16742733.html
-Advertisement-
Play Games

一:打開支付寶開發平臺,登錄,然後點擊控制台 https://open.alipay.com/ 二:滾動到底部,選著沙箱服務 三:獲取到對接要用的appId和公鑰私鑰 四:打開IDEA導入所需的xml文件 <!-- 支付寶--> <!-- https://mvnrepository.com/arti ...


一:打開支付寶開發平臺,登錄,然後點擊控制台

https://open.alipay.com/

 

 

 

二:滾動到底部,選著沙箱服務

 

 

 

三:獲取到對接要用的appId和公鑰私鑰

 

 

 

 

四:打開IDEA導入所需的xml文件

<!--        支付寶-->
        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-easysdk</artifactId>
            <version>2.2.0</version>
        </dependency>

 

五:編寫實體類:

import lombok.Data;

@Data
public class Alipay {
    private String traceNo;
    private String totalAmount;
    private String subject;
    private String alipayTraceNo;
}

 

六:編寫yaml文件(這裡的回調要用網路https服務,這裡建議使用花生殼可以完成功能變數名稱訪問!)

  #支付寶配置
alipay:
  appId: ?
  #私鑰
  appPrivateKey: ?
  #公鑰
  alipayPublicKey: ?
  #回調地址
  notifyUrl: ?

 

七:編寫服務類:

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AplipayConfig {
    private String appId;
    private String appPrivateKey;
    private String alipayPublicKey;
    private String notifyUrl;


    @PostConstruct
    public void init() {
        // 設置參數(全局只需設置一次)
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipaydev.com";
        config.signType = "RSA2";
        config.appId = this.appId;
        config.merchantPrivateKey = this.appPrivateKey;
        config.alipayPublicKey = this.alipayPublicKey;
        config.notifyUrl = this.notifyUrl;
        Factory.setOptions(config);
        System.out.println("=======支付寶SDK初始化成功=======");
    }

}

 

八:編寫控制器(寫完控制器建議直接測試訪問看看可不可以訪問的到,鏈接在第九步)

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.rookie.sixthbackstage.entity.Alipay;
import com.rookie.sixthbackstage.entity.OrderItem;
import com.rookie.sixthbackstage.mapper.OrderItemMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/alipay")
public class AliPayController {

    @Autowired
    OrderItemMapper orderItemMapper;

    @GetMapping("/alipay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public String pay(Alipay aliPay) {
        AlipayTradePagePayResponse response;
        try {
            //  發起API調用(以創建當面付收款二維碼為例)
            response = Factory.Payment.Page()
                    .pay(URLEncoder.encode(aliPay.getSubject(), "UTF-8"), aliPay.getTraceNo(), aliPay.getTotalAmount(), "《這裡放支付成功的地址!》");
        } catch (Exception e) {
            System.err.println("調用遭遇異常,原因:" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getBody();
    }

    @PostMapping("/notify")  // 註意這裡必須是POST介面
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付寶非同步回調========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            int tradeNo = Integer.parseInt(params.get("out_trade_no"));
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            double pay_price= Double.parseDouble(params.get("buyer_pay_amount"));
            // 支付寶驗簽
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 驗簽通過
                System.out.println("交易名稱: " + params.get("subject"));
                System.out.println("交易狀態: " + params.get("trade_status"));
                System.out.println("支付寶交易憑證號: " + params.get("trade_no"));
                System.out.println("商戶訂單號: " + params.get("out_trade_no"));
                System.out.println("交易金額: " + params.get("total_amount"));
                System.out.println("買家在支付寶唯一id: " + params.get("buyer_id"));
                System.out.println("買家付款時間: " + params.get("gmt_payment"));
                System.out.println("買家付款金額: " + params.get("buyer_pay_amount"));

                // 支付成功後,修改自己的訂單狀態,這裡的方法是我自己寫的,根據自己實際情況來做更改
                OrderItem orderItem=new OrderItem(0,tradeNo,0,pay_price,gmtPayment,"","已支付");
                orderItemMapper.updateOrderItemById(orderItem);
            }
        }
        return "success";
    }
}

 

九:前端測試

 //http://localhost:8089/alipay/alipay?subject=asdflas&traceNo=123123&totalAmount=29999//鏈接,複製到瀏覽器試試看可不可以打開支付寶的頁面
 //http://localhost:8089/alipay/alipay/asdflas/123123/29999//傳數據,名稱,訂單號,價格,更多參數請參考官網的文檔!
//結賬按鈕綁定的方法 
gopay() { var url = localhost + "/alipay/alipay?subject=" + subject + "
&traceNo=" + traceNo + "&totalAmount=" + totalAmount; location.href = url; },

 

十:結果

 

十一:想要掃碼支付的要下載沙箱的支付寶,賬號密碼的話在沙箱賬號里,也是沙箱支付寶的登錄賬號!

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、項目優化 1.去掉列印console 需求:在開發環境中,保留列印console;在生產上線環境,自動去掉列印console 使用步驟: 第一步:在項目根目錄下,創建如下圖兩個配置文件 在.env.development中(開發環境變數) NODE_ENV=development 在.env.p ...
  • 裝飾器模式(Decorator Design Pattern)是一種結構型設計模式,通過將對象放入包含行為的特殊封裝對象中來為原對象綁定新的行為。簡單地說,就是允許向一個現有的功能添加新的功能,同時又不改變其結構。 ...
  • 介面 interface 介面就是一組規範(就像我們法律一樣),所有實現類都要遵守。 面向對象的精髓,最能體現這一點的就是介面。為什麼我們討論設計模式都只針對具備了抽象能力的語言(比如 C++、Java、C#等),就是因為設計模式所研究的,實際上就是如何合理的去抽象。 介面的作用 為什麼需要介面?接 ...
  • ##示例代碼 public class ArrayListSource { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); //跳轉至第一步 for (int i = 0; i < 10; ...
  • Java反射03 3.通過反射獲取類的結構信息 3.1java.lang.Class類 getName:獲取全類名 getSimpleName:獲取簡單類名 getFields:獲取所有public修飾的屬性,包含本類以及父類的 getDeclaredFields:獲取本類中所有屬性 getMeth ...
  • #(1)amax(),amin() 作用:計算數組中的元素沿指定軸的最大值,最小值 import numpy as np x = np.random.randint(1,11,9).reshape((3,3)) print(x) #output: [[ 9 1 2] [ 5 2 6] [10 10 ...
  • 國慶假期快到了,想查查還有幾天幾小時到假期,這對程式員小菜一碟,輕輕鬆松用python寫個倒計時程式(天、時、分、秒),助你熬到假期! 一、先看效果: 二、安裝python: 1、下載安裝python 下載安裝python3.9.6,進入python官方網站://www.python.org/ 點擊 ...
  • 抽象方法和抽象類 抽象方法 使用 abstract 修飾的方法,沒有方法體,只有聲明。 定義的是一種“規範”,就是告訴子類必須要給抽象方法提供具體的實現。 抽象類 包含抽象方法的類就是抽象類。 通過抽象類,我們就可以做到嚴格限制子類的設計,使子類之間更加通用。 //抽象類的定義 public abs ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...