Java 從零開始實現支付寶支付(後臺)
阿新 • • 發佈:2019-01-06
框架使用的是spring boot
我們整合支付寶支付 也就需要提供兩個接口出來.一個是給前端 作用是拿到請求引數加簽返回給前端
BizContent:
我們整合支付寶支付 也就需要提供兩個接口出來.一個是給前端 作用是拿到請求引數加簽返回給前端
前端拿到我們返回的資料.進行調起支付就行了,第二個介面是提供給支付寶的伺服器,支付成功或者失敗的時候.支付寶的伺服器會回撥我們的這個介面.非同步通知我們支付結果
好了.廢話不哆嗦,直接上程式碼:(此時,公鑰 私鑰環境都已經配好)
給兩個相關model@RestController @RequestMapping("/payment") public class PaymentController { // 支付寶重要引數 private static String APP_ID = ""; private static String APP_PRIVATE_KEY = ""; private static String CHARSET = "utf-8"; private static String ALIPAY_PUBLIC_KEY = ""; /** * 對支付寶支付資訊進行簽名 * * @param info * 資料類 * @return * @throws AlipayApiException * @throws UnsupportedEncodingException */ @PostMapping("/sign") public Object sign(@RequestBody SignInfo info) throws AlipayApiException, UnsupportedEncodingException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String appID = APP_ID; String bizContent = toJson(info.Content); String charset = CHARSET; String method = "alipay.trade.app.pay"; String signType = "RSA"; String timestamp = sdf.format(new Date()); String version = "1.0"; String notify_url = "https://pay.ytbapp.com/payment/notify";// 增加支付非同步通知回撥,記住上下notify_url的位置,全在sign_type之前,很重要,同樣放在最後都不行 String content = "app_id=" + appID + "&biz_content=" + bizContent + "&charset=" + charset + "&method=" + method + "¬ify_url=" + (notify_url) + "&sign_type=" + signType + "×tamp=" + timestamp + "&version=" + version; String sign = AlipaySignature.rsaSign(content, APP_PRIVATE_KEY, charset); return "{\"Result\": \"app_id=" + encode(appID) + "&biz_content=" + encode(bizContent) + "&charset=" + encode(charset) + "&method=" + encode(method) + "¬ify_url=" + encode(notify_url) + "&sign_type=" + encode(signType) + "×tamp=" + encode(timestamp) + "&version=" + encode(version) + "&sign=" + encode(sign) + "\"}"; } private String encode(String sign) throws UnsupportedEncodingException { return URLEncoder.encode(sign, "utf-8").replace("+", "%20"); } private String toJson(BizContent content) { String context = ""; context += "{" + "\"timeout_express\":\"" + content.timeout_express + "\"," + "\"seller_id\":\"" + content.seller_id + "\"," + "\"product_code\":\"" + content.product_code + "\"," + "\"total_amount\":\"" + content.total_amount + "\"," + "\"subject\":\"" + content.subject + "\"," + "\"body\":\"" + content.body + "\"," + "\"out_trade_no\":\"" + content.out_trade_no + "\"}"; return context; } /** * 支付寶支付成功後.會回撥該介面 * * @param request * @return * @throws UnsupportedEncodingException */ @PostMapping("/notify") public String notify(HttpServletRequest request) throws UnsupportedEncodingException { 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 = iter.next(); String[] values = 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"), "gbk"); params.put(name, valueStr); } String out_trade_no = request.getParameter("out_trade_no");// 商戶訂單號 boolean signVerified = false; try { signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET); } catch (AlipayApiException e) { // TODO Auto-generated catch block e.printStackTrace(); return ("fail");// 驗簽發生異常,則直接返回失敗 } // 呼叫SDK驗證簽名 if (signVerified) { // TODO 驗籤成功後 // 按照支付結果非同步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,校驗成功後在response中返回success,校驗失敗返回failure String result = updateALiPayOrderStatus(out_trade_no); System.out.println("驗證成功,去更新狀態 \t訂單號:" + out_trade_no + "來自支付寶支付,更新結果:" + result); BaseResponse baseResponse = GsonUtils.getGson().fromJson(result, BaseResponse.class); if (null != baseResponse && baseResponse.isSucceeded) { return ("success"); } else { return ("fail");// 更新狀態失敗 } } else { // TODO 驗籤失敗則記錄異常日誌,並在response中返回failure. System.out.println("驗證失敗,不去更新狀態"); return ("fail"); } } }
SignInfo:
public class SignInfo
{
public BizContent Content;
}
BizContent:
public class BizContent { public String body = ""; public String subject = ""; public String out_trade_no = ""; public String timeout_express = ""; public String total_amount = ""; public String seller_id = ""; public String product_code = ""; }