天天看點

java服務端和android支付寶支付

文檔中心:https://doc.open.alipay.com/

點右上角的進入文檔中心

java服務端和android支付寶支付

使用的你的支付寶賬号登入 ,實名認證後

點 開放者中心 -沙箱應用

java服務端和android支付寶支付

生成商戶應用公鑰和私鑰

https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1

生成後會儲存在本地

java服務端和android支付寶支付

點沙箱應用中RSA2秘鑰 設定公用秘鑰

java服務端和android支付寶支付

把本地生成的應用公鑰填進去,會自動生成應用公鑰和支付寶公鑰

下載下傳 手機網站支付SDK&Demo:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.mS4BOD&treeId=193&articleId=105910&docType=1

AlipayConfig配置

public class AlipayConfig {
	// 沙箱應用appid 
	//public static String APPID = "";
	//正式線上應用appid
	public static String APPID = "";
	// 應用私鑰 pkcs8格式的
	public static String RSA_PRIVATE_KEY = "xxxx"
	// 伺服器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常通路
	public static String notify_url = "http://xxxxx/notifyCallback.do";
	// 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常通路
	// 商戶可以自定義同步跳轉位址
	public static String return_url = "http://xxxx/return_url.jsp";
	// return_url.jsp";
	// 請求網關位址
	// public static String URL = "https://openapi.alipay.com/gateway.do";
	//沙箱測試網關
	public static String URL = "https://openapi.alipaydev.com/gateway.do";
	// 編碼
	public static String CHARSET = "UTF-8";
	// 傳回格式
	public static String FORMAT = "json";
	// 支付寶公鑰 不是應用公鑰 
	// 沙箱測試支付寶公鑰
	// public static String ALIPAY_PUBLIC_KEY ="xXXXx"//
	//正式線上支付寶公鑰
	public static String ALIPAY_PUBLIC_KEY = "xxxx"// 
	//日志記錄目錄
	public static String log_path = "/log";
	// RSA2
	public static String SIGNTYPE = "RSA2";
}
           
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;

/**
 * API調用用戶端工廠
 * 
 * @author taixu.zqq
 * @version $Id: AlipayAPIClientFactory.java, v 0.1 2014年7月23日 下午5:07:45
 *          taixu.zqq Exp $
 */
public class AlipayAPIClientFactory {

	/** API調用用戶端 */
	private static AlipayClient alipayClient;

	/**
	 * 獲得API調用用戶端
	 * 
	 * @return
	 */
	public static AlipayClient getAlipayClient() {

		if (null == alipayClient) {
			// 執行個體化用戶端
			alipayClient = new DefaultAlipayClient(AlipayConfig.URL,
					AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY,
					AlipayConfig.FORMAT, AlipayConfig.CHARSET,
					AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
		}
		return alipayClient;
	}
}
           

app支付服務端

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.Y845Da&treeId=54&articleId=106370&docType=1

生成APP支付訂單資訊(orderInfo)

/**
	 * JAVA服務端SDK生成APP支付訂單資訊
	 * https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.y7E1BI&
	 * apiId=1046&docType=4
	 * 
	 * @param body
	 *            商品描述,可空
	 * @param subject
	 * @param out_trade_no
	 *            商戶訂單号,商戶網站訂單系統中唯一訂單号,必填
	 * @param total_amount
	 *            付款金額,必填
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/appbuildOrder", produces = "text/html;charset=UTF-8", method = RequestMethod.GET)
	public String aliAppPay(String body, String subject, String out_trade_no, String total_amount) {
		try {
			// 中文亂碼處理,不做處理可能會導緻異步回調驗證失敗
			body = new String(body.getBytes("ISO-8859-1"), "utf-8");
			subject = new String(subject.getBytes("ISO-8859-1"), "utf-8");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 獲得API調用用戶端
		AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClient();

		// 執行個體化具體API對應的request類,類名稱和接口名稱對應,目前調用接口名稱:alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		// SDK已經封裝掉了公共參數,這裡隻需要傳入業務參數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

		// 對交易或商品的描述
		model.setBody(body);
		// 賣家支付寶使用者ID。 如果該值為空,則預設為商戶簽約賬号對應的支付寶使用者ID
		// model.setSellerId("2088102170333051");
		// 訂單标題
		model.setSubject(subject);
		// 商戶訂單号,64個字元以内
		model.setOutTradeNo(out_trade_no);
		// 逾時時間 可空
		model.setTimeoutExpress("2m");
		// 訂單總金額 必須
		model.setTotalAmount(total_amount);
		// 銷售産品碼 必填
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		// 支付異步通知位址
		request.setNotifyUrl(AlipayConfig.notify_url);

		String form = "";

		try {
			// 這裡和普通的接口調用不同,使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			System.out.println(response.getBody());// 就是orderString
													// 可以直接給用戶端請求,無需再做處理。
			form = response.getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return form;
	}
           

異步回調通知

/**
	 * 支付統一回調接口
	 * https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.afod0z&
	 * treeId=193&articleId=105301&docType=1 異步通知位址
	 * 收到支付成功異步通知要回複success,否則導緻支付寶重發數次通知,重發通知伺服器異步通知參數notify_id是不變的。
	 * 
	 * @param request
	 */
	@ResponseBody
	@RequestMapping(value = "notifyCallback", produces = "text/html;charset=UTF-8")
	public String notifyCallback(HttpServletRequest request) throws Exception {
		// 擷取支付寶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] + ",";
			}
			// 亂碼解決,這段代碼在出現亂碼時使用。
			// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			params.put(name, valueStr);
		}
		String subject = params.get("subject");
		String body = params.get("body");
		String gmt_create = params.get("gmt_create");
		String gmt_payment = params.get("gmt_payment");
		String gmt_refund = params.get("gmt_refund");
		String refund_fee = params.get("refund_fee");
		String gmt_close = params.get("gmt_close");
		String fund_bill_list = params.get("fund_bill_list");
		String trade_status = params.get("trade_status");
		String out_trade_no = params.get("out_trade_no");
		String trade_no = params.get("trade_no");
		String notify_time = params.get("notify_time");
		String notify_id = params.get("notify_id");
		// 商戶業務ID,主要是退款通知中傳回退款申請的流水号
		String out_biz_no = params.get("out_biz_no");
		String buyer_id = params.get("buyer_id");
		String seller_id = params.get("seller_id");
		String total_amount = params.get("total_amount");
		String receipt_amount = params.get("receipt_amount");
		String invoice_amount = params.get("invoice_amount");

		System.out.println(params.toString());
		System.out.println("支付寶回調位址!");
		System.out.println("訂單标題:" + subject);
		System.out.println("商品描述:" + body);
		System.out.println("交易建立時間:" + gmt_create);
		System.out.println("交易付款時間:" + gmt_payment);
		System.out.println("交易退款時間:" + gmt_refund);
		System.out.println("交易結束時間:" + gmt_close);
		System.out.println("商戶的訂單編号:" + out_trade_no);
		System.out.println("支付寶交易号:" + trade_no);
		System.out.println("支付的狀态:" + trade_status);
		System.out.println("通知時間:" + notify_time);
		System.out.println("通知校驗ID:" + notify_id);
		System.out.println("商戶業務号:" + out_biz_no);
		System.out.println("買家支付寶使用者号:" + buyer_id);
		System.out.println("賣家支付寶使用者号:" + seller_id);
		System.out.println("訂單金額:" + total_amount);
		System.out.println("實收金額:" + receipt_amount);
		System.out.println("開票金額:" + invoice_amount);
		System.out.println("支付金額資訊:" + fund_bill_list);
		System.out.println("總退款金額:" + refund_fee);

		// 切記
		// AlipayConfig.ALIPAY_PUBLIC_KEY是支付寶的公鑰,不是應用公鑰,請去open.alipay.com對應應用下檢視。
		boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET,
				AlipayConfig.SIGNTYPE);
		// 驗證失敗可能原因:AlipayConfig.ALIPAY_PUBLIC_KEY是支付寶的公鑰,不是應用公鑰,請去open.alipay.com對應應用下檢視
		// 建立訂單時請求字段有亂碼,異步回調才去進行中文亂碼,導緻驗證失敗(解決建立訂單進行中文亂碼,異步回調不處理)

		if (verify_result) {// 驗證成功
			//
			// 請在這裡加上商戶的業務邏輯程式代碼
			System.out.println("-----驗證成功----");

			// 注意:
			// 狀态TRADE_SUCCESS的通知觸發條件是商戶簽約的産品支援退款功能的前提下,買家付款成功;
			// 交易狀态TRADE_FINISHED的通知觸發條件是商戶簽約的産品不支援退款功能的前提下,買家付款成功;或者,商戶簽約的産品支援退款功能的前提下,交易已經成功并且已經超過可退款期限。
			if (trade_status.equals("TRADE_FINISHED")) {
               //業務處理
			} else if (trade_status.equals("TRADE_SUCCESS")) {
                //支付成功業務處理
			} else if (trade_status.equals("TRADE_CLOSED")) {// 當商戶使用站内退款時,系統會發送包含refund_status和gmt_refund字段的通知給商戶。
				if(StringUtils.isNotBlank(out_biz_no)){
					//退款業務處理
				}
			}

			return "success";

			//
		} else {
			System.out.println("-----驗證失敗----");
			return "failure";
		}

	}
}
           

android端

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.b71f3q&treeId=193&articleId=105296&docType=1

沙箱測試

app支付隻支援Android版接入,在使用sdk時,在支付接口前調用如下方法 

EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

http請求伺服器生成orderInfo

OkHttpUtils.get().url(AppURL.buildOrder_url)
                .addParams("body", "我是商品描述")
                .addParams("subject", "iphone7")
                .addParams("out_trade_no", System.currentTimeMillis() + "")
                .addParams("total_amount", "1000")
                .build().execute(new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {
                Toast.makeText(PayDemoActivity.this,
                        "訂單建立失敗", Toast.LENGTH_SHORT)
                        .show();
            }

            @Override
            public void onResponse(String response, int id) {
                if (!TextUtils.isEmpty(response)) {
                    final String orderInfo = response;
                    Runnable payRunnable = new Runnable() {

                        @Override
                        public void run() {
                            PayTask alipay = new PayTask(PayDemoActivity.this);
                            Map<String, String> result = alipay.payV2(orderInfo, true);
                            Log.i("msp", result.toString());

                            Message msg = new Message();
                            msg.what = SDK_PAY_FLAG;
                            msg.obj = result;
                            mHandler.sendMessage(msg);
                        }
                    };

                    Thread payThread = new Thread(payRunnable);
                    payThread.start();
                } else {
                    Toast.makeText(PayDemoActivity.this,
                            "訂單建立失敗", Toast.LENGTH_SHORT)
                            .show();
                }
            }
        });
           

電腦網站支付

/**
	 * JAVA服務端SDK生成pc支付訂單資訊
	 * https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.PeSXkv&
	 * treeId=193&articleId=105899&docType=1
	 * 
	 * @param body
	 *            商品描述,可空
	 * @param subject
	 * @param out_trade_no
	 *            商戶訂單号,商戶網站訂單系統中唯一訂單号,必填
	 * @param total_amount
	 *            付款金額,必填
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/WebPagebuildOrder", produces = "text/html;charset=UTF-8", method = RequestMethod.POST)
	public String aliWebPagePay(String webbody, String subject, String out_trade_no, String total_amount) {
		// 獲得API調用用戶端
		AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClient();

		AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();// 建立API對應的request

		AlipayTradePagePayModel model = new AlipayTradePagePayModel();

		// 對交易或商品的描述
		model.setBody(webbody);
		// 賣家支付寶使用者ID。 如果該值為空,則預設為商戶簽約賬号對應的支付寶使用者ID
		// model.setSellerId("2088102170333051");
		// 訂單标題
		model.setSubject(subject);
		// 商戶訂單号,64個字元以内
		model.setOutTradeNo(out_trade_no);
		// 逾時時間 可空
		model.setTimeoutExpress("2m");
		// 訂單總金額 必須
		model.setTotalAmount(total_amount);
		// 銷售産品碼 必填
		model.setProductCode("FAST_INSTANT_TRADE_PAY");
		request.setBizModel(model);

		request.setReturnUrl(AlipayConfig.return_url);
		request.setNotifyUrl(AlipayConfig.notify_url);// 在公共參數中設定回跳和通知位址

		// alipayRequest.setBizContent("{" + "
		// \"out_trade_no\":\"20150320010101001\","
		// + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + "
		// \"total_amount\":88.88,"
		// + " \"subject\":\"Iphone6 16G\"," + " \"body\":\"Iphone6 16G\","
		// + "
		// \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\","
		// + " \"extend_params\":{" + "
		// \"sys_service_provider_id\":\"2088511833207846\"" + " }" + " }");//
		// 填充業務參數
		String form = "";
		try {
			form = alipayClient.pageExecute(request).getBody(); // 調用SDK生成表單
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}

		return form;
	}
           

jsp

<div id="main">
        <form name=alipayment action='${pageContext.request.contextPath}/pay/WebPagebuildOrder.do' method=post target="_blank">
            <div id="body" style="clear:left">
                <dl class="content">
                    <dt>商戶訂單号:</dt>
                    <dd>
                        <input id="out_trade_no" name="out_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>訂單名稱:</dt>
                    <dd>
                        <input id="subject" name="subject" />
                    </dd>
                    <hr class="one_line">
                    <dt>付款金額:</dt>
                    <dd>
                        <input id="total_amount" name="total_amount" />
                    </dd>
                    <hr class="one_line"/>
                    <dt>商品描述:</dt>
                    <dd>
                        <input id="webbody" name="webbody" />
                    </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>
        <div id="foot">
			<ul class="foot-ul">
				<li>
					支付寶版權所有 2015-2018 ALIPAY.COM 
				</li>
			</ul>
		</div>
	</div>
</body>
<script language="javascript">
	function GetDateNow() {
		var vNow = new Date();
		var sNow = "";
		sNow += String(vNow.getFullYear());
		sNow += String(vNow.getMonth() + 1);
		sNow += String(vNow.getDate());
		sNow += String(vNow.getHours());
		sNow += String(vNow.getMinutes());
		sNow += String(vNow.getSeconds());
		sNow += String(vNow.getMilliseconds());
		document.getElementById("out_trade_no").value =  sNow;
		document.getElementById("subject").value = "Iphone6 16G";
		document.getElementById("total_amount").value = "100";
        document.getElementById("webbody").value = "Iphone6 16G";
	}
	GetDateNow();
</script>
           

http://blog.csdn.net/qq_22484755/article/details/53126353?locationNum=9&fps=1

支付寶沙箱測試-ALI40247

http://blog.csdn.net/huyuchaoheaven/article/details/56280978