/** *支付寶支付 * @param orderId 訂單編號 * @param actualPay 實際支付金額 * @return */ private String getOrderInfoByAliPay(String orderId,float actualPay) {
//回調頁面 String ali_call_back_url = propertiesService.ALI_CALL_BACK_URL; String seller_id = propertiesService.SELLER_ID;//商戶編號 String[] parameters={ "service=\"mobile.securitypay.pay\"",//固定值(手機快捷支付) "partner=\"2088421544444\"",//合作身份者ID(16位)
"_input_charset=\"utf-8\"", "notify_url=\""+ali_call_back_url+"\"",//通知地址 "out_trade_no=\""+orderId+"\"",//商戶內部訂單號 "subject=\"測試\"",//測試 "payment_type=\"1\"",//固定值 "seller_id=\""+seller_id+"\"",//賬戶郵箱 "total_fee=\""+"0.01"+"\"",//支付金額(元) "body=\"訂單說明\"",//訂單說明
"it_b_pay=\"30m\""(訂單過期時間 30分鐘過期無效) }; String signOrderUrl = signAllString(parameters); return signOrderUrl; }
/** * 支付寶簽名 * @param array * @return */ private String signAllString(String [] array){ StringBuffer sb = new StringBuffer(""); for (int i = 0; i < array.length; i++) { if(i==(array.length-1)){ sb.append(array[i]); }else{ sb.append(array[i]+"&"); } } System.out.println(sb.toString()); String sign = ""; try { sign = URLEncoder.encode(RSA.sign(sb.toString(), AlipayConfig.private_key, "utf-8"), "utf-8");//private_key私鑰 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } sb.append("&sign=\""+sign+"\"&"); sb.append("sign_type=\"RSA\""); return sb.toString(); }
package com.alipay.sign; import javax.crypto.Cipher; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
public class RSA{ public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; /** * RSA簽名 * @param content 待簽名數據 * @param privateKey 商戶私鑰 * @param input_charset 編碼格式 * @return 簽名值 */ public static String sign(String content, String privateKey, String input_charset) { try { byte[] decode = Base64.decode(privateKey); PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decode ); KeyFactory keyf= KeyFactory.getInstance("RSA"); PrivateKey priKey= keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(input_charset) ); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA驗簽名檢查 * @param content 待簽名數據 * @param sign 簽名值 * @param ali_public_key 支付寶公鑰 * @param input_charset 編碼格式 * @return 布爾值 */ public static boolean verify(String content, String sign, String ali_public_key, String input_charset) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] encodedKey = Base64.decode(ali_public_key); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(input_charset) ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 解密 * @param content 密文 * @param private_key 商戶私鑰 * @param input_charset 編碼格式 * @return 解密後的字符串 */ public static String decrypt(String content, String private_key, String input_charset) throws Exception { PrivateKey prikey = getPrivateKey(private_key); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, prikey); InputStream ins = new ByteArrayInputStream(Base64.decode(content)); ByteArrayOutputStream writer = new ByteArrayOutputStream(); //rsa解密的字節大小最多是128,將需要解密的內容,按128位拆開解密 byte[] buf = new byte[128]; int bufl; while ((bufl = ins.read(buf)) != -1) { byte[] block = null; if (buf.length == bufl) { block = buf; } else { block = new byte[bufl]; for (int i = 0; i < bufl; i++) { block[i] = buf[i]; } } writer.write(cipher.doFinal(block)); } return new String(writer.toByteArray(), input_charset); } /** * 得到私鑰 * @param key 密鑰字符串(經過base64編碼) * @throws Exception */ public static PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = Base64.decode(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } }
支付寶參數裏面爲什麼要進行轉義?主要是因爲返回給移動的參數結果是springmvc進行返回的給移動端時,會認爲"爲結束,所以需要\"進行轉義!