【java】小白最詳細除錯支付寶沙箱手機網站支付,電腦網站掃碼支付
最近公司有電腦網站跟手機網站的支付寶支付需求,正好博主最近相對有空,於是花了一天時間去實現這個功能。先是在支付寶的開放平臺的文件中心看了半天,,發現並不能找到立馬就能上手開發的內容。於是搜了幾篇部落格,綜合之下終於實現了功能。在此將java沙箱除錯的歷程整理出來,希望能對大家有所幫助,好了廢話不扯,來看看怎麼一步步實現的。
第一步
訪問開放平臺文件中西,看看支付寶的支付流程,大概瞭解一下就行了。地址如下https://docs.open.alipay.com/270/105898/
第二步
下載java的demo(非常重要),裡面包含了需要的jar包以及定義好了支付寶支付的基本引數,下載下來之後我們把自己的引數copy進去,呼叫起來就很方便。下載路徑如下
第三步
申請沙箱環境。沙箱環境相當於是一個支付寶的測試中心,申請之後,會給你指定的appid,測試買家的賬號(付款賬號),測試賣家賬號(收款賬號)。有了這些,我們就能愉快的享受除錯買買買的樂趣了。
申請及資料採集步驟如下
1.進入支付寶沙箱測試中心
2.需要生成RSA2(SHA256)的應用公鑰,並且配置好RSA2(SHA256)的應用公鑰,這裡注意,不需要配置RSA(SHA1)金鑰。(生成RSA2的應用公鑰詳情請參考:https://docs.open.alipay.com/291/105971) 然後將生成的公鑰填寫到下圖中的應用公鑰,再將支付寶的公鑰copy下來備用。
3.沙箱應用中,還需要配置應用閘道器,這裡就需要做內網穿透了。需要讓你本地的服務能在公網上被訪問到。博主使用的是natapp工具,使用起來很方便,生成了自己的域名之後,然後直接訪問,看看tomcat服務能不能跑起來,能訪問到之後,將域名天下到應用閘道器下。至此,沙箱配置就完成啦
第四步,將下載下來的demo解壓,匯入到自己的開發工具中,博主用的myeclipse,目錄及結構如下
其中為了方便處理支付寶的結構化引數,額外匯入了fastjson的包 ,具體的資源大家可以在百度maven 在倉庫中搜索下載啦
第五部,新增自己的程式碼快,如下
package com.inspiron.alipay;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.config.AlipayConfig;
public class AlipayClientFactory {
/*private static final AlipayClient client = new DefaultAlipayClient(
AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY); */
private static final AlipayClient client = new DefaultAlipayClient(
AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
public static AlipayClient getAlipayClientInstance() {
return client;
}
/**
* appAuthToken
* 如ISV代替商家呼叫當面付介面,需將商戶授權後獲取的app_auth_token帶上;如商家申請當面付自己呼叫,則傳null bizContent
* JSON格式 商戶的請求引數
*/
// 手機網頁支付 網站支付
public String ydAndPc_Pay(Map<String, String> maps)
throws AlipayApiException {
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
String NotifyUrl = maps.get("NotifyUrl");
String ReturnUrl = maps.get("ReturnUrl");
// 後臺回撥
if (!StringUtils.isEmpty(NotifyUrl)) {
alipayRequest.setNotifyUrl(NotifyUrl);
// bizContent 中不需要 公共引數
maps.remove("NotifyUrl");
}
// 頁面回撥
if (!StringUtils.isEmpty(ReturnUrl)) {
alipayRequest.setReturnUrl(ReturnUrl);
// bizContent 中不需要 公共引數
maps.remove("ReturnUrl");
}
String bizCon = JSON.toJSONString(maps);
alipayRequest.setBizContent(bizCon);
String form = "";
try {
form = AlipayClientFactory.getAlipayClientInstance()
.pageExecute(alipayRequest).getBody();
} catch (AlipayApiException e) {
form = "err";
e.printStackTrace();
} // 呼叫SDK生成表單
return form;
}
public String Pc_Pay(Map<String, String> maps)
throws AlipayApiException {
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
String NotifyUrl = maps.get("NotifyUrl");
String ReturnUrl = maps.get("ReturnUrl");
// 後臺回撥
if (!StringUtils.isEmpty(NotifyUrl)) {
alipayRequest.setNotifyUrl(NotifyUrl);
// bizContent 中不需要 公共引數
maps.remove("NotifyUrl");
}
// 頁面回撥
if (!StringUtils.isEmpty(ReturnUrl)) {
alipayRequest.setReturnUrl(ReturnUrl);
// bizContent 中不需要 公共引數
maps.remove("ReturnUrl");
}
String bizCon = JSON.toJSONString(maps);
System.out.println("bizCon :"+bizCon);
alipayRequest.setBizContent(bizCon);
String form = "";
try {
form = AlipayClientFactory.getAlipayClientInstance()
.pageExecute(alipayRequest).getBody();
} catch (AlipayApiException e) {
form = "err";
e.printStackTrace();
} // 呼叫SDK生成表單
return form;
}
// 查詢訂單狀態
public AlipayTradeQueryResponse query(String appAuthToken, String bizContent)
throws AlipayApiException {
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.putOtherTextParam("app_auth_token", appAuthToken);
request.setBizContent(bizContent);
return AlipayClientFactory.getAlipayClientInstance().execute(request);
}
// 條碼支付
public AlipayTradePayResponse pay(String appAuthToken, String bizContent)
throws AlipayApiException {
AlipayTradePayRequest request = new AlipayTradePayRequest();
request.putOtherTextParam("app_auth_token", appAuthToken);
request.setBizContent(bizContent);
return AlipayClientFactory.getAlipayClientInstance().execute(request);
}
// 掃碼支付
public AlipayTradePrecreateResponse precreate(String appAuthToken,
String bizContent) throws AlipayApiException {
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.putOtherTextParam("app_auth_token", appAuthToken);
request.setBizContent(bizContent);
return AlipayClientFactory.getAlipayClientInstance().execute(request);
}
// 訂單撤銷
public AlipayTradeCancelResponse cancel(String appAuthToken,
String bizContent) throws AlipayApiException {
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
request.putOtherTextParam("app_auth_token", appAuthToken);
request.setBizContent(bizContent);
return AlipayClientFactory.getAlipayClientInstance().execute(request);
}
// 申請退款
public AlipayTradeRefundResponse refund(String appAuthToken,
String bizContent) throws AlipayApiException {
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.putOtherTextParam("app_auth_token", appAuthToken);
request.setBizContent(bizContent);
return AlipayClientFactory.getAlipayClientInstance().execute(request);
}
@SuppressWarnings("unused")
public static void main(String[] args) {
AlipayClientFactory c = new AlipayClientFactory();
try {
Map<String, String> map = new HashMap<String, String>();
map.put("out_trade_no", "20160914113218");
String bizContent = JSON.toJSONString(map);
System.err.println(bizContent);
AlipayTradeQueryResponse rp = c.query(null, bizContent);
} catch (AlipayApiException e) {
e.printStackTrace();
}
}
}
package com.inspiron.alipay;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alipay.api.AlipayApiException;
public class CsPay extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 引數目前都是 寫死的 根據業務需求 寫活
System.out.println("已經成功進入到後臺介面");
Map<String, String> maps = new HashMap<String, String>();
maps.put("out_trade_no", UtilDate.getOrderNum());
maps.put("total_amount","1.00");
maps.put("subject", "Iphone6 16G");
maps.put("body", "Iphone6 16G");
//maps.put("product_code", "QUICK_WAP_PAY");
maps.put("product_code", "FAST_INSTANT_TRADE_PAY");//網頁版引數不同
// 下面兩個 引數的 KEY 不要亂寫 要和工具類裡面對應
maps.put("ReturnUrl", "http://f8s7ks.natappfree.cc/alipay.trade.wap.pay-java-utf-8/return_url.jsp");
maps.put("NotifyUrl", "http://f8s7ks.natappfree.cc/alipay.trade.wap.pay-java-utf-8/notify_url.jsp");
try {
AlipayClientFactory ali = new AlipayClientFactory();
String form = ali.Pc_Pay(maps);
if (!form.equals("err")) {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(form);// 直接將完整的表單html輸出到頁面
response.getWriter().flush();
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
}
}
package com.inspiron.alipay;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class CsUtil {
/**
* 把陣列所有元素排序,並按照“引數=引數值”的模式用“&”字元拼接成字串
*
* @param params 需要排序並參與字元拼接的引數組
* @return 拼接後字串
*/
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {// 拼接時,不包括最後一個&字元
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
}
package com.inspiron.alipay;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
/*
* * 類名:UtilDate 功能:自定義訂單類 詳細:工具類,可以用作獲取系統日期、訂單編號等 版本:3.3 日期:2012-08-17 說明:
* 以下程式碼只是為了方便商戶測試而提供的樣例程式碼,商戶可以根據自己網站的需要,按照技術文件編寫,並非一定要使用該程式碼。 該程式碼僅供學習和研究支付寶介面使用,只是提供一個參考。
*/
public class UtilDate {
/** 年月日時分秒(無下劃線) yyyyMMddHHmmss */
public static final String dtLong = "yyyyMMddHHmmss";
/** 完整時間 yyyy-MM-dd HH:mm:ss */
public static final String simple = "yyyy-MM-dd HH:mm:ss";
/** 年月日(無下劃線) yyyyMMdd */
public static final String dtShort = "yyyyMMdd";
/**
* 返回系統當前時間(精確到毫秒),作為一個唯一的訂單編號
*
* @return 以yyyyMMddHHmmss為格式的當前系統時間
*/
public static String getOrderNum() {
Date date = new Date();
DateFormat df = new SimpleDateFormat(dtLong);
return df.format(date);
}
/**
* 獲取系統當前日期(精確到毫秒),格式:yyyy-MM-dd HH:mm:ss
*
* @return
*/
public static String getDateFormatter() {
Date date = new Date();
DateFormat df = new SimpleDateFormat(simple);
return df.format(date);
}
/**
* 獲取系統當期年月日(精確到天),格式:yyyyMMdd
*
* @return
*/
public static String getDate() {
Date date = new Date();
DateFormat df = new SimpleDateFormat(dtShort);
return df.format(date);
}
/**
* 產生隨機的三位數
*
* @return
*/
public static String getThree() {
Random rad = new Random();
return rad.nextInt(1000) + "";
}
}
程式碼貼進去之後,填寫AlipayConfig檔案中的引數,如下
然後需要配置servelt的入口,我們在web.xml 檔案中作如下配置
<servlet>
<servlet-name>cspay</servlet-name>
<servlet-class>com.inspiron.alipay.CsPay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cspay</servlet-name>
<url-pattern>/cspay</url-pattern>
</servlet-mapping>
將專案載入到伺服器中,訪問路徑 http://自己的網址/alipay.trade.wap.pay-java-utf-8/cspay
出現以下頁面
恭喜你,大公高成啦。
如果是手機網站,呼叫app的方式,需要在程式碼中做如下修改
然後訪問出現如下頁面
表示成功 。然後可以登入沙箱給我們的買家的賬號,就可以體驗支付的流程啦
如果有問題,歡迎大家溝通指導~~