VISA 支付

springboot + Thymeleaf 做的 VISA 支付  做个笔记。

在开发中一直想行项目中抽离出来  

 以下是 大概的流程图

第一步先确定数据的发送

源码是这样的

package com.vb.controller;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.asiapay.secure.PaydollarSecureUtil;



/**
 * 此類將用於數據封裝提交到VISA
 * @author 
 *
 */
@Controller
public class OnliePay {
	/**
	 * The merchant ID we provide to you  百度翻譯 ----我们提供给你的商人身份证
	 * 
	 * 意思就是我們跟銀行申請支付功能,銀行反饋給我們這邊的id,來標識身份
	 */
	private static final String merchantId = "88061970";
	/**
	 * The currency of the payment i.e.
	 * 貨幣的類型
	 * “344” – HKD  港幣
		“840” – USD 美元
		“702” – SGD
		“156” – CNY (RMB)  毛爺爺
		“392” – JPY 日元
		“901” – TWD 
		“036” – AUD
		“978” – EUR
		“826” – GBP
		“124” – CAD 
	 */
    private static final String currCode = "344" ;
	
	
	@RequestMapping("/VISARequest")
	public ModelAndView virtualRequest(HttpServletRequest request,HttpServletResponse reponse) throws Exception{
		 Map<String, String> map = new ConcurrentHashMap<String,String>();
		 String bankId = "258465466";//插入數據庫生成的流水帳號id ,有助於客戶付款成功後返回給我們的唯一標識
		 String amount = "100";//支付銀行100塊錢
		 String payType = "N";//正常付款
		/**
		 * 必須获取加密的字符,作用餘銀行收錢成功後返回數據時,做校驗,以防安全隱患  里面源码访问secureHashSecret.config文件里面的字符 去生成
		 */
		String  secureHash = PaydollarSecureUtil.generatePaymentSecureHash(merchantId, bankId, currCode, amount, payType);
		
		map.put("amount", amount);
		map.put("merchantId", merchantId);
		map.put("secureHash", secureHash);
		map.put("orderRef", bankId);
		map.put("remark", "備註隨意");//不超過    Text (200)  字符
		return new ModelAndView("vbank/submitfFormBank","map",map);
	}
	
	
	
}

接下来就是跳到页面代码

扫描二维码关注公众号,回复: 8644442 查看本文章
<div style="margin-left: 25%; margin-top: 15%;">
	<h1>VISA支付demo參數</h1>
<!-- 	<form name="payFormCcard" method="post" action="https://www.paydollar.com/b2c2/eng/payment/payForm.jsp"> -->
	<form name="payFormCcard" method="post" action="http://192.168.41.58:8088/virtualBank/pay/virtualRequest">
		<input type="text" name="merchantId" th:value="${map.merchantId}"><br/>
		<input type="text" name="amount" th:value="${map.amount}" ><br/>
		<input type="text" name="orderRef" th:value="${map.orderRef}"><br/>
		<input type="text" name="remark" th:value="${map.remark}"><br/>
		<input type="text" name="secureHash" th:value="${map.secureHash}"><br/>
		
		<!-- 	
				支付方式 一下可以選  直接定義全部都可以
				“ALL” – All the available payment method
				“CC” – Credit Card Payment
				“PPS” – PayDollar PPS Payment
				“PAYPAL” – PayPal By PayDollar Payment
				“CUP” – PayDollar CUP Payment
				“ALIPAY” – PayDollar ALIPAY Payment 
		 -->
		<input type="hidden" name="payMethod" th:value="ALL" ><br/>
		<!-- 
			The payment card type ---》  支付卡类型
		可選 (“VISA”,“Master”,”Diners”,”JCB”, “AMEX”) 
			具體可參照文檔
		 -->
		<input type="text" name="pMethod" th:value="VISA" ><br/>
		<!-- 支付貨幣類型  344 HKD  156 RMB -->
		<input type="text" name="currCode" th:value="344" ><br/>
		<!-- 立即付款 ,具體可看文檔-->
		<input type="text" name="payType" th:value="N"><br/>
		<!-- 語言 E,英,C,中文  -->
		<input type="text" name="lang" th:value="E"><br/>
		
		<!-- 
			本項目給銀行返回的結果的連接,告知操作人支付成功還是失敗
			PS: 自定義連接
		 -->
		<input type="text" name="successUrl" value="http://www.yourdomain.com/Success.html"><br/>
		<input type="text" name="failUrl" value="http://www.yourdomain.com/Fail.html"><br/>
		<input type="text" name="cancelUrl" value="http://www.yourdomain.com/Cancel.html"><br/>
		
		<input type="submit" name="submit" value="提交">
	</form> 
	
	
	</div>

接下来第二步

package com.vb.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
@RequestMapping("/pay")
public class BankHandleAction {

	public String map;
	public static Map<String, String> paramMap =  new ConcurrentHashMap<String,String>();
	

 	@RequestMapping("/hello")
    @ResponseBody
    public String hello() {
        return "hello world2222";
    }
	//請求過來的請求
 	@RequestMapping("/virtualRequest")
	public ModelAndView virtualRequest(HttpServletRequest request,HttpServletResponse reponse){
 		 Map<String, String> map = new ConcurrentHashMap<String,String>();
		try {
			Enumeration<String> names = request.getParameterNames();
			while(names.hasMoreElements()){
				String name = names.nextElement();
				String value = request.getParameter(name);
				System.err.println(name+":"+value);
				paramMap.put(name, value);
				if(name.equals("failUrl")){
					map.put("failUrl", value);
				}
				if(name.equals("successUrl")){
					map.put("successUrl", value);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ModelAndView("vbank/bankhandle","map",map);
	}
 	/**
 	 * 支付成功
 	 * @param request
 	 * @param reponse
 	 * @return
 	 */
	@RequestMapping("/virtualSuccess")
	public void virtualSuccess(HttpServletRequest request,HttpServletResponse reponse){
		try {
			String merchantId=paramMap.get("merchantId");
			String orderRef=paramMap.get("orderRef");
			String currCode=paramMap.get("currCode");
			String amount=paramMap.get("amount"); 
			String payType=paramMap.get("payType"); 
			String secureHash=paramMap.get("secureHash"); 
			String errorUrl=paramMap.get("errorUrl"); 
			StringBuffer buffer = new StringBuffer();
			buffer.append(merchantId).append("|").append(orderRef)
			.append("|").append(currCode).append("|")
					.append(amount)
					.append("|")
					.append(payType).append("|")
					.append("YwkkhiEV55OLGKGRJ1RBBO3oA5OXS8M0");

				
			String hash =null;
				try {
					hash = operationAlgorithm(buffer.toString());
				} catch (NoSuchAlgorithmException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(!secureHash.equals(hash))
			{
				paramMap.put("successcode", "1");
				
			}else{
				paramMap.put("successcode", "0");
			}	
			new Thread(new Runnable() {
				String s = null;
				@Override
				public void run() {
					HttpURLConnection conn = null;
					PrintWriter out = null;
					BufferedReader reader = null;
						try {
							String query = buildQuery(paramMap, "utf-8");
							/**********************************注意此連接是銀行成功回調連接************************************/
							URL url = new URL("http://192.168.41.58:8088/virtualBank/VISAdataback");
							conn = (HttpURLConnection) url.openConnection();
							conn.setRequestMethod("POST");
							conn.setRequestProperty("Content-Length", "200000");
							conn.setRequestProperty("Accept", "application/json");
							conn.setRequestProperty("User-Agent", "top-sdk-java");
							conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
							conn.setRequestProperty("Connection", "keep-alive");
							conn.setConnectTimeout(5000);
							conn.setUseCaches(false);
							conn.setDoOutput(true);
							conn.setDoInput(true);
							conn.connect();
							out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
							out.write(query);
							out.flush();
							reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
							while(true){
								if((s=reader.readLine()) != null){
									System.err.println(s);
								}else{
									break ;
								}
							}
						} catch (IOException e) {
							e.printStackTrace();
						}finally{
							if(out != null){
								out.close();
							}
							if(reader != null){
								try {
									reader.close();
								} catch (IOException e) {
									e.printStackTrace();
								}
							}
							if(conn != null){
								conn.disconnect();
							}
						}
				}
			}).start();
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private static String buildQuery1(Map<String, String> params, String charset) throws IOException {
		if (params == null || params.isEmpty()) {
			return "";
		}
		StringBuilder query = new StringBuilder();
		Set<Entry<String, String>> set = params.entrySet();
		Iterator<Entry<String, String>> iterator = set.iterator();
		Boolean flag = true;
		while (iterator.hasNext()) {
			Entry<String,String> p = iterator.next();
			String name = p.getKey();
			String value = p.getValue();
			if(flag){
				query.append(name+"=").append(URLEncoder.encode(value, charset));
				flag = !flag;
			}else{
				query.append("&"+name+"=").append(URLEncoder.encode(value, charset));
			}
			
		}
		return query.toString();
	}
	
	public String operationAlgorithm(String secureData) throws NoSuchAlgorithmException,UnsupportedEncodingException {
		MessageDigest md = MessageDigest.getInstance("SHA-1");
		md.update(secureData.getBytes("utf-8"), 0, secureData.length());
		byte[] sha1hash = md.digest();
		return convertToHex(sha1hash);
	}

	private String convertToHex(byte[] data) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < data.length; i++) {
			int halfbyte = (data[i] >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				if ((0 <= halfbyte) && (halfbyte <= 9))
					buf.append((char) ('0' + halfbyte));
				else
					buf.append((char) ('a' + (halfbyte - 10)));
				halfbyte = data[i] & 0x0F;
			} while (two_halfs++ < 1);
		}
		return buf.toString();
	}
	private  String buildQuery(Map<String, String> params, String charset) throws IOException {
		if (params == null || params.isEmpty()) {
			return "";
		}

		String src = "0";
		String prc = "0";
		String successCode =params.get("successcode");	//0- succeeded, 1- failure, Others - error
		String ref = params.get("orderRef");
		String payRef = "123456789";	//paydollar支付编号	//PayDollar Payment Reference Number
		String amt = params.get("amount");	//交易金额											//Transaction Amount
		String cur = params.get("currCode");	//交易货币种类	344 - HKD ; 156 – CNY (RMB)											//Transaction Currency
		String payerAuth = "Y";	
		
		
		StringBuffer buffer = new StringBuffer();
		buffer.append(src).append("|").append(prc).append("|").append(
				successCode).append("|").append(ref)
				.append("|").append(payRef).append("|")
				.append(cur).append("|").append(amt).append("|")
				.append(payerAuth).append("|").append(
						"YwkkhiEV55OLGKGRJ1RBBO3oA5OXS8M0");

			
		String secureHash =null;
			try {
				 secureHash = operationAlgorithm(buffer.toString());
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		StringBuilder query = new StringBuilder();
		query.append("src=").append(URLEncoder.encode(src, charset));
		query.append("&prc=").append(URLEncoder.encode(prc, charset));
		query.append("&successcode=").append(URLEncoder.encode(params.get("successcode"), charset));
		query.append("&Ref=").append(URLEncoder.encode(ref, charset));
		query.append("&Ord=").append("12345678");
		query.append("&PayRef=").append(URLEncoder.encode(payRef, charset));
		query.append("&Amt=").append(URLEncoder.encode(params.get("amount"), charset));
		query.append("&Cur=").append(URLEncoder.encode(cur, charset));
		query.append("&payerAuth=").append(URLEncoder.encode(payerAuth, charset));
		query.append("&remark=").append(URLEncoder.encode(params.get("remark"), charset));
		query.append("&secureHash=").append(URLEncoder.encode(secureHash, charset));
		return query.toString();
	}
	
	public String getMap() {
		return map;
	}
	public void setMap(String map) {
		this.map = map;
	}

}

第三步

package com.vb.controller;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.asiapay.secure.PaydollarSecureUtil;

@Controller
public class DataBack {
	
	
	
	@RequestMapping("/VISAdataback")
	public void databack(HttpServletRequest request,HttpServletResponse reponse) throws Exception{
				System.out.println(request.getParameterMap()+"--------"
				+ request.getParameterNames()
				+"Ord="+request.getParameter("Ord")
				+"holder="+request.getParameter("Holder")
				+"Ref="+request.getParameter("Ref")
				+"successcode="+request.getParameter("successcode")
				+"remark="+request.getParameter("remark")
				+"PayRef="+request.getParameter("PayRef")
				+"Amt="+request.getParameter("Amt")
				+"src="+request.getParameter("src")
				+"prc="+request.getParameter("prc")
				+"Cur="+request.getParameter("Cur")
				+"payerAuth="+request.getParameter("payerAuth")
				+"secureHash="+request.getParameter("secureHash"));
				//打印
				Enumeration paramNames = request.getParameterNames();
				while (paramNames.hasMoreElements()) {
				        String name =(String) paramNames.nextElement();
				        String value = request.getParameter(name);  
				        System.out.println(name+"="+value);
				    }
		
				String reqsuccesscode = request.getParameter("successcode") == null ? "": request.getParameter("successcode");
				String reqremark = request.getParameter("remark") == null ? "": request.getParameter("remark");
				//付款成功標識
				if ("0".equals(reqsuccesscode)) {
						String src = request.getParameter("src");
						String prc = request.getParameter("prc");
						String successcode = request.getParameter("successcode");	//0- succeeded, 1- failure, Others - error
						String ref = request.getParameter("Ref");//银行的交易编号
						String payRef = request.getParameter("PayRef");	//paydollar支付编号	//PayDollar Payment Reference Number
						String amt = request.getParameter("Amt");	//交易金额											//Transaction Amount
						String cur = request.getParameter("Cur");	//交易货币种类	344 - HKD ; 156 – CNY (RMB)											//Transaction Currency
						String payerAuth = request.getParameter("payerAuth");	
						String[] secureHash = request.getParameterValues("secureHash");
						//解密過程 start 
						List tempList = new ArrayList();
						if (secureHash != null) {
							for (int k = 0; k < secureHash.length; k++) {
								if (secureHash[k].indexOf(",") > 0) {
									String[] data = secureHash[k].split(",");
									for (int j = 0; data != null & j < data.length; j++) {
										tempList.add(data[j]);
									}
								} else {
									tempList.add(secureHash[k]);
								}
							}
						}
						int size = tempList.size();
						if (size > 0) {
							secureHash = new String[size];
							for (int i = 0; i < size; i++) {
								secureHash[i] = (String) tempList.get(i);
							}
						}
						//解密的過程 end 
						//會看到密鑰會讀取   secureHashSecret.config  裏面有個 SHA 哈希,這個 是 開發者加 secureHashSecret 密過程中 加岩(添加自定字符串)   
						
						boolean verifyResult = PaydollarSecureUtil.verifyPaymentDatafeed(src, prc, successcode, ref,payRef, cur, amt, payerAuth, secureHash);
						
						if (verifyResult) {//匹配SHA1
							System.out.println("the same secureHash   匹配SHA1  成功");
						}else{
							System.out.println("not the same secureHash    匹配SHA1失败      ");
							return;
						}
						
						
						//接下來就 根據流水帳號去查詢,處理數據信息
						String bankId = request.getParameter("Ref")==null?"": request.getParameter("Ref"); //流水帐号id
						String reqAmount = request.getParameter("Amt") == null ? "": request.getParameter("Amt");//总金额
				
						//最後完成後得通知銀行已處理,否者銀行那邊會再次請求看文檔是知己 put  “ok” 就可以了
						PrintWriter pw1 = reponse.getWriter();
						pw1.write("OK");
						pw1.flush();
						pw1.close();
				}else {
					System.out.println("付款失敗");
					return;
				}
		
	}
	
	
	
	
	
	

}

时间有点紧急忙写完

项目源码以放github 官网    https://github.com/MJFuture/Springboot-VISA-PAy

以及相应的开发文档    1.pdf

任何问题欢迎留言

发布了33 篇原创文章 · 获赞 7 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/sinat_26987533/article/details/103407748
今日推荐