支付寶Wap支付你了解多少?

上幾篇文章詳細介紹了支付寶APP支付微信APP支付

此文章來介紹下支付寶Wap支付(也叫作手機網站支付)

目錄
1、創建應用并獲取APPID
2、配置應用環境
3、配置沙箱環境
4、服務端實現(Maven添加本地Jar包、集成并配置SDK)

先上官方文檔入口,支付寶文檔入口模仿微信最最近做了更新,變得更簡潔明了。

官方手機網站支付快速接入文檔

1、創建應用并獲取APPID

這個比較簡單可以參考《開放平臺應用創建指南》

2、配置應用環境

開發者調用接口前需要先生成RSA密鑰,RSA密鑰包含應用私鑰(APP_PRIVATE_KEY)、應用公鑰(APP_PUBLIC_KEY)。生成密鑰后在開放平臺管理中心進行密鑰配置,配置完成后可以獲取支付寶公鑰(ALIPAY_PUBLIC_KEY)。詳細步驟請參考《配置應用環境》

為了方便開發者生成一對RSA密鑰支付寶提供一鍵生成工具,具體如何生成與配置密鑰詳見簽名專區

WINDOWS
MAC_OSX

下載該工具后,解壓打開文件夾,運行“RSA簽名驗簽工具.bat”(WINDOWS)或“RSA簽名驗簽工具.command”(MAC_OSX)。

以下演示截圖

Window 配置應用環境生成相關Key截圖參考上篇文檔支付寶APP支付

以下是Mac電腦生成RSA密鑰工具截圖

Mac 生成RSA密鑰工具.png
生成密鑰.png

工具生成一對RSA密鑰之后將公鑰配置到應用環境。
生成的私鑰需妥善保管,避免遺失,不要泄露。應用私鑰需填寫到代碼中供簽名時使用。應用公鑰需提供給支付寶賬號管理者上傳到支付寶開放平臺。

上傳支付寶公鑰.png

3、配置沙箱環境

注意:沙箱環境的密鑰最好與正式上線的應用進行區分避免一些不必要的麻煩。WAP支付支持沙箱環境而app支付不支持沙箱環境

官方介紹質料-箱環境使用說明

上傳對應的公鑰,沙箱賬號待會在測試的時候回使用到

沙箱環境配置.png
沙箱工具.png

4、服務端實現(集成并配置SDK)

官方資源下載地址

服務端SDK下載與簡介
服務端SDK下載
服務端SDK
SDK包說明
Maven項目中使用本地JAR包

1、首先我在項目根目錄中創建一個lib文件夾,將jar包拷貝到lib文件夾下

添加jar包

2、然后我們在maven的pom.xml中配置

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>20161129201425</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/alipay-sdk-java20161129201425.jar</systemPath>
</dependency>

3、這里的groupId和artifactId以及version都是可以隨便填寫的 ,scope必須填寫為system,而systemPath我們現在我們jar包的地址就可以了

4、最后我們必須在maven打包的過程中加入我們這個jar包。因為項目運行的時候需要這個Jar,并且我們得拷貝在WEB-INF/lib目錄下

<groupId>org.apache.maven.plugins</groupId>  
<artifactId>maven-war-plugin</artifactId>  
<configuration>  
    <webResources>  
        <resource>  
            <directory>${project.basedir}/lib</directory>  
            <targetPath>WEB-INF/lib</targetPath>  
            <filtering>false</filtering>  
            <includes>  
                <include>**/*.jar</include>  
            </includes>  
        </resource>  
    </webResources>  
</configuration>  
<version>2.1.1</version>  

集成

在使用SDK調用具體API前,需要先配置通用接入參數

參數

1、APP_ID 使用沙箱模式中的APP_ID.
2、APP_PRIVATE_KEY ALIPAY_PUBLIC_KEY 使用文章2、配置應用環境中生成的測試密鑰.
3、CHARSET 默認使用UTF-8

然后,使用上述接入參數初始化AlipayClient:

AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",APP_ID,APP_PRIVATE_KEY,"json",CHARSET,ALIPAY_PUBLIC_KEY);

接下來,就可以用alipayClient來調用具體的API了。alipayClient只需要初始化一次,后續調用不同的API都可以使用同一個alipayClient對象。

手機網站支付不支持第三方授權,不能代商家發起請求。

調用接口

手機網站支付產品包含兩類API:
頁面跳轉類:需要從前端頁面以Form表單的形式發起請求,瀏覽器會自動跳轉至支付寶的相關頁面(一般是收銀臺或簽約頁面),用戶在該頁面完成相關業務操作后再回跳到商戶指定頁面。例如本產品中的手機網站支付接口alipay.trade.wap.pay

系統調用類:直接從服務端發起HTTP請求,支付寶會同步返回請求結果。例如本產品中的交易查詢等配套API。

調用流程圖
調用流程
使用說明
使用SDK快速接入

手機網站支付alipay.trade.wap.pay:
對于頁面跳轉類API,SDK不會也無法像系統調用類API一樣自動請求支付寶并獲得結果,而是在接受request請求對象后,為開發者生成前臺頁面請求需要的完整form表單的html(包含自動提交腳本),商戶直接將這個表單的String輸出到http response中即可。

public void doPost(HttpServletRequest httpRequest,
                      HttpServletResponse httpResponse) throws ServletException, IOException {
    AlipayClient alipayClient = ... //獲得初始化的AlipayClient
    AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//創建API對應的request
    alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");
    alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");//在公共參數中設置回跳和通知地址
    alipayRequest.setBizContent("{" +
        "    \"out_trade_no\":\"20150320010101002\"," +
        "    \"total_amount\":88.88," +
        "    \"subject\":\"Iphone6 16G\"," +
        "    \"seller_id\":\"2088123456789012\"," +
        "    \"product_code\":\"QUICK_WAP_PAY\"" +
        "  }");//填充業務參數
    String form = alipayClient.pageExecute(alipayRequest).getBody(); //調用SDK生成表單
    httpResponse.setContentType("text/html;charset=" + AlipayServiceEnvConstants.CHARSET);
    httpResponse.getWriter().write(form);//直接將完整的表單html輸出到頁面
    httpResponse.getWriter().flush();
}

異步通知驗簽
Map<String, String> paramsMap = ... //將異步通知中收到的所有參數都存放到map中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET) //調用SDK驗證簽名
if(signVerfied){
    // TODO 驗簽成功后,按照支付結果異步通知中的描述,對支付結果中的業務內容進行二次校驗,校驗成功后在response中返回success并繼續商戶自身業務處理,校驗失敗返回failure
}else{
    // TODO 驗簽失敗則記錄異常日志,并在response中返回failure.
}

服務端具體封裝

將參數獨立配置在一個屬性文件中方便管理,當然也可以從數據庫

沙盒環境配置參數

加載接入參數并初始化AlipayClient

加載接入參數并初始化`AlipayClient`

使用SDK快速接入代碼封裝


public void wapPay(){
        String body="我是測試數據";
        String subject="Iphone6 16G";
        String total_amount="0.01";
        String passback_params="1";
        
        BizContent content = new BizContent();
        content.setBody(body);
        content.setOut_trade_no(OrderInfoUtil2_0.getOutTradeNo());;
        content.setPassback_params(passback_params);
        content.setSubject(subject);
        content.setTotal_amount(total_amount);
        content.setProduct_code("QUICK_WAP_PAY");
        
        
        try {
            AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//創建API對應的request
            alipayRequest.setReturnUrl("http://javen.tunnel.qydev.com/alipay/return_url");
            alipayRequest.setNotifyUrl("http://javen.tunnel.qydev.com/alipay/notify_url");//在公共參數中設置回跳和通知地址
            //參數參考 https://doc.open.alipay.com/doc2/detail.htm?treeId=203&articleId=105463&docType=1#s0
            System.out.println(JsonKit.toJson(content));
            alipayRequest.setBizContent(JsonKit.toJson(content));//填充業務參數
                String form = alipayClient.pageExecute(alipayRequest).getBody(); //調用SDK生成表單
                HttpServletResponse httpResponse = getResponse();
                httpResponse.setContentType("text/html;charset=" + charset);
                httpResponse.getWriter().write(form);//直接將完整的表單html輸出到頁面
                httpResponse.getWriter().flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        renderNull();
    }
public void return_url() {
        try {
            // 獲取支付寶GET過來反饋信息
            Map<String, String> map = AliPayApi.toMap(getRequest());
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }

            boolean verify_result = AlipaySignature.rsaCheckV1(map, AliPayApi.ALIPAY_PUBLIC_KEY, AliPayApi.CHARSET,
                    AliPayApi.SIGN_TYPE);

            if (verify_result) {// 驗證成功
                // TODO 請在這里加上商戶的業務邏輯程序代碼
                System.out.println("return_url 驗證成功");
                renderText("success");
                return;
            } else {
                System.out.println("return_url 驗證失敗");
                // TODO
                renderText("failure");
                return;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            renderText("failure");
        }
    }
public void notify_url() {
        try {
            // 獲取支付寶POST過來反饋信息
            Map<String, String> params = AliPayApi.toMap(getRequest());

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

            boolean verify_result = AlipaySignature.rsaCheckV1(params, AliPayApi.ALIPAY_PUBLIC_KEY, AliPayApi.CHARSET,
                    AliPayApi.SIGN_TYPE);

            if (verify_result) {// 驗證成功
                // TODO 請在這里加上商戶的業務邏輯程序代碼
                System.out.println("notify_url 驗證成功succcess");
                renderText("success");
                return;
            } else {
                System.out.println("notify_url 驗證失敗");
                // TODO
                renderText("failure");
                return;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            renderText("failure");
        }
    }
/**
     * 將異步通知的參數轉化為Map
     * @param request
     * @return
     */
    public static Map<String, String> toMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 亂碼解決,這段代碼在出現亂碼時使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }

此項目源碼【下載地址

測試

下載部署如果沒有做任何修改默認的分別為:
測試地址:http://域名或者IP/alipay/wapPay
回跳地址:http://域名或者IP/alipay/return_url
通知地址:http://域名或者IP/alipay/notify_url

測試截圖

wap支付頁面
輸入支付賬號以及密碼
確認付款
輸入支付密碼
支付成功
回跳頁面

推薦閱讀
Android版-微信APP支付
極速開發微信公眾號之微信買單
極速開發微信公眾號之公眾號支付
極速開發微信公眾號之掃碼支付
極速開發微信公眾號之刷卡支付
極速開發微信公眾號之現金紅包
Android版-支付寶APP支付

記錄學習的點滴,以此勉勵不斷奮斗的自己?????? 如果對你有幫助記得點喜歡

源碼下載地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容