支付--支付寶手機網站支付(WAP)
阿新 • • 發佈:2019-01-08
介紹:
這是放在微信供公眾號內的一個專案,支付模組設計到微信公眾號支付和支付寶手機網站支付,這次把支付寶手機網站支付整理下來。
簽約:
首先要到支付寶開發者後臺去簽約支付寶手機網站支付方式。簽約的要求是必須有能訪問的網頁,網頁上有標明價格、名稱等詳細資訊的商品,而且整個下單流程要完善,網站的完成度要高,這才能通過稽核。
參考:
因為之前對接過支付寶的app支付,所以對接wap支付就容易得多。後臺拼接引數的思路、方式都和之前一樣。直接複用之前的程式碼,只需稍微修改幾個引數就可以。
參見上一篇支付寶APP支付:http://blog.csdn.net/tonyfreak/article/details/78104519
思路:
1、先到支付寶開放平臺建立應用獲取APPID
2、配置應用的相關引數,簽約申請開通對應的支付型別
3、獲得支付許可權後就可以著手進行程式碼編寫:
①、組裝引數分為公共請求引數和業務請求引數兩部分。詳見:https://docs.open.alipay.com/203/107090/
②、先把業務請求引數轉成json放入公共請求引數biz_content 中
③、將公共請求引數進行簽名操作
④、將簽名後獲得的簽名引數放入公共請求引數sign中
⑤、將此時的公共請求引數進行url編碼
⑥、將json資料傳給前端
微信公眾平臺無法使用支付寶收付款的解決方案
微信中無法開啟支付寶收款是微信瀏覽器限制所致,可以參考下圖方法引導使用者轉到系統瀏覽器,即可用支付寶收款。 點此下載。
微信中呼叫支付寶支付效果展示
後臺程式碼
組裝引數
/**
* 封裝好引數,前臺通過form表單來調起支付寶
*/
@RequestMapping("/alipayPayChongRequest")
@ApiOperation(value="支付寶充值起調的介面",httpMethod="POST",response=JsonUtil.class,notes="支付寶充值起調的介面---/alipayPayChongRequest")
public void alipayPayChongRequest(
@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("")){
BusWalletChong chong = busWalletChongService.findBusWalletChongById(orderNumber);// 根據訂單主鍵id查詢,訂單編號就是主鍵id
String saleMoney = chong.getPrice().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_chong);// 支付寶伺服器主動通知商戶服務
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字串轉義
Map<String, String> payMap = new HashMap<>();
try {
param.put("sign", PayUtil.getSign(param, AlipayConfig.private_key)); // 業務請求引數
String orderStr = PayUtil.getSignEncodeUrl(param, true);
System.out.println(orderStr);
payMap.put("orderStr", orderStr);
} 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));
}
支付回撥
/**
* 支付寶充值成功的回撥介面
*/
@RequestMapping("/alipayPayCallBackWallet")
@ApiOperation(value="支付寶充值成功的回撥介面",httpMethod="POST",response=JsonUtil.class,notes="支付寶充值成功的回撥介面---pay/alipayPayCallBackWallet")
public String alipayPayCallBackWallet(){
try {
// 獲取支付寶POST過來反饋資訊
Map<String, String> params = new HashMap<String, String>();
Map requestParams = request.getParameterMap();
for (Iterator 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] + ",";
}
// 亂碼解決,這段程式碼在出現亂碼時使用。如果mysign和sign不相等也可以使用這段程式碼轉化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
// 獲取支付寶的通知返回引數,可參考技術文件中頁面跳轉同步通知引數列表(以下僅供參考)//
// 商戶訂單號
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 支付寶交易號
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 充值金額
String price = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
// 獲取支付寶的通知返回引數,可參考技術文件中頁面跳轉同步通知引數列表(以上僅供參考)//
boolean check = AlipayNotify.verify(params);
if (check) {// 驗證成功
// ////////////////////////////////////////////////////////////////////////////////////////
// 請在這裡加上商戶的業務邏輯程式程式碼
String orderNo = out_trade_no;// 提交訂單返回的訂單編號
// 支付寶交易號
String alipayOrderNo = trade_no;
BusWalletChong chong = busWalletChongService.findBusWalletChongById(orderNo);
if(chong != null && !"".equals(chong)){
if("1".equals(chong.getStatus())){// 支付狀態為:已支付
response.getWriter().write(setXML("SUCCESS", ""));
}else{
BusWalletChong newChong = new BusWalletChong();
newChong.setPrice(new BigDecimal(price));
newChong.setPayId(alipayOrderNo);
newChong.setPayType(BusWalletChong.ALIPAY_ZHIFU_TYPE);
newChong.setId(orderNo);
boolean flag = busWalletChongService.updateWallet(newChong);
if(flag){
response.getWriter().write(setXML("SUCCESS", ""));
}else{
response.getWriter().write(setXML("FAIL", ""));
}
}
}else{
response.getWriter().write(setXML("FAIL", ""));
}
response.getWriter().write("SUCCESS");
} else {// 驗證失敗
response.getWriter().write("FAIL");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String setXML(String return_code, String return_msg) {
return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg
+ "]]></return_msg></xml>";
}
簽名工具類
/**
* 對支付引數資訊進行簽名
*
* @param map
* 待簽名授權資訊
*
* @return
*/
public static String getSign(Map<String, String> map, String rsaKey) {
List<String> keys = new ArrayList<String>(map.keySet());
// key排序
Collections.sort(keys);
StringBuilder authInfo = new StringBuilder();
boolean first = true;
for (String key : keys) {
if (first) {
first = false;
} else {
authInfo.append("&");
}
authInfo.append(key).append("=").append(map.get(key));
}
return SignUtils.sign(authInfo.toString(), rsaKey);
}
簽名編碼工具類
/**
* 返回簽名編碼拼接url
*
* @param params
* @param isEncode
* @return
*/
public static String getSignEncodeUrl(Map<String, String> map, boolean isEncode) {
String sign = map.get("sign");
String encodedSign = "";
if (CollectionUtil.isNotEmpty(map)) {
map.remove("sign");
List<String> keys = new ArrayList<String>(map.keySet());
// key排序
Collections.sort(keys);
StringBuilder authInfo = new StringBuilder();
boolean first = true;// 是否第一個
for (String key: keys) {
if (first) {
first = false;
} else {
authInfo.append("&");
}
authInfo.append(key).append("=");
if (isEncode) {
try {
authInfo.append(URLEncoder.encode(map.get(key), AlipayConstants.CHARSET_UTF8));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
authInfo.append(map.get(key));
}
}
try {
encodedSign = authInfo.toString() + "&sign=" + URLEncoder.encode(sign, AlipayConstants.CHARSET_UTF8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return encodedSign.replaceAll("\\+", "%20");
}
前端程式碼
//點選支付寶付款
function payByAli(orderId,description,title){
$.ajax({
data:{orderNumber:orderId,orderTitle:title,description:description},
dataType:"json",
type:"post",
async: false,
url:"${ctxPath}/payZhiFuBao/alipayPayRequest",
success:function(msg){
if(msg.result.msg == "成功"){
//獲取拼接好的url
var url = msg.data.result.orderStr;
var urls = "https://mapi.alipay.com/gateway.do?"+url;
console.log(urls);
$(".ali").attr("href",urls);
}
},
error:function(msg){
}
});
}