支付寶支付-手機瀏覽器H5支付


前言

支付寶支付—沙箱環境使用
支付寶支付-支付寶PC端掃碼支付
支付寶支付-手機瀏覽器H5支付本文
支付寶支付-當面付之掃碼支付

手機瀏覽器支付,用戶在安裝支付寶APP的情況下,調用手機網站支付接口默認會喚起支付寶錢包支付,接下來通過運行官方Demo進行測試。

Java支付項目實戰教程,包括支付寶,微信等支付方式,不看虧!

本文開發環境:IDEA + Tomcat8.5 + 支付寶沙箱環境

補充:調用沙箱環境接口,需要安裝沙箱環境下的支付寶APP,不了解的小伙伴可以參考上方 支付寶支付—沙箱環境使用

下載運行測試Demo

官方Demo下載鏈接:手機網站支付

下載后導入 IDEA 中后需要調整的參數如下:

AlipayConfig.java

public class AlipayConfig {
    // 商戶appid
    public static String APPID = "2016101700705301";
    // 私鑰 pkcs8格式的
    public static String RSA_PRIVATE_KEY = "";
    // 服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
    public static String notify_url = "http://ngrok.sscai.club/alipay_trade_wap_pay_java_utf_8_war_exploded/notify_url.jsp";
    // 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址
    public static String return_url = "http://ngrok.sscai.club/alipay_trade_wap_pay_java_utf_8_war_exploded/return_url.jsp";
    // 請求網關地址
    public static String URL = "https://openapi.alipaydev.com/gateway.do";
    // 編碼
    public static String CHARSET = "UTF-8";
    // 返回格式
    public static String FORMAT = "json";
    // 支付寶公鑰
    public static String ALIPAY_PUBLIC_KEY = "";
    // 日志記錄目錄
    public static String log_path = "/log";
    // RSA2
    public static String SIGNTYPE = "RSA2";
}

幾個主要的參數:

  1. APPID :商戶appid
  2. RSA_PRIVATE_KEY:應用私鑰
  3. ALIPAY_PUBLIC_KEY:支付寶公鑰「注意不是應用公鑰」

這幾個參數不清楚的,可以看一下 沙箱環境使用,或者看一下官方文檔參數說明

項目啟動后如下圖所示:

Maven項目中的使用

Maven中的使用其實跟上篇 支付寶支付-支付寶PC端掃碼支付 代碼非常的像,換湯不換葯,改幾個參數,具體如下:

pom.xml中引入支付寶SDK依賴

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>3.1.0</version>
</dependency>

配置可以單獨創建一個類,靜態初始化參數:

public class AlipayConfig {

    // [沙箱環境]應用ID,您的APPID,收款賬號既是您的APPID對應支付寶賬號
    public static String app_id = "";

    // [沙箱環境]商戶私鑰,您的PKCS8格式RSA2私鑰
    public static String merchant_private_key = "";

    // [沙箱環境]支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應APPID下的支付寶公鑰。
    public static String alipay_public_key = "";

    // [沙箱環境]服務器異步通知頁面路徑  需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
    public static String notify_url = "http://ngrok.sscai.club/alipay/aliPayNotify_url";

    // [沙箱環境]頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
    public static String return_url = "http://ngrok.sscai.club/index.html#/alipay/success";

    // [沙箱環境]
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
}

至於接口啥的基本就是可以參考上方運行的Demo了。

簡單看看生成支付寶訂單接口「沒有使用開源SDK」。

@Transactional
public String alipayOrder(AlipayOrderRequest alipayOrderRequest) throws AlipayApiException {

    //獲得初始化的AlipayClient
    AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,
            AlipayConfig.app_id,
            AlipayConfig.merchant_private_key,
            "json",
            AlipayConfig.charset,
            AlipayConfig.alipay_public_key,
            AlipayConfig.sign_type);

    //設置請求參數
    String payType = alipayOrderRequest.getPayType();

    // wap
    AlipayTradeWapPayRequest alipayWapRequest = new AlipayTradeWapPayRequest();
    alipayWapRequest.setReturnUrl(AlipayConfig.return_url);
    alipayWapRequest.setNotifyUrl(AlipayConfig.notify_url);

    //商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
    String out_trade_no = alipayOrderRequest.getWidOutTradeNo();
    //付款金額,必填
    String total_amount = alipayOrderRequest.getWidTotalFee();
    //訂單名稱,必填
    String subject = alipayOrderRequest.getWidSubject();
    //商品描述,可空
    String body = alipayOrderRequest.getWIDbody();

    //拼接參數
    alipayWapRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        + "\"total_amount\":\""+ total_amount +"\","
        + "\"subject\":\""+ subject +"\","
        + "\"body\":\""+ body +"\","
        + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

    // 發起請求
    return alipayClient.pageExecute( alipayWapRequest).getBody();
}

手機網站支付接口調用后返回的也是一個 Form 表單,也就是 result 實際是一段 Html 代碼,然后把 result 傳給前段調用即可,下面是返回的 Form 的一個示例:

  <form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=UTF-8&method=alipay.trade.wap.pay&sign=xx&return_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Freturn_url.jsp&notify_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Fnotify_url.jsp&version=1.0&app_id=2016101700705301&sign_type=RSA2&timestamp=2020-01-08+14%3A09%3A58&alipay_sdk=alipay-sdk-java-3.3.0&format=json"> 
   <input type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;購買測試商品0.01元&quot;,&quot;out_trade_no&quot;:&quot;20201814955421&quot;,&quot;product_code&quot;:&quot;QUICK_WAP_WAY&quot;,&quot;subject&quot;:&quot;手機網站支付測試商品&quot;,&quot;timeout_express&quot;:&quot;2m&quot;,&quot;total_amount&quot;:&quot;0.01&quot;}" /> 
   <input type="submit" value="立即支付" style="display:none" /> 
  </form>

怎么調用呢?下面是一段我在vue中的測試代碼片段,前段接收到后端返回的 Form 表單進行提交:

const div = document.createElement('div');
console.log("我是后端返回的數據:"+res.result)
div.innerHTML = res.result;
document.body.appendChild(div);
console.log("punchout_form:"+document.forms.punchout_form)
document.forms.punchout_form.submit();

支付成功后會自動重定向到配置的跳轉界面,由后端的的 return_url 參數控制。
再看看支付成功后的回調接口「沒有使用開源的SDK演示」:

public String alipaynotify(Model model, HttpServletRequest request) {

    log.info("支付寶異步回調 ------------beg-----------");
    String result = "fail";
    //獲取支付寶POST過來反饋信息
    /* *
     * 功能:支付寶服務器異步通知頁面
     * 說明:
     * 以下代碼只是為了方便商戶測試而提供的樣例代碼,商戶可以根據自己網站的需要,按照技術文檔編寫,並非一定要使用該代碼。
     * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。
     */
    Map<String, String> params=this.getAlipayRequest(request);
    if(params == null || params.size()==0){
        BufferedReader bufferReader = null;
        StringBuilder sb = new StringBuilder();
        try {
            bufferReader = new BufferedReader(request.getReader());

            String line = null;
            while ((line = bufferReader.readLine()) != null) {
                sb.append(new String(line.getBytes("ISO-8859-1"), "utf-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String body= null;
        try {
            body = URLDecoder.decode(sb.toString(),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        params=UriComponentsBuilder.newInstance().query(body).build().getQueryParams().toSingleValueMap();
    }
    boolean signVerified =false;
    try {
        signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
    } catch (AlipayApiException e1) {
        // TODO Auto-generated catch block
        log.error("由於"+e1.getErrMsg()+"返回給支付寶系統的結果result:fail");
        model.addAttribute("result", "fail");
        return result;
    } //調用SDK驗證簽名

    //——請在這里編寫您的程序(以下代碼僅作參考)——

        /* 實際驗證過程建議商戶務必添加以下校驗:
        1、需要驗證該通知數據中的out_trade_no是否為商戶系統中創建的訂單號,
        2、判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額),
        3、校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email)
        4、驗證app_id是否為該商戶本身。
        */
    log.error("支付寶驗證簽名:---------------------------------"+signVerified);
    if(signVerified) {//驗證成功
        //商戶訂單號
        //交易狀態
        log.info("支付寶異步回調驗簽成功!");
        String trade_status = params.get("trade_status");

        if("TRADE_FINISHED".equals(trade_status)){
            //判斷該筆訂單是否在商戶網站中已經做過處理
            //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序
            //如果有做過處理,不執行商戶的業務程序

            //注意:
            //退款日期超過可退款期限后(如三個月可退款),支付寶系統發送該交易狀態通知
            try {
                // 在這里處理支付成功后的操作,比如修改訂單狀態等等
                coding...
                result = "success";
            } catch (Exception e) {
                log.error(e.getMessage());
                result = "fail";
            }
        }else if ("TRADE_SUCCESS".equals(trade_status)){
            //判斷該筆訂單是否在商戶網站中已經做過處理
            //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序
            //如果有做過處理,不執行商戶的業務程序

            //注意:
            //付款完成后,支付寶系統發送該交易狀態通知
            try {
                // 在這里處理支付成功后的操作,比如修改訂單狀態等等
                coding...
                result = "success";
            } catch (Exception e) {
                log.error(e.getMessage());
                result = "fail";
            }
        }else{
            result = "fail";
        }
    }else {//驗證失敗
        result = "fail";
        //調試用,寫文本函數記錄程序運行情況是否正常
        //String sWord = AlipaySignature.getSignCheckContentV1(params);
        //AlipayConfig.logResult(sWord);
        log.debug("支付寶異步回調驗簽失敗");
    }
    log.debug("異步回調返回給支付寶系統的結果result:"+result);

    model.addAttribute("result", result);
    log.info("支付寶異步回調  -------------end ------------");
    return result;
}

該方法返回給支付寶的 resultsuccessfail 兩個結果。
從以上看來,其實不難發現支付寶支付是非常簡單的,盡管我上邊貼了大量的代碼,其實采用開源SDK的話可以更加縮減、美化一些,如下是支付成功的截圖。

ok,這篇文章就到這結束了,上邊並沒有詳細介紹接口調用、參數說明等,詳細介紹請移步官方文檔:https://docs.open.alipay.com/60/104790/

本文源碼下載

可運行的官方手機網站支付Demohttps://www.lanzous.com/i8oe2sb

求關注,求推薦

博客地址:https://www.cnblogs.com/niceyoo

求關注❤️,求推薦👍,如果覺得這篇文章有點東西,不妨左上角關注一下我。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM