從零開始將支付寶支付接口進一步封裝到發佈上線使用!

自從工作以來就很少寫博客了,其實自己有很多很多個人總結想寫下來,但是自己比較懶加上又只有單休那就更寫的少。但是寫博客這種總結的學習方式是值得我們每個人堅持的。

如果你想做個小商場的話,你絕對離不開支付,而如果不實現支付你網站做的再好也是紙上談兵?

那對於支付的話我們可能最先想到的是微信支付、支付寶支付,但是調用人家的接口是有一定限制的。

支付寶:1.實名認證   2.最少有營業執照(公司性質那就不用說了那絕對可以)

微信:1.實名認證  2.最少有營業執照(公司性質那就不用說了那絕對可以) 3.對公賬戶

綜合來看支付寶限制還是低一些,爲此我註冊了一個個體工商戶(個體工商戶成本是最低的,建議和我一樣話50塊錢在老家辦一個,這樣限制更低)

 

當你滿足上面的條件後你就可以開始了。

第一步:創建一個支付應用

第二步:認證,讓支付寶授權你的應用

這裏就用到我們的營業執照了,多和小姐姐溝通一下,很快的。

第三步:建議你看一下支付寶的幫助文檔,瞭解下他的流程

上面都是準備階段,獲得權限後你就可以開始設置公鑰私鑰了。

https://opensupport.alipay.com/support/knowledge/20069/201602369174?ant_source=zsearch

 

將生成的公鑰上傳到支付寶,再將支付寶的公鑰複製出來作爲請求的參數。(公鑰這個一定要複製支付寶給出的公鑰,不要你可以支付成功,但驗證會不成功)

做好公祕鑰後你就完成一半了,你就可以跑支付寶給出的例子。

下載官方給出的demo

https://docs.open.alipay.com/54/106682/

(demo全是jsp寫的,一看就是好久好久的。首先你要看懂他寫的內容再做改編。)

在pay.jsp中你看到的是他接收傳來的訂單參數,並請求支付寶接口。(只要是我也不是很會jsp,再加上這樣寫的好彆扭,所以我改成servlet,你也可以改成一個controller)

 

改寫後的代碼如下:

http://47.94.205.224:8080/PayTest/pay?WIDout_trade_no=1511111111112222222&WIDsubject=測試&WIDtotal_amount=10&WIDbody=測試&OrderInsetUrl=http://www.abc.com&SuccessReturnUrl=https://blog.csdn.net/qq_35376421/article/details/80239080&FailReturnUrl=https://blog.csdn.net&notifyurl=http://47.94.205.224:8080/PayTest/notifyInfo&returnurl=http://47.94.205.224:8080/PayTest/returnInfo

你就可以通過get請求來調用你的接口,再去調用支付寶的接口

package com.alipay.config;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.internal.util.*;


@WebServlet("/pay")
public class Pay extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("pay");
		
		response.setContentType("text/html;charset=" + AlipayConfig.CHARSET); 
		PrintWriter out = response.getWriter();

		// 商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
		String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
		// 訂單名稱,必填
		String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
		// 付款金額,必填
		String total_amount=new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
		// 商品描述,可空
		String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
		// 超時時間 可空
		String timeout_express="1m";
		// 銷售產品碼 必填
		String product_code="QUICK_WAP_WAY";

		//獲取自定義參數
		try {
			// 訂單信息插入接口,必填
			AlipayConfig.OrderInsetUrl = new String(request.getParameter("OrderInsetUrl").getBytes("ISO-8859-1"),"UTF-8");
			// 同步信息成功轉跳頁面,必填
			AlipayConfig.SuccessReturnUrl = new String(request.getParameter("SuccessReturnUrl").getBytes("ISO-8859-1"),"UTF-8");
			// 同步信息失敗轉跳頁面,必填
			AlipayConfig.FailReturnUrl = new String(request.getParameter("FailReturnUrl").getBytes("ISO-8859-1"),"UTF-8");
			// 服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
			AlipayConfig.notify_url = new String(request.getParameter("notifyurl").getBytes("ISO-8859-1"),"UTF-8");
			// 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址
			AlipayConfig.return_url = new String(request.getParameter("returnurl").getBytes("ISO-8859-1"),"UTF-8");
			
			System.out.println(AlipayConfig.OrderInsetUrl+" "
					+AlipayConfig.SuccessReturnUrl+" "
					+AlipayConfig.FailReturnUrl+" "
					+AlipayConfig.notify_url+" "
					+AlipayConfig.return_url);

		}catch(Exception e) {
			//保存日誌
			LogFile.logResult("請求參數不全   "+out_trade_no+"/n"
					+subject+" "
					+total_amount+" "
					+body+" "
					+timeout_express+" "
					+product_code+" "
					+AlipayConfig.OrderInsetUrl+" "
					+AlipayConfig.SuccessReturnUrl+" "
					+AlipayConfig.FailReturnUrl+" "
					+AlipayConfig.notify_url+" "
					+AlipayConfig.return_url
					,request,"less_param");
			
			out.write("請求參數不全!");
			out.flush(); 
			out.close();
			e.printStackTrace();
		}

		//獲取參數都不爲空時,則繼續支付。反之則返回錯誤信息
		if((request.getParameter("WIDout_trade_no")!=null)&& 
				(!StringUtils.isEmpty(out_trade_no))&&
				(!StringUtils.isEmpty(subject))&&
				(!StringUtils.isEmpty(total_amount))&&
				(!StringUtils.isEmpty(AlipayConfig.OrderInsetUrl))&&
				(!StringUtils.isEmpty(AlipayConfig.SuccessReturnUrl))&&
				(!StringUtils.isEmpty(AlipayConfig.FailReturnUrl))
				){

			// SDK 公共請求類,包含公共請求參數,以及封裝了簽名與驗籤,開發者無需關注簽名與驗籤     
			//調用RSA簽名方式
			AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
			AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

			// 封裝請求支付信息
			AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
			model.setOutTradeNo(out_trade_no);
			model.setSubject(subject);
			model.setTotalAmount(total_amount);
			model.setBody(body);
			model.setTimeoutExpress(timeout_express);
			model.setProductCode(product_code);
			alipay_request.setBizModel(model);
			// 設置異步通知地址
			alipay_request.setNotifyUrl(AlipayConfig.notify_url);
			// 設置同步地址
			alipay_request.setReturnUrl(AlipayConfig.return_url);   

			// form表單生產
			String form = "";
			try {
				// 調用SDK生成表單
				form = client.pageExecute(alipay_request).getBody();
				out.write(form);//直接將完整的表單html輸出到頁面 
				out.flush(); 
				out.close();
			} catch (AlipayApiException e) {
				out.write("請求支付寶接口錯誤!");
				out.flush(); 
				out.close();
				e.printStackTrace();
			} 
		}else {
			out.write("參數不存在空值!");
			out.flush(); 
			out.close();
		}
	}

}

 

package com.alipay.config;

public class AlipayConfig {
	// 商戶appid
	public static String APPID = "2018101061666026";
	// 私鑰 pkcs8格式的
	public static String RSA_PRIVATE_KEY = (你的私鑰)"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDcWlLjbmgEIkG1\r\n" + 
			"tSyHaw31GhD2dQoAPRD4roG7/u3i75WI/E2+5UuPMJlAEGR3wsCd7szgPImiL7G/\r\n" + 
			"rjF8PKoSMJMy/i3i548QKBgQDOISbJgq6SdZivFlPd\r\n" + 
			"zJr2uFroEwdNAeNNzocW1plUCa2IraMyFiAJLUaCVGI2IHGYlMKTCKPqiNnYTKPc\r\n" + 
			"fg7EbbV8JJzc2L1gMT3oYvvoO3ZtHkED/mkHUhIGcdC45oaHiPxjHSFlEUbUvrp+\r\n" + 
			"3PBtqtLAYEflRWdxqn9Ez/tkIw==";
	// 服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
	public static String notify_url = "";
	// 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址
	public static String return_url = "";
	// 請求網關地址
	public static String URL = "https://openapi.alipay.com/gateway.do";
	// 編碼
	public static String CHARSET = "UTF-8";
	// 返回格式
	public static String FORMAT = "json";
	// 支付寶公鑰
	public static String ALIPAY_PUBLIC_KEY = (你的公鑰)"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiqNfxFppsMpPjb8C8dUb34VuoJ6fI+0t+WxO3NeqeACozo3i09lqlwIDAQAB";
	// 日誌記錄目錄
	public static String log_path = "\\log\\";
	// RSA2
	public static String SIGNTYPE = "RSA2";
	
	//訂單保存的接口路徑
	public static String OrderInsetUrl = "";
	
	//同步信息返回成功後轉跳的頁面路徑
	public static String SuccessReturnUrl = "";
	
	//同步信息返回失敗後轉跳的頁面路徑
	public static String FailReturnUrl = "";
	
	
	
	
	
	
}

(這幾個是寫你程序的接口和頁面)    

//訂單保存的接口路徑
    public static String OrderInsetUrl = "";
    
    //同步信息返回成功後轉跳的頁面路徑
    public static String SuccessReturnUrl = "";
    
    //同步信息返回失敗後轉跳的頁面路徑
    public static String FailReturnUrl = "";

 

在將return_url.jsp改寫成servlet

package com.alipay.config;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.gson.Gson;

@WebServlet("/returnInfo")
public class ReturnInfo extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("returnInfo");
		//設置響應的內容類型  MIME類型
		response.setContentType("text/html; charset=utf-8");
		//獲取響應的輸出流
		PrintWriter out = response.getWriter();

		//獲取支付寶GET過來反饋信息
		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");

		//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)//
		//計算得出通知驗證結果
		//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
		boolean verify_result = false;
		try {
			verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		
		Gson g = new Gson();
		if(verify_result){
			//驗證成功
			System.out.println("return");
			System.out.println(g.toJson(params));
			System.out.println(verify_result);
			System.out.println();
			out.write("<script language='javascript'>window.location.href=\""+AlipayConfig.SuccessReturnUrl+"?out_trade_no="+out_trade_no+"&trade_no="+trade_no+"&verify_result="+verify_result+"\"; </script>");
		}else{
			//驗證失敗
			System.out.println("return");
			System.out.println(g.toJson(params));
			System.out.println(verify_result);
			System.out.println();
			out.write("<script language='javascript'>window.location.href=\""+AlipayConfig.FailReturnUrl+"?out_trade_no="+out_trade_no+"&trade_no="+trade_no+"&verify_result="+verify_result+"\"; </script>");
			
			
		}
	}
}

 

在將notify_url.jsp改寫成servlet

package com.alipay.config;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.gson.Gson;


@WebServlet("/notifyInfo")
public class NotifyInfo extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("notifyInfo");
		Gson g = new Gson();
		//設置響應的內容類型  MIME類型
		response.setContentType("text/html; charset=utf-8");
		//獲取響應的輸出流
		PrintWriter out = response.getWriter();

		//獲取支付寶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"), "gbk");
			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 trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

		//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)//
		//計算得出通知驗證結果
		//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
		boolean verify_result = false;
		try {
			verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}

		if(verify_result){
			//驗證成功
			System.out.println("notify");
			System.out.println(g.toJson(params));
			//保存日誌
			LogFile.logResult(("驗證成功   "+g.toJson(params)),request,params.get("out_trade_no"));
			System.out.println(verify_result);
			System.out.println(AlipayConfig.OrderInsetUrl);
			System.out.println();

			out.write("success");  
		}else{
			//驗證失敗
			System.out.println("notify");
			System.out.println(g.toJson(params));
			//保存日誌
			LogFile.logResult(("驗證失敗   "+g.toJson(params)),request,params.get("out_trade_no"));
			System.out.println(AlipayConfig.OrderInsetUrl);
			System.out.println();
			
			out.write("fail");  
		}
		
		out.flush();  
		out.close();
	}

}

(文章末尾會帶源碼,再此其他jsp改編就不一一說了)

 

做好這些後你可以用netapp

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章