1. 程式人生 > >支付寶PC端二維碼支付(沙箱環境)

支付寶PC端二維碼支付(沙箱環境)

一,準備工作

jar
在這裡插入圖片描述

獲取以下內容:

1,APPID
2,支付寶閘道器
3,公鑰
4,私鑰
5,支付寶錢包賬號密碼

支付寶開放平臺:

https://openhome.alipay.com/platform/developerIndex.htm

在這裡插入圖片描述

在這裡根據規則設定私鑰和公鑰
在這裡插入圖片描述

下面有一個錢包下載二維碼,下載沙箱錢包後,檢視賬號密碼並登入買家賬號

在這裡插入圖片描述

在這裡插入圖片描述

二,配置檔案

將以上資訊填寫在下面配置

package com.ticket.config;

import java.io.FileWriter;
import java.io.IOException;

/* *
 *類名:AlipayConfig
 *功能:基礎配置類
 *詳細:設定帳戶有關資訊及返回路徑
 *修改日期:2017-04-05
 *說明:
 *以下程式碼只是為了方便商戶測試而提供的樣例程式碼,商戶可以根據自己網站的需要,按照技術文件編寫,並非一定要使用該程式碼。
 *該程式碼僅供學習和研究支付寶介面使用,只是提供一個參考。
 */

public class AlipayConfig {
	
//↓↓↓↓↓↓↓↓↓↓請在這裡配置您的基本資訊↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

	// 應用ID,您的APPID,收款賬號既是您的APPID對應支付寶賬號
	public static String app_id = "";
	
	// 商戶私鑰,您的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 = "";

	// 頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義引數,必須外網可以正常訪問
	//這裡地址為,支付成功之後跳轉的地址,同步
	public static String return_url = "http://localhost:8080/ticketsystem/alipayReturnNoticebill";

	// 簽名方式
	public static String sign_type = "RSA2";
	
	// 字元編碼格式
	public static String charset = "utf-8";
	
	// 支付寶閘道器
	public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
	
	// 支付寶閘道器
	public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑請在這裡配置您的基本資訊↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    /** 
     * 寫日誌,方便測試(看網站需求,也可以改成把記錄存入資料庫)
     * @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();
                }
            }
        }
    }
}


三,提交訂單後,支付

前端提交ajax提交

 @RequestMapping(value = "/applybill", produces = "text/html; charset=UTF-8",method=RequestMethod.POST)
		@ResponseBody
		public String goAlipay(Bill bill, HttpServletRequest request, HttpServletRequest response) throws Exception {
	    	HttpSession session = request.getSession();
	    	Admin user = (Admin) session.getAttribute("user");
	    	Gson gson = new Gson();
	    	
	    	//訂單儲存
	    	//省略業務程式碼

	    	//商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
	    	String out_trade_no =CommonUtil.ordernum();  
	    	
			//獲得初始化的AlipayClient
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

			//設定請求引數
			AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
			//這裡設定支付後跳轉的地址
			alipayRequest.setReturnUrl(AlipayConfig.return_url);
			//alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

			
			//付款金額,必填
			String total_amount = String.valueOf(bill.getTicketnum()*bill.getPrice());
			//訂單名稱,必填
			String subject ="使用者"+user.getAccount()+"影票訂單";
			//商品描述,可空
			String body = "使用者訂購商品個數:" + bill.getTicketnum();

			// 該筆訂單允許的最晚付款時間,逾期將關閉交易。取值範圍:1m~15d。m-分鐘,h-小時,d-天,1c-當天(1c-當天的情況下,無論交易何時建立,都在0點關閉)。 該引數數值不接受小數點, 如 1.5h,可轉換為 90m。
	    	String timeout_express = "5m";

			alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
					+ "\"total_amount\":\""+ total_amount +"\","
					+ "\"subject\":\""+ subject +"\","
					+ "\"body\":\""+ body +"\","
					+ "\"timeout_express\":\""+ timeout_express +"\","
					+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

			//請求
			String result = alipayClient.pageExecute(alipayRequest).getBody();

			return result;
		}

上面ajax請求之後,會返回result,我打印發現時一段html程式碼,我不處理它不跳轉,不知道為啥,我的處理方式:
在這裡插入圖片描述

請求之後,會進入支付頁面
在這裡插入圖片描述

使用沙箱錢包付款,
付款成功後,會進入你配置的非同步或者同步方法。

在這裡插入圖片描述

在這裡插入圖片描述

示例:非同步方法

/**
		 *
		 * @Title: AlipayController.java
		 * @Package com.sihai.controller
		 * @Description: 支付寶非同步 通知頁面
		 * Copyright: Copyright (c) 2017
		 * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY
		 *
		 * @author sihai
		 * @date 2018年11月23日 下午8:51:13
		 * @version V1.0
		 */
		/*@RequestMapping(value = "/alipayNotifyNotice")
		@ResponseBody
		public String alipayNotifyNotice(HttpServletRequest request, HttpServletRequest response) throws Exception {

			System.out.println("支付成功11111111111");

			//獲取支付寶POST過來反饋資訊
			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 = (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);
			}

			boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //呼叫SDK驗證簽名

			//——請在這裡編寫您的程式(以下程式碼僅作參考)——
			
			 實際驗證過程建議商戶務必新增以下校驗:
			1、需要驗證該通知資料中的out_trade_no是否為商戶系統中建立的訂單號,
			2、判斷total_amount是否確實為該訂單的實際金額(即商戶訂單建立時的金額),
			3、校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email)
			4、驗證app_id是否為該商戶本身。
			
			if(signVerified) {//驗證成功
				//商戶訂單號
				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");

				//付款金額
				String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

				if(trade_status.equals("TRADE_FINISHED")){
					//判斷該筆訂單是否在商戶網站中已經做過處理
					//如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程式
					//如果有做過處理,不執行商戶的業務程式

					//注意: 尚自習的訂單沒有退款功能, 這個條件判斷是進不來的, 所以此處不必寫程式碼
					//退款日期超過可退款期限後(如三個月可退款),支付寶系統傳送該交易狀態通知
				}else if (trade_status.equals("TRADE_SUCCESS")){
					//判斷該筆訂單是否在商戶網站中已經做過處理
					//如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程式
					//如果有做過處理,不執行商戶的業務程式

					//注意:
					//付款完成後,支付寶系統傳送該交易狀態通知

					// 修改叮噹狀態,改為 支付成功,已付款; 同時新增支付流水
					
				}
				System.out.println("111支付成功");

			}else {//驗證失敗
				
			}

			return "success";
		}*/