自己個人擁有一個可以支付功能的網站?當然可以了!保姆級演示!

語言: CN / TW / HK
ead>

前提條件

這是必要條件!!! 這是必要條件!!! 這是必要條件!!! 開通當面付,個人、企業賬號均可!!!


演示

獲取訂單點選,然後掃碼支付 在這裡插入圖片描述

支付成功後就會響應支付成功 在這裡插入圖片描述

應用申請開通和配置

接下來介紹應用的建立和配置,一定要仔細哦!!!

應用建立

首先進入支付寶開放平臺,進入控制檯,建立一個應用,大概1個工作日內就會稽核 在這裡插入圖片描述

把這幾個必填項填寫,然後確認建立,注意名字要清晰,應用圖示要有一定的可識別性,不然不給過,應用型別選網頁應用

在這裡插入圖片描述

應用配置

建立好後,進入產品詳情頁面,點選產品繫結,然後去繫結 在這裡插入圖片描述

選擇支付 -> 當面付[勾選] -> 繫結,另外你還可以找到花唄支付,這樣使用者掃碼時就支援花唄支付了 在這裡插入圖片描述

要確認是開通狀態哦,如果沒有開通需要開通哦,看上面的 前提條件 在這裡插入圖片描述

然後需要配置金鑰,點選下圖中側邊欄中的 開發設定,需要配置的是 介面加簽方式(證書/金鑰)

  • 介面加簽方式(證書/金鑰):配置支付寶開放平臺會引導你下載安裝金鑰生成工具,生成一個應用公鑰和應用私鑰,私鑰一定要保管好,不要洩露,儲存到本地,到時候配置在伺服器上,然後把應用公鑰配置在開放平臺上,就算配置完成了,支付寶就會給到你一個支付寶公鑰,接下來你一共有三個金鑰,支付寶公鑰、應用公鑰、應用私鑰,這三個一定要分清,接下來文章介紹的所需要用到的金鑰只有這三個,清一定要分清!!!

在這裡插入圖片描述


程式碼開發

接下來你可以結合著官方的開發文件看我的文章,官方文件:https://opendocs.alipay.com/open/02ekfg?ref=api&scene=19 - 本文後端以Java的開發方式,僅供參考! - Web前端使用原生Html+CSS+JavaScript簡單實現,僅供參考! - 安卓呼叫可以參考我這篇文章:https://myhub.blog.csdn.net/article/details/128399771

後端例項

SDK整合

首先獲取相應的SDK,SDK下載頁面(官方):https://opendocs.alipay.com/open/54/103419

我這裡以Maven的方式整合,另外我集成了zxing,用於生成支付二維碼使用

```xml

com.alipay.sdk alipay-sdk-java 4.35.9.ALL

com.google.zxing core 3.5.1 ```

Controller例項

  • 生成付款二維碼,我標明瞭詳細的註釋,可以直接看!
  • 由於涉及到公鑰、私鑰等資訊,這些部分我都用了 **來表示,
  • 記得替換哦!!!
  • 記得替換哦!!!
  • 記得替換哦!!!
  • 替換成你自己的!!!

以下為簡單的Demo演示,一定要結合官方文件,閱讀接入注意事項:https://opendocs.alipay.com/open/194/105322

```java package com.demo.pay;

import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradePrecreateRequest; import com.alipay.api.request.AlipayTradeQueryRequest; import com.alipay.api.response.AlipayTradePrecreateResponse; import com.alipay.api.response.AlipayTradeQueryResponse; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.Map;

/* * @author ThirdGoddess * @version 1.0.0 * @time 2022/12/22 14:37 * @desc AliPay當面付Demo / @RestController @RequestMapping("pay") public class AliPayController {

//模擬一個使用者的支付狀態
private boolean userPayState = false;

//==================================================================================================================
//這裡都是固定的

//支付寶閘道器地址
private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";

//charset
private static final String CHARSET = "GBK";

//format
private static final String FORMAT = "json";

//sign type
private static final String SIGN_TYPE = "RSA2";

//==================================================================================================================
//下面這三個是需要配置的

//APPID,即建立應用的那個ID,在應用詳情中的左上角可以看到
private static final String APPID = "**************";

//應用私鑰,注意是應用私鑰!!!應用私鑰!!!應用私鑰!!!
private static final String APP_PRIVATE_KEY = "**************";

//支付寶公鑰,注意是支付寶公鑰!!!支付寶公鑰!!!支付寶公鑰!!!
private static final String ALIPAY_PUBLIC_KEY = "**************";

/**
 * 獲取二維碼
 * 獲取的是使用者要掃碼支付的二維碼
 * 建立訂單,帶入自己的業務邏輯
 */
@RequestMapping(value = "/getQr", produces = MediaType.IMAGE_JPEG_VALUE)
@ResponseBody
public byte[] getQr() {

    userPayState = false;

    AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
    AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

    //配置這是一個url,下圖我已經配置好了,這個意思是當用戶成功後,支付寶那邊會呼叫這個地址url,他會給你傳過去一些訂單資訊,
    //你處理完你的業務邏輯給支付寶響應success就行,就代表這個訂單完成交易了!
    //* 建議前期開發的時候加上內網穿透除錯,不然支付寶是沒有辦法調到你開發的介面的
    request.setNotifyUrl("http://**************.com/pay/payNotification");

    JSONObject bizContent = new JSONObject();

    //自己生成一個訂單號,我這裡直接用時間戳演示,正常情況下建立完訂單需要儲存到自己的業務資料庫,做記錄和支付完成後校驗
    String orderNumber = "pay" + System.currentTimeMillis();

    bizContent.put("out_trade_no", orderNumber);//訂單號
    bizContent.put("total_amount", 0.01);//訂單金額
    bizContent.put("subject", "demo");//支付主題,自己稍微定義一下
    request.setBizContent(bizContent.toString());

    try {
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("呼叫成功");
        } else {
            System.out.println("呼叫失敗");
        }

        //獲取生成的二維碼,這裡是一個String字串,即二維碼的內容;
        //然後用二維碼生成SDK生成一下二維碼,弄成圖片返回給前端就行,我這裡使用Zxing生成
        //其實也可以直接把這個字串資訊返回,讓前端去生成,一樣的道理,只需要關心這個二維碼的內容就行
        String qrCode = response.getQrCode();

        //生成支付二維碼圖片
        BufferedImage image = QrCodeUtil.createImage(qrCode);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(image, "jpeg", out);
        byte[] b = out.toByteArray();
        out.write(b);
        out.close();

        //最終返回圖片
        return b;
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("呼叫失敗");
    }
    return null;
}

/**
 * 支付完成後支付寶會請求這個回撥
 */
@PostMapping("payNotification")
public String payNotification(HttpServletRequest request) {
    Map<String, String> params = new HashMap<>();
    Map<String, String[]> requestParams = request.getParameterMap();
    for (String name : requestParams.keySet()) {
        String[] values = requestParams.get(name);
        String valueStr = "";
        for (int i = 0; i < values.length; i++) {
            valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
        }
        params.put(name, valueStr);
    }

    for (Map.Entry<String, String> entry : params.entrySet()) {
        System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
    }

    //==============================================================================================================
    try {
        //執行驗籤,確保結果是支付寶回撥的,而不是被惡意呼叫,一定要做這一步
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
        if (signVerified) {
            //驗籤成功,繼續執行業務邏輯
            System.out.println("驗籤成功");

            //再次主動查詢訂單,不要只依賴支付寶回撥的結果
            String orderStatus = searchOrderStatus(params.get("out_trade_no"), params.get("trade_no"));
            switch (orderStatus) {
                case "TRADE_SUCCESS"://交易支付成功;
                case "TRADE_FINISHED": //交易結束,不可退款;
                    //TODO 在這裡繼續執行使用者支付成功後的業務邏輯
                    userPayState = true;
                    break;
            }
            return "success";
        } else {
            //驗籤失敗(很可能介面被非法呼叫)
            System.out.println("驗籤失敗");
            return "fail";
        }
    } catch (AlipayApiException e) {
        e.printStackTrace();
        return "fail";
    }
}

/**
 * 封裝一個訂單查詢
 *
 * @param outTradeNo 商戶訂單號
 * @param tradeNo    支付寶交易號。支付寶交易憑證號
 * @return 訂單狀態:String
 * @throws AlipayApiException AlipayApiException
 * @desc "WAIT_BUYER_PAY":交易建立,等待買家付款;"TRADE_CLOSED":未付款交易超時關閉,或支付完成後全額退款; "TRADE_SUCCESS":交易支付成功;"TRADE_FINISHED":交易結束,不可退款;
 */
private String searchOrderStatus(String outTradeNo, String tradeNo) throws AlipayApiException {
    AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //獲得初始化的AlipayClient
    AlipayTradeQueryRequest aliRequest = new AlipayTradeQueryRequest();//建立API對應的request類
    JSONObject bizContent = new JSONObject();
    bizContent.put("out_trade_no", outTradeNo);
    bizContent.put("trade_no", tradeNo);
    aliRequest.setBizContent(bizContent.toString()); //設定業務引數
    AlipayTradeQueryResponse response = alipayClient.execute(aliRequest);//通過alipayClient呼叫API,獲得對應的response類
    JSONObject responseObject = JSONObject.parseObject(response.getBody());
    JSONObject alipayTradeQueryResponse = responseObject.getJSONObject("alipay_trade_query_response");
    return alipayTradeQueryResponse.getString("trade_status");
}

/**
 * 前端輪詢查詢這個介面,來查詢訂單的支付狀態
 *
 * @return OrderStateEntity
 */
@CrossOrigin
@GetMapping("searchOrder")
public OrderStateEntity searchOrder() {
    //userPayState是一個模擬值
    if (userPayState) {
        //使用者支付成功了
        return new OrderStateEntity(200, "支付成功了");
    } else {
        //使用者還沒有支付
        return new OrderStateEntity(201, "你還沒有支付哦");
    }
}

/**
 * 響應給前端的實體
 */
static class OrderStateEntity {
    private int code;
    private String msg;

    public OrderStateEntity(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

}

```

使用者支付後的回撥

當使用setNotifyUrl後,使用者成功支付後,會回撥其設定的url,如 ==setNotifyUrl("http://xxx.com/pay/payNotification")== ,那麼支付寶會等待使用者支付成功後會以POST去請求 ==http://xxx.com/pay/payNotification== 這個地址來達成回撥,需要響應success或者fail,只有這兩種值哦!

響應值 | 描述 | 非同步是否重試傳送 ------|-----|------- fail | 訊息獲取失敗 | 重試 success | 訊息獲取成功 | 不重試

前端程式碼例項

```html

支付寶當面付Demo演示

```


原始碼

Github:https://github.com/ThirdGoddess/aliPay