呼叫支付寶第三方支付介面詳解(沙箱環境)
阿新 • • 發佈:2018-11-21
首發地址:Java知音
注:這裡的支付是沙箱模擬支付
- 註冊螞蟻金服開放平臺
螞蟻金服開放平臺註冊地址
支付寶掃碼登陸 -> 註冊為自主研發者
2. 配置你的沙箱支付寶
支付寶提供一鍵生成工具便於開發者生成一對RSA2金鑰:https://docs.open.alipay.com/291/105971
該工具使用需要java環境
windows安裝java環境:https://blog.csdn.net/edison_03/article/details/79757591
Mac安裝java環境:https://www.cnblogs.com/xqx-qyy/p/7659805.html
![生成RSA2金鑰](https://upload-images.jianshu.io/upload_images/13637268-a7bfc1f3ac49c3d0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
注意:生成時一定要選擇PKCS8+2048
![配置RSA2金鑰](https://upload-images.jianshu.io/upload_images/13637268-0f537fd0bb2f935a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
將應用閘道器和回撥地址更改為:https://www.alipay.com
AES金鑰不用管
然後往下會有支付寶沙箱安卓端工具,下載,以供後續支付使用
進入頁面左側導航欄沙箱賬號,沙箱安卓端安裝後用買家賬號登陸
到這裡基本配置就完了,下面進入大家喜歡的程式碼時間:
3. 新建一個配置類 AlipayConfig.java
package com.alipay.config;
import java.io.FileWriter;
import java.io.IOException;
/* *
*類名:AlipayConfig
*作者:有夢想一起實現
*/
public class AlipayConfig{
// ↓↓↓↓↓↓↓↓↓↓請在這裡配置您的基本資訊↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 應用ID,您的APPID,收款賬號既是您的APPID對應支付寶賬號
public static String app_id = "APPID";//例:2016082600317257
// 商戶私鑰,您的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 = "你的伺服器地址/專案名稱/notify_url";
// 頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義引數,必須外網可以正常訪問
/**
* 此頁面是同步返回使用者頁面,也就是使用者支付後看到的頁面,上面的notify_url是非同步返回商家操作,謝謝
* 要是看不懂就找度娘,或者多讀幾遍,或者去看支付寶第三方介面API,不看API直接拿去就用,遇坑不怪別人
*/
public static String return_url = " 你的伺服器地址/專案名稱/return_url";
// 簽名方式
public static String sign_type = "RSA2";
// 字元編碼格式
public static String charset = "gbk";
// 支付寶閘道器
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 日誌地址
public static String log_path = "D:/logs/";
// ↑↑↑↑↑↑↑↑↑↑請在這裡配置您的基本資訊↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 寫日誌,方便測試(看網站需求,也可以改成把記錄存入資料庫)
*
* @param sWord
* 要寫入日誌裡的文字內容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_"
+ System.currentTimeMillis() + ".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
如果你是在本地測試,支付完成不會跳轉回調頁面,那麼就需要外網了
推薦一個東西,叫內網穿透,只要你電腦tomcat啟動,可以連線外網,就可以使用
---- 內網穿透軟體 ----
NATAPP 提供免費的測試足夠->https://natapp.cn/
ngrok或者frp以及其他免費開源Google自行了解
- 引入依賴包
<dependency>
<groupId>com.pentahohub.nexus</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>20150820220052</version>
</dependency>
如果上面的依賴失效或者無法使用,依賴下載地址:http://central.maven.org/maven2/com/pentahohub/nexus/alipay-sdk-java/20150820220052/alipay-sdk-java-20150820220052.jar
5. 支付呼叫的介面
/**
* 快捷支付呼叫支付寶支付介面
* @param model,id,payables,
* @throws IOException,AlipayApiException
* @return Object
* @author 有夢想一起實現
*/
@RequestMapping("alipaySum")
public Object alipayIumpSum(Model model, String payables, String subject, String body, HttpServletResponse response)
throws Exception {
// 獲得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfigInfo.gatewayUrl, AlipayConfigInfo.app_id,
AlipayConfigInfo.merchant_private_key, "json", AlipayConfigInfo.charset,
AlipayConfigInfo.alipay_public_key, AlipayConfigInfo.sign_type);
// 設定請求引數
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfigInfo.return_url);
alipayRequest.setNotifyUrl(AlipayConfigInfo.notify_url2);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
// 商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
String out_trade_no = sdf.format(new Date());
// 付款金額,必填
String total_amount = payables.replace(",", "");
alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
+ "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
// 請求
String result = alipayClient.pageExecute(alipayRequest).getBody();
// System.out.println(result);
AlipayConfigInfo.logResult(result);// 記錄支付日誌
response.setContentType("text/html; charset=gbk");
PrintWriter out = response.getWriter();
out.print(result);
return null;
}
引數傳入是必須有的,不然會報訂單資訊有誤
如果有其他額外引數,請參考支付寶第三方API文件
- 支付完成回撥
這裡支付完成會回撥兩個介面,notify_url和return_url,就是在配置類配置的兩個介面
- notify_url介面->非同步回撥的後臺操作
/**
* 支付完成回撥驗證操作
* @param response,request
* @throws Exception
* @return void
* @author 有夢想一起實現
*/
@RequestMapping("notify_url")
public void Notify(HttpServletResponse response, HttpServletRequest request) throws Exception {
System.out.println("----------------------------notify_url------------------------");
// 商戶訂單號
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "GBK");
// 付款金額
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "GBK");
// 支付寶交易號
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "GBK");
// 交易說明
String cus = new String(request.getParameter("body").getBytes("ISO-8859-1"), "GBK");
// 交易狀態
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "GBK");
if (trade_status.equals("TRADE_SUCCESS")) {//支付成功商家操作
//下面是我寫的一個簡單的插入操作,根據你的操作自行編寫
/*Map<Object, Object> map = new HashMap<Object, Object>();
map.put("cuId", Integer.valueOf(cus));
RepaymentPlan repaymentPlan = new RepaymentPlan();
Integer id = Integer.valueOf(out_trade_no);
double payablesCheck = Double.valueOf(total_amount);
RepaymentPlan repayCheck = serviceMain.selectByPrimaryKey(id);
double total = repayCheck.getPayables();
if (Double.valueOf(total_amount) < repayCheck.getPayables()) {
map.put("ubalance", total - Double.valueOf(total_amount));
serviceMain.updateCusMoney(map);
}
repaymentPlan.setId(id);
repaymentPlan.setActualPayment(total);
repaymentPlan.setRepaymentStatus(1);
int i = serviceMain.updateByPrimaryKeySelective(repaymentPlan);
System.out.println("---------------------還款影響行數----------------------------" + i);*/
}
}
- return_url 介面->同步通知返回的是頁面
/**
* 同步通知的頁面的Controller
* 我這邊就簡單的返回了一個頁面
* @param request,response
* @throws InterruptedException
*/
@RequestMapping("return_url")
public String Return_url() throws InterruptedException {
return "alipayexit";
}
- 請求支付介面的JSP的頁面
<form name=alipayment action=alipay.trade.page.pay.jsp method=post
target="_blank">
<div id="body1" class="show" name="divcontent">
<dl class="content">
<dt>商戶訂單號 :</dt>
<dd>
<input id="WIDout_trade_no" name="WIDout_trade_no" />
</dd>
<hr class="one_line">
<dt>訂單名稱 :</dt>
<dd>
<input id="WIDsubject" name="WIDsubject" />
</dd>
<hr class="one_line">
<dt>付款金額 :</dt>
<dd>
<input id="WIDtotal_amount" name="WIDtotal_amount" />
</dd>
<hr class="one_line">
<dt>商品描述:</dt>
<dd>
<input id="WIDbody" name="WIDbody" />
</dd>
<hr class="one_line">
<dt></dt>
<dd id="btn-dd">
<span class="new-btn-login-sp">
<button class="new-btn-login" type="submit"
style="text-align: center;">付 款</button>
</span> <span class="note-help">如果您點選“付款”按鈕,即表示您同意該次的執行操作。</span>
</dd>
</dl>
</div>
</form>
<!--這裡的target為_blank是新開啟一個視窗-->
支付寶介面的SDK&DEMO地址:https://docs.open.alipay.com/270/106291/