微信瀏覽器中進行支付寶支付
B端專案使用的是支付寶手機網頁支付,微信瀏覽器中遮蔽了支付寶的功能。上有政策下有對策,支付寶也有應對的辦法,下來就來說一說支付寶手機網站支付。
第一步:開發準備工作
登入支付寶平臺(需要實名認證的支付寶賬號),根據實際情況建立應用。
選擇自用型應用,新增應用功能。
配置應用環境
支付寶中使用的是RSA2非對稱金鑰結構。
第二步:快速接入
下載服務端SDK(software Development Kit),包含了java、php、.net三個語言版本,封裝了簽名驗籤、http請求等功能。但是我們的專案中沒有使用sdk,一般情況下sdk是用在原生的安卓和ios專案中,但是我們的專案使用的是混合式開發。
準備工作:支付寶給出了在微信瀏覽器中支付的解決方法,而且官網中有demo。
我下載了demo,其中有兩個比較重要的檔案,一個是ap.js,另一個是pay.htm(支付寶在微信瀏覽器中的引導頁,會引導使用者在瀏覽器中訪問此連結),支付頁面和pay.htm頁面必須引入ap.js檔案。
大概思路是前臺點選支付寶支付,然後調起後臺的拼裝支付引數的方法,返回一個拼裝好的url,將這個url在前臺賦值給一個a標籤,我寫了一個自定義事件,為了觸發a標籤前去訪問拼裝好的連結。
注意:ap.js中有個地址要修改下。
修改為本地的路徑。前臺程式碼就是這些就可以調起支付寶了。
後臺程式碼:
/**
* 後臺組裝好請求資料,前臺以form表單的形式向支付寶手機網頁
* 支付介面發起請求
* @param saleMoney
* @param orderNumber
* @param orderTitle
* @param description
*/
@RequestMapping ("/alipayPayRequest")
@ApiOperation(value="支付寶付款起調的介面",httpMethod="POST",response=JsonUtil.class,notes="支付寶付款起調的介面---/alipayPayRequest")
public void alipayPayRequest(
@ApiParam(required=true,name="orderNumber",value="訂單編號")@RequestParam(value="orderNumber") String orderNumber,
@ApiParam(required=true,name="orderTitle" ,value="訂單標題")@RequestParam(value="orderTitle") String orderTitle,
@ApiParam(required=true,name="description",value="訂單描述")@RequestParam(value="description") String description){
try{
if(orderNumber !=null && !orderNumber.equals("")
&& orderTitle !=null && !orderTitle.equals("")
&& description !=null && !description.equals("")
){
OrderCommCai orderCommCai = orderCommCaiService.get(orderNumber);//根據綜合採購單id來查詢綜合採購單
String saleMoney = orderCommCai.getOrderZongCommPrices().toString();
// 公共請求引數
Map<String, String> param = new HashMap<>();
param.put("app_id", AlipayConfig.appId); // 應用appId
param.put("method", "alipay.trade.wap.pay"); // 介面名稱
param.put("format", "json"); //資料型別
param.put("charset", AlipayConfig.input_charset);//編碼格式
param.put("timestamp", DatetimeUtil.formatDateTime(new Date()));//傳送請求時間
param.put("version", "1.0");//呼叫介面版本,固定為1.0
param.put("notify_url", AlipayConfig.notify_url);// 支付寶伺服器主動通知商戶服務
param.put("sign_type", AlipayConfig.sign_type);//簽名型別
// 支付業務請求引數
Map<String, Object> pcont = new HashMap<>();
pcont.put("out_trade_no", orderNumber);// 訂單號(綜合採購單編號)
pcont.put("total_amount", String.valueOf(saleMoney));// 交易金額
pcont.put("subject", orderTitle); // 訂單標題
pcont.put("body", description); // 對交易或商品的描述
pcont.put("product_code", "QUICK_WAP_WAY"); // 銷售產品碼
param.put("biz_content", JSON.toJSONString(pcont)); // 業務請求引數 不需要對json字串轉義
param.put("return_url", AlipayConfig.RETURN_URL);
Map<String, String> payMap = new HashMap<>();
try {
param.put("sign", PayUtil.getSign(param, AlipayConfig.private_key)); //業務請求引數
payMap.put("orderStr", PayUtil.getSignEncodeUrl(param, true));//拼接好的url
} catch (Exception e) {
e.printStackTrace();
}
map1.put("msg", "成功");
map2.put("result", payMap);
}else{
map1.put("msg", "引數不全");
}
} catch (BusinessException e) {
e.printStackTrace();
map1.put("msg", "發生後臺異常");
}
map.put("data", map2);
map.put("result", map1);
JsonUtil.writeJson(response, JsonUtil.objectToJson(map));
}
程式碼邏輯:
將公共引數放進map集合中,然後將請求引數放進另一個map1集合中。將map1轉換為json字串,然後將map1放進map中去,鍵值為biz_content,然後對引數進行簽名,將簽名後得到的字串放進map集合中,鍵值是sign,將map集合進行urlEncode,返回的就是拼接好的支付連結.
混合式開發基本都是這種寫法,只是引數的值可能會有變動。
請求引數說明:
請求地址:https://openapi.alipay.com/gateway.do
公共請求引數,根據自己的情況來選擇引數,有的是必填,有的是非必填。我在程式碼中主要用的是必填的引數。
app_id:支付寶分配給開發者的應用id
method:介面名稱
charset:請求使用的編碼格式
sign_type:演算法生成簽名字串使用的簽名演算法型別目前支援RSA和RSA2
sign:商戶請求引數的簽名串
timestamp:傳送請求的時間,格式yyyy-MM-dd HH:mm:ss
version:呼叫介面版本,固定為1.0
notify_url:支付寶伺服器主動通知商戶伺服器裡指定的頁面http/https路徑
return_url:支付成功後跳轉的頁面
biz_content:業務請求引數集合,最大長度不限,除公共引數外所有請求引數必須放在這個引數中傳遞。
請求引數:
subject:商品標題、交易標題、訂單標題、訂單關鍵字等
out_trade_no:商戶網站唯一訂單號
total_amount:訂單金額,單位為元,精確到小數點後兩位
product_code:銷售產品碼,商家和支付寶簽約的產品碼。填寫固定值QUICK_WAP_WAY