亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)支付功能附源碼

 更新時間:2020年11月20日 11:12:49   作者:丶漠然  
這篇文章主要介紹了SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)功能支付附源碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言

提示:這里可以添加本文要記錄的大概內(nèi)容:
例如:隨著人工智能的不斷發(fā)展,機器學(xué)習(xí)這門技術(shù)也越來越重要,很多人都開啟了學(xué)習(xí)機器學(xué)習(xí),本文就介紹了機器學(xué)習(xí)的基礎(chǔ)內(nèi)容。

提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、官網(wǎng)

https://open.unionpay.com/tjweb/user/mchTest/param 個人登錄后的相關(guān)參數(shù)查看

在這里插入圖片描述

其實在接入支付之前建議大家了解下 對稱加密,分對稱加密RSA之類,摘要算法,https,證書等這些知識點,因為此代碼后面的驗簽,判斷都是基于此的。初始化加載證書,判斷證書是否正確,過期,是否被串改都需要上面知識的支撐

二、使用步驟

1.下載官方提供的代碼

https://open.unionpay.com/tjweb/acproduct/list?apiSvcId=449&index=5
支持3個語言的接入,這里只說java版本的。而且后面我也對代碼進行了重構(gòu),畢竟demo的項目還是無法直接嵌入到生產(chǎn)項目中

在這里插入圖片描述

項目展示(示例):因為我接入的是token版本的,所以都是查看token的代碼,銀聯(lián)的支付涉及web 和token兩種,大同小異,只是涉及到傳入的參數(shù)類型不一樣而已

在這里插入圖片描述

2.目錄說明【一定要對著項目結(jié)構(gòu)認(rèn)真看這段內(nèi)容】

ACPSample-WuTiaoZhuan

├src┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈類文件夾
│ │
│ ├assets ┈┈┈┈┈┈┈┈┈相關(guān)資源目錄
│ │ │
│ ├assets ┈┈┈┈┈┈┈┈┈相關(guān)資源目錄
│ │ │
│ │ ├apache_httpclient┈┈┈┈┈┈┈┈┈apache中的http post方法
│ │ │
│ │ ├測試環(huán)境證書
│ │ │ │
│ │ │ ├acp_test_enc.cer ┈┈┈┈┈┈┈┈┈ 【重要】測試環(huán)境敏感信息加密證書(所有商戶固定使用同一個)
│ │ │ │
│ │ │ ├acp_test_sign.pfx ┈┈┈┈┈┈┈┈┈ 【重要】 測試環(huán)境簽名私鑰證書(所有商戶固定使用同一個)
│ │ │ │
│ │ │ ├acp_test_root.cer ┈┈┈┈┈┈┈┈┈ 【重要】 測試環(huán)境驗簽公鑰證書根證書 (所有商戶固定使用同一個)
│ │ │ │
│ │ │ └acp_test_middle.cer ┈┈┈┈┈┈┈┈┈【重要】 測試環(huán)境驗簽公鑰證書中級證書 (所有商戶固定使用同一個)
│ │ │
│ │ ├對賬文件樣例
│ │ │ │
│ │ │ └802310048993424_20150905.zip ┈┈┈┈┈┈┈┈┈提供的對賬文件樣例(如果需要可以參考)
│ │ │
│ │ ├收單機構(gòu)接入需做改動
│ │ │ │
│ │ │ ├acp_test_sign_inst.pfx ┈┈┈┈┈┈┈┈┈【重要】 收單機構(gòu)接入的測試環(huán)境簽名私鑰證書(所有機構(gòu)固定使用同一個)
│ │ │ │
│ │ │ └機構(gòu)接入需做改動.txt
│ │ │
│ │ ├測試環(huán)境配置文件
│ │ │ │
│ │ │ └acp_sdk.properties ┈┈┈┈┈┈┈┈┈【重要】 測試環(huán)境配置文件樣例(證書方式簽名)(使用方式請看文件里的說明)
│ │ │
│ │ ├生產(chǎn)環(huán)境配置文件
│ │ │ │
│ │ │ └acp_sdk.properties ┈┈┈┈┈┈┈┈┈【重要】 生產(chǎn)環(huán)境配置文件樣例(證書方式簽名)(使用方式請看文件里的說明)
│ │ │
│ │ └生產(chǎn)環(huán)境證書
│ │ │
│ │ ├acp_prod_enc.cer┈┈┈┈┈┈┈┈┈【重要】 生產(chǎn)環(huán)境敏感信息加密證書(所有商戶固定使用同一個)
│ │ │
│ │ ├acp_prod_root.cer ┈┈┈┈┈┈┈┈┈【重要】 生產(chǎn)環(huán)境驗簽公鑰根證書 (所有商戶固定使用同一個)
│ │ │
│ │ └acp_prod_middle.cer ┈┈┈┈┈┈┈┈┈【重要】 生產(chǎn)環(huán)境驗簽公鑰中級證書 (所有商戶固定使用同一個)
│ │
│ ├com.unionpay.acp.demo
│ │ │
│ │ ├token ┈┈┈┈┈┈┈┈┈無跳轉(zhuǎn)token交易相關(guān)
│ │ │ │
│ │ │ ├Form03_6_2_Token_OpenCard_Back.java┈┈┈┈┈商戶側(cè)開通示例類(后臺)
│ │ │ │
│ │ │ ├Form03_6_2_Token_OpenCard_Front.java┈┈┈┈┈銀聯(lián)側(cè)開通示例類(前臺)
│ │ │ │
│ │ │ ├Form03_6_3_Token_OpenQuery.java┈┈┈┈┈開通查詢示例類(后臺)
│ │ │ │
│ │ │ ├Form03_6_4_Token_DeleteToken.java┈┈┈┈┈刪除token示例類(后臺)
│ │ │ │
│ │ │ ├Form03_6_5_Token_UpdateToken.java┈┈┈┈┈更新token示例類(后臺)
│ │ │ │
│ │ │ ├Form03_6_6_Token_ConsumeSMS.java┈┈┈┈┈消費短信示例類(后臺)
│ │ │ │
│ │ │ ├Form03_6_6_Token_OpenSMS.java┈┈┈┈┈開通短信示例類 (后臺)
│ │ │ │
│ │ │ ├Form03_6_7_Token_Consume.java┈┈┈┈┈消費示例類 (后臺)
│ │ │ │
│ │ │ ├Form03_6_7_Token_OpenAndConsume.java┈┈┈┈┈開通并付款示例類 (前臺)
│ │ │ │
│ │ │ └Form03_6_Token_ApplyToken.java┈┈┈┈申請toke號示例類 (前臺)
│ │ │
│ │ ├BackRcvResponse.java┈┈┈┈┈后臺通知處理示例類
│ │ │
│ │ ├DemoBase.java┈┈┈┈┈基礎(chǔ)類
│ │ │
│ │ ├EncryptCerUpdateQuery.java┈┈┈┈┈加密證書更新示例類(后臺)
│ │ │
│ │ ├Form03_6_3_ConsumeUndo.java┈┈┈┈┈消費撤銷示例類 (后臺)
│ │ │
│ │ ├Form03_6_4_Refund.java┈┈┈┈┈退貨示例類 (后臺)
│ │ │
│ │ ├Form03_6_5_Query.java┈┈┈┈┈交易狀態(tài)查詢示例類 (后臺)
│ │ │
│ │ ├Form03_7_FileTransfer.java┈┈┈┈┈對賬文件下載示例(后臺)
│ │ │
│ │ ├FrontRcvResponse.java┈┈┈┈┈前臺通知處理示例類
│ │ │
│ │ └多個商戶號各自使用自己的私鑰證書(多證書)使用方法.txt
│ │
│ ├com.unionpay.acp.sdk
│ │ │
│ │ ├AcpService.java┈┈┈┈┈┈全渠道SDK API接口類
│ │ │
│ │ ├CertUtil.java┈┈┈┈┈┈證書處理工具類
│ │ │
│ │ ├HttpClient.java┈┈┈┈┈后臺交易http post通訊類,如果要使用代理訪問或者產(chǎn)生了問題那么可以自行解決或者使用apache httpClient
│ │ │
│ │ ├LogUtil.java┈┈┈┈┈日志工具類
│ │ │
│ │ ├SDKConfig.java┈┈┈┈┈┈┈讀取acp_sdk.properties屬性文件并填裝配置的屬性的配置類
│ │ │
│ │ ├SDKConstants.java┈┈┈┈┈┈┈常量類
│ │ │
│ │ ├SDKUtil.java┈┈┈┈┈┈┈SDK工具類,包含了對報文的簽名,驗簽等方法
│ │ │
│ │ ├SecureUtil.java┈┈┈┈┈┈┈安全相關(guān)工具類
│ │ │
│ │ └SM3Digest.java┈┈┈┈┈┈┈sm3算法工具類
│ │
│ └web ┈┈┈┈┈┈┈┈┈ web相關(guān)類
│ │
│ ├AutoLoadServlet.java ┈┈┈┈┈┈初始化讀取acp_sdk.properties初始化請求銀聯(lián)地址,證書等相關(guān)資源的servlet
│ │
│ └CharsetEncodingFilter.java ┈┈┈┈web請求編碼過濾器

├acp_sdk.properties ┈┈┈┈【重要】測試環(huán)境配置文件,請求銀聯(lián)地址,私鑰簽名證書,驗簽公鑰路徑,多證書的配置文件(這個文件切換生產(chǎn)的時候要替換成生產(chǎn)環(huán)境的配置文件)

├log4j.properties ┈┈┈┈LogUtil.java日志工具類的配置文件

├WebContent ┈┈┈┈┈┈┈┈┈┈┈┈┈┈頁面文件夾
│ │
│ ├index.jsp ┈┈┈┈┈┈┈┈┈調(diào)試入口頁面
│ │
│ └WEB-INF
│ │
│ └lib(如果JAVA項目中包含這些架包,則不需要導(dǎo)入)
│ │
│ ├bcprov-jdk15on-1.54.jar---------注意包名后綴版本,低版本的bc包不支持sdk使用的部分方法
│ │
│ ├commons-codec-1.6.jar
│ │
│ ├commons-io-2.2.jar
│ │
│ ├commons-lang-2.5.jar
│ │
│ ├log4j-1.2.17.jar
│ │
│ ├slf4j-api-1.5.11.jar
│ │
│ └slf4j-log4j12-1.5.11.jar

└readme.txt ┈┈┈┈┈┈┈┈┈使用說明文本

───────────
注意

1.【接口規(guī)范】該接口參考文檔位置:
接口產(chǎn)品規(guī)范:open.unionpay.com幫助中心 下載 產(chǎn)品接口規(guī)范 《無跳轉(zhuǎn)產(chǎn)品接口規(guī)范》
應(yīng)答碼規(guī)范:《平臺接入接口規(guī)范-第5部分-附錄》
商戶對賬文件格式說明:《全渠道平臺接入接口規(guī)范 第3部分 文件接口》

2.【測試商戶號】開發(fā)包中使用的商戶號777290058110097是open.unionpay.com注冊的測試商戶號,只能在入網(wǎng)測試環(huán)境使用;
可以先使用這個商戶調(diào)通交易(當(dāng)然您也可以自己在這個網(wǎng)站注冊一個777開頭的測試商戶號,自己注冊后要開通權(quán)限:https://open.unionpay.com 登陸后 右上角我的測試-我的產(chǎn)品-將未測試的產(chǎn)品點擊成測試狀態(tài),過10分鐘后就有權(quán)限了)
正式線上環(huán)境請?zhí)鎿Q成申請的正式商戶號,并確保商戶號有對應(yīng)的權(quán)限,如果報了無此交易權(quán)限等錯誤,請聯(lián)系您申請接入銀聯(lián)的業(yè)務(wù)人員確認(rèn)您做的交易是否開通了對應(yīng)的權(quán)限。

3.【關(guān)于配置文件】
配置文件在src/assets文件夾下可以找到,src下面默認(rèn)使用的是測試環(huán)境使用證書方式簽名的配置文件。請按配置文件中的說明進行修改。
使用時需要配置證書路徑,證書文件除了生產(chǎn)環(huán)境的簽名證書需要業(yè)務(wù)郵件發(fā)送下載方式下載,其余證書均在src/assets文件夾下面有提供,需要復(fù)制到配置文件配置的路徑。

4.【測試過程遇到問題】
1)優(yōu)先在open平臺中查找答案:
調(diào)試過程中的問題或其他問題請在 https://open.unionpay.com/ajweb/help/faq/list 幫助中心 FAQ 搜索解決方案
測試過程中產(chǎn)生的7位應(yīng)答碼問題疑問請在https://open.unionpay.com/ajweb/help/respCode/respCodeList 輸入應(yīng)答碼搜索解決方案
2)測試環(huán)境測試支付請使用測試卡號測試, FAQ搜索“測試卡”。
3)切換生產(chǎn)環(huán)境要點請FAQ搜索“切換”。

5.【生產(chǎn)環(huán)境遇到問題】連接銀聯(lián)生產(chǎn)環(huán)境測試遇到的問題 如果通過open平臺無法解決 請登陸merchant.unionpay.com 菜單"服務(wù)單管理"->"創(chuàng)建服務(wù)單"請求排查問題。

3. 配置項目啟動相關(guān)參數(shù)

由于項目啟動需要驗證各種類型的證書,在本地他會找磁盤路徑的證書位置,需要大家將 assert目錄的證書拷貝到磁盤中 并對應(yīng)到配置文件中的路徑上 如下

在這里插入圖片描述

4. 依賴jar

因為當(dāng)前的項目不是一個maven項目只是一個普通的web項目,會涉及各種的jar依賴,大家自行配置項目中的web路徑下lib目錄,其中如果有問題請看當(dāng)下目錄的說明文件

在這里插入圖片描述

5.tomcat啟動項目

在這里插入圖片描述

在這里插入圖片描述

其實銀聯(lián)的這個文檔寫的還是相當(dāng)不錯的。就是在接的過程中他涉及的各種問題就是需要自己去體會理解。畢竟是老的版本,所以有些技術(shù)細(xì)節(jié)還是跟當(dāng)下不一樣的,比如傳參居然不是json。

6.支付 項目已經(jīng)正常啟動,那么帶大家了解下他的支付流程,這里先簡單介紹下,后面直接上代碼。其實所有的支付無非就是生產(chǎn)訂單,請求第三方支付定義的接口,傳遞規(guī)范的參數(shù),然后支付方會返回一個同步通知,還有一個異步通知,在這兩個通知中實現(xiàn)你的業(yè)務(wù)處理。

== 同步,異步通知 都是需要外網(wǎng)能夠訪問的連接地址,所以你需要一個內(nèi)網(wǎng)穿透工具,之前我一直在用natapp,https://blog.csdn.net/hu15081398237/article/details/94721290 這里面有我介紹使用natapp接入微信的步驟, 今天在這里使用的是uTools https://u.tools/docs/guide/about-uTools.html 它提供穿透功能==

在這里插入圖片描述
在這里插入圖片描述

當(dāng)你項目啟動成功,然后使用當(dāng)前工具映射地址即可成功,然后你就可以使用鏈接訪問自己項目。此項目能被外網(wǎng)訪問

在這里插入圖片描述

7.銀聯(lián)自己的項目代碼簡單介紹

建議大家先看下他們的代碼,跑通后在自己整合,我們是大致瞅了一眼,我們架構(gòu)就開始封裝了,畢竟是大佬,但是后面我們也踩坑,我又調(diào)用它原始代碼,分析入?yún)?,出參,結(jié)合我們的代碼分析問題,一般都是出在了參數(shù)傳遞問題

在這里插入圖片描述

在你都接入好后,需要用他們提供的信息進行測試,有問題就到這個地址找,搜索。銀聯(lián)這方面還是做得不錯的
https://open.unionpay.com/tjweb/support/faq/mchlist?id=4

在這里插入圖片描述

8.整合后的SpringBoot項目

在這里插入圖片描述
在這里插入圖片描述

自定義starter初始化項目

在這里插入圖片描述

注意 相當(dāng)于jdk spi,doubo spi 的特性:

在這里插入圖片描述

9.springboot項目啟動

在這里插入圖片描述

10.支付講解,先看圖,后面有Demo代碼,注釋很清楚

在這里插入圖片描述
在這里插入圖片描述

上面填寫的參數(shù)就是如下需要的信息

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

11.示例代碼講解

package com.ehs.union.pay.spring.boot.demo.controller;

import com.esh.union.pay.sdk.bean.config.UnionPayConfig;
import com.esh.union.pay.sdk.bean.consts.*;
import com.esh.union.pay.sdk.bean.request.UnionOpenAllChannelAndPayRequest;
import com.esh.union.pay.sdk.service.UnionPayService;
import com.esh.union.pay.sdk.utils.UnionStrUtil;
import com.esh.union.pay.sdk.utils.sign.CertDescriptor;
import com.esh.union.pay.sdk.utils.sign.UnionSecureUtil;
import com.esh.union.pay.sdk.utils.sign.UnionSignUtil;
import com.esh.union.pay.sdk.utils.sign.encrypt.RSA2;
import com.esh.union.pay.sdk.utils.sign.encrypt.X509;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.PrivateKey;
import java.util.*;

/**
 * 無跳轉(zhuǎn)支付
 *
 * @author huyufan
 * @date 2020/11/8 16:49
 */
@Controller
@RequestMapping(value = "/pay")
public class PayController {

 protected static final Logger log = LoggerFactory.getLogger(PayController.class);

 @Autowired
 private UnionPayService unionPayService;

 @Autowired
 private CertDescriptor certDescriptor;


 /**
 * 支付請求 TO 銀聯(lián)
 * @param resp
 * @param openAllChannelAndPayRequest
 */
 @RequestMapping(value = "/yinlian", method = RequestMethod.POST)
 public void toYinlianPay(HttpServletResponse resp, @ModelAttribute(value = "openAllChannelAndPayRequest") UnionOpenAllChannelAndPayRequest openAllChannelAndPayRequest) {
 UnionPayConfig config = unionPayService.getConfig();
 CertDescriptor certDescriptor = unionPayService.getCertDescriptor();
 openAllChannelAndPayRequest.setBizType(UnionBizTypeConsts.BIZ_TYPE_000902);
 openAllChannelAndPayRequest.setTxnTime(DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"));
 //TODO 后臺異步回調(diào),暫未實現(xiàn) backUrl 默認(rèn)填官方要求的默認(rèn)值,否則會校驗
 openAllChannelAndPayRequest.setBackUrl(config.getBackUrl());
 openAllChannelAndPayRequest.setCurrencyCode("156");
 openAllChannelAndPayRequest.setTxnType(UnionTxnTypeConsts.TXN_TYPE_01);
 openAllChannelAndPayRequest.setTxnSubType(UnionTxnSubTypeConsts.TXN_SUB_TYPE_01);
 openAllChannelAndPayRequest.setAccessType(UnionAccessTypeConsts.ACCESS_TYPE_0);
 openAllChannelAndPayRequest.setSignature(UnionSignMethodConsts.SIGNMETHOD_01);
 openAllChannelAndPayRequest.setChannelType(UnionChannelTypeConsts.CHANNEL_TYPE_07);
 openAllChannelAndPayRequest.setAccType(UnionAccTypeConsts.ACC_TYPE_01);
 openAllChannelAndPayRequest.setTokenPayData("{trId=99988877766&tokenType=01}");
 openAllChannelAndPayRequest.setAccNo(null);
 //前臺通知地址
 openAllChannelAndPayRequest.setFrontUrl(config.getFrontUrl());
 openAllChannelAndPayRequest.setPayTimeout(DateFormatUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMddHHmmss"));
 //request
 openAllChannelAndPayRequest.setCertId(certDescriptor.getSignCertId());
 openAllChannelAndPayRequest.setEncryptCertId(certDescriptor.getEncryptCertId());
 Map<String, String> paramMap = openAllChannelAndPayRequest.signAndGetMap(config,
  certDescriptor.getSignCertPrivateKey(config.getPrivateCertPwd()),
  config.getPrivateKeyString());
 String html = createAutoFormHtml(String.format(UnionUrlConsts.FRONT_TRANS_URL, "test.95516.com"), paramMap, "UTF-8");
 try {
  resp.getWriter().write(html);
 } catch (IOException e) {
  e.printStackTrace();
 }
 }

 /**
 * 銀聯(lián)同步通知
 * @param req
 * @return
 */
 @RequestMapping("/frontRcvResponse")
 public ModelAndView frontRcvResponse(HttpServletRequest req) {
 String encoding = req.getParameter("encoding");
 log.info("返回報文中encoding=[" + encoding + "]");
 String pageResult = "";
 if ("UTF-8".equalsIgnoreCase(encoding)) {
  pageResult = "success";
 } else {
  pageResult = "error";
  ModelAndView modelAndView = new ModelAndView(pageResult);
  modelAndView.addObject("result", "交易出錯,請聯(lián)系管理員");
  return modelAndView;
 }
 //獲取響應(yīng)數(shù)據(jù)轉(zhuǎn)換為map
 Map<String, String> respParam = getAllRequestParam(req);
 // 驗簽集合
 Map<String, String> valideData = null;
 StringBuffer page = new StringBuffer();
 //組裝集合數(shù)據(jù)
 if (null != respParam && !respParam.isEmpty()) {
  Iterator<Map.Entry<String, String>> it = respParam.entrySet().iterator();
  valideData = new HashMap<String, String>(respParam.size());
  while (it.hasNext()) {
  Map.Entry<String, String> e = it.next();
  String key = (String) e.getKey();
  String value = (String) e.getValue();
  valideData.put(key, value);
  }
 }
 //獲取公鑰證書
 /*X509Certificate x509Cert = SDK.genCertificateByStr(valideData.get("signPubKeyCert"));
 if (x509Cert == null) {
  log.info("convert signPubKeyCert failed");
  throw new RuntimeException();
 }*/
 // 2.驗證證書鏈 以及是否過期
 /*if (!SDK.verifyCertificate(x509Cert, certDescriptor)) {
  log.info("驗證公鑰證書失敗,證書信息:[" + valideData.get("signPubKeyCert") + "]");
  throw new RuntimeException();
 }*/
 //驗 簽 處理
 String sign256 = DigestUtils.sha256Hex(UnionSignUtil.createQueryString(valideData, UnionParamConsts.getDefaultIgnoreSignParams()));
 boolean validate = RSA2.verify(sign256, valideData.get(UnionParamConsts.PARAM_SIGNATURE),X509.getPublicKey(valideData.get(UnionParamConsts.PARAM_SIGN_PUB_KEY_CERT)), "UTF-8");
 if (!validate) {
  log.info("驗證簽名結(jié)果[失敗].");
  return null;
 } else {
  log.info("驗證簽名結(jié)果[成功].");
  //前臺回調(diào)接口不涉及用戶相關(guān)信息封裝
  /*String customerInfo = valideData.get("customerInfo");
  if (null != customerInfo) {
  Map<String, String> customerInfoMap = this.parseCustomerInfo(customerInfo, "UTF-8");
  page.append("customerInfo明文: " + customerInfoMap);
  }
  String accNo = valideData.get("accNo");
  //如果返回的卡號是密文那么,可以用下邊方法解密
  if (null != accNo) {
  accNo = AcpService.decryptData(accNo, "UTF-8");
  page.append("<br>accNo明文: " + accNo);
  }*/
  //判斷respCode=00、A6后,對涉及資金類的交易,請再發(fā)起查詢接口查詢,確定交易成功后更新數(shù)據(jù)庫。
  String respCode = valideData.get("respCode");
 }
 if (StringUtils.equals(valideData.get("respCode"), "00")) {
  //解密卡號
  String accNo = UnionSecureUtil.decryptData(certDescriptor.getSignCertPrivateKey("000000"), valideData.get("accNo"), "UTF-8");
  respParam.put("accNo明文",accNo);
  ModelAndView modelAndView = new ModelAndView(pageResult);
  modelAndView.addObject("result", respParam);
  return modelAndView;
 } else {
  //TODO 交易碼不正確 邏輯未完善
  ModelAndView modelAndView = new ModelAndView(pageResult);
  modelAndView.addObject("result", "交易出錯,請聯(lián)系管理員");
  return modelAndView;
 }
 }


 /**
 * 解析返回報文(后臺通知)中的customerInfo域:<br>
 * 解base64,如果帶敏感信息加密 encryptedInfo 則將其解密并將 encryptedInfo中的域放到customerInfoMap返回<br>
 *
 * @param customerInfo<br>
 * @param encoding<br>
 * @return
 */
 public Map<String, String> parseCustomerInfo(String customerInfo, String encoding) {
 Map<String, String> customerInfoMap = null;
 try {
  byte[] b = Base64.decodeBase64(customerInfo.getBytes(encoding));
  String customerInfoNoBase64 = new String(b, encoding);
  log.info("解base64后===>" + customerInfoNoBase64);
  //去掉前后的{}
  customerInfoNoBase64 = customerInfoNoBase64.substring(1, customerInfoNoBase64.length() - 1);
  customerInfoMap = UnionStrUtil.parseQString(customerInfoNoBase64);
  if (customerInfoMap.containsKey("encryptedInfo")) {
  String encInfoStr = customerInfoMap.get("encryptedInfo");
  customerInfoMap.remove("encryptedInfo");
  PrivateKey privateKey = certDescriptor.getSignCertPrivateKey("000000");
  String encryptedInfoStr = UnionSecureUtil.decryptData(privateKey, encInfoStr, encoding);
  Map<String, String> encryptedInfoMap = UnionStrUtil.parseQString(encryptedInfoStr);
  customerInfoMap.putAll(encryptedInfoMap);
  }
 } catch (UnsupportedEncodingException e) {
  log.info(e.getMessage(), e);
 } catch (IOException e) {
  log.info(e.getMessage(), e);
 }
 return customerInfoMap;
 }


 /**
 * 獲取請求參數(shù)中所有的信息
 * 當(dāng)商戶上送frontUrl或backUrl地址中帶有參數(shù)信息的時候,
 * 這種方式會將url地址中的參數(shù)讀到map中,會導(dǎo)多出來這些信息從而致驗簽失敗,這個時候可以自行修改過濾掉url中的參數(shù)或者使用getAllRequestParamStream方法。
 *
 * @param request
 * @return
 */
 public static Map<String, String> getAllRequestParam(
  final HttpServletRequest request) {
 Map<String, String> res = new HashMap<String, String>();
 Enumeration<?> temp = request.getParameterNames();
 if (null != temp) {
  while (temp.hasMoreElements()) {
  String en = (String) temp.nextElement();
  String value = request.getParameter(en);
  res.put(en, value);
  // 在報文上送時,如果字段的值為空,則不上送<下面的處理為在獲取所有參數(shù)數(shù)據(jù)時,判斷若值為空,則刪除這個字段>
  if (res.get(en) == null || "".equals(res.get(en))) {
   // System.out.println("======為空的字段名===="+en);
   res.remove(en);
  }
  }
 }
 return res;
 }

 /**
 * 獲取請求參數(shù)中所有的信息。
 * 非struts可以改用此方法獲取,好處是可以過濾掉request.getParameter方法過濾不掉的url中的參數(shù)。
 * struts可能對某些content-type會提前讀取參數(shù)導(dǎo)致從inputstream讀不到信息,所以可能用不了這個方法。理論應(yīng)該可以調(diào)整struts配置使不影響,但請自己去研究。
 * 調(diào)用本方法之前不能調(diào)用req.getParameter("key");這種方法,否則會導(dǎo)致request取不到輸入流。
 *
 * @param request
 * @return
 */
 public static Map<String, String> getAllRequestParamStream(
  final HttpServletRequest request) {
 Map<String, String> res = new HashMap<String, String>();
 try {
  String notifyStr = new String(IOUtils.toByteArray(request.getInputStream()), "UTF-8");
  log.info("收到通知報文:" + notifyStr);
  String[] kvs = notifyStr.split("&");
  for (String kv : kvs) {
  String[] tmp = kv.split("=");
  if (tmp.length >= 2) {
   String key = tmp[0];
   String value = URLDecoder.decode(tmp[1], "UTF-8");
   res.put(key, value);
  }
  }
 } catch (UnsupportedEncodingException e) {
  log.info("getAllRequestParamStream.UnsupportedEncodingException error: " + e.getClass() + ":" + e.getMessage());
 } catch (IOException e) {
  log.info("getAllRequestParamStream.IOException error: " + e.getClass() + ":" + e.getMessage());
 }
 return res;
 }


 public static String createAutoFormHtml(String reqUrl, Map<String, String> hiddens, String encoding) {
 StringBuffer sf = new StringBuffer();
 sf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + encoding + "\"/></head><body>");
 sf.append("<form id = \"pay_form\" action=\"" + reqUrl
  + "\" method=\"post\">");
 if (null != hiddens && 0 != hiddens.size()) {
  Set<Map.Entry<String, String>> set = hiddens.entrySet();
  Iterator<Map.Entry<String, String>> it = set.iterator();
  while (it.hasNext()) {
  Map.Entry<String, String> ey = it.next();
  String key = ey.getKey();
  String value = ey.getValue();
  sf.append("<input type=\"hidden\" name=\"" + key + "\" id=\""
   + key + "\" value=\"" + value + "\"/>");
  }
 }
 sf.append("</form>");
 sf.append("</body>");
 sf.append("<script type=\"text/javascript\">");
 sf.append("document.all.pay_form.submit();");
 sf.append("</script>");
 sf.append("</html>");
 return sf.toString();
 }

}

總結(jié)

項目封裝基礎(chǔ),業(yè)務(wù)處理我們架構(gòu)都用了設(shè)計模式【sdk模塊】,主要就是模板設(shè)計。建議大家好好理解下模板設(shè)計模式,真的各種項目框架的源代碼不可能沒有模板。需要項目源碼請雙擊點贊留言+郵箱,畢竟整理不易。后面我抽出時間會整理個開源的sdk出來,這個的封裝是我們架構(gòu)封裝,我只是嵌入業(yè)務(wù)功能代碼實現(xiàn)。所以有些封裝只是適合我們的業(yè)務(wù)處理,對于開源是我們沒有考慮的。如果大家關(guān)注度高我就來整理下。主要最近沉迷于netty中,從入門到迷茫(>ω<)喵

到此這篇關(guān)于SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)功能支付附源碼的文章就介紹到這了,更多相關(guān)SpringBoot銀聯(lián)支付內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 實現(xiàn)讀取txt文本數(shù)據(jù)并以數(shù)組形式一行一行取值

    java 實現(xiàn)讀取txt文本數(shù)據(jù)并以數(shù)組形式一行一行取值

    今天小編就為大家分享一篇java 實現(xiàn)讀取txt文本數(shù)據(jù)并以數(shù)組形式一行一行取值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Spring啟動時實現(xiàn)初始化有哪些方式?

    Spring啟動時實現(xiàn)初始化有哪些方式?

    今天給大家?guī)淼奈恼率顷P(guān)于Spring的相關(guān)知識,文章圍繞著Spring啟動時實現(xiàn)初始化有哪些方式展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下
    2021-06-06
  • Java中的forEach循環(huán)詳細(xì)解讀

    Java中的forEach循環(huán)詳細(xì)解讀

    這篇文章主要介紹了Java中的forEach循環(huán)詳細(xì)解讀,不要再foreach循環(huán)里面進行元素的add和remove,如果你非要進行remove元素,那么請使用Iterator方式,如果存在并發(fā),那么你一定要選擇加鎖,需要的朋友可以參考下
    2023-12-12
  • Java?easyExcel的復(fù)雜表頭多級表頭導(dǎo)入

    Java?easyExcel的復(fù)雜表頭多級表頭導(dǎo)入

    最近在項目開發(fā)中遇到的一個excel復(fù)雜表頭的導(dǎo)入數(shù)據(jù)庫操作,下面這篇文章主要給大家介紹了關(guān)于Java?easyExcel的復(fù)雜表頭多級表頭導(dǎo)入的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Spring IoC容器常見獲取Bean的方式匯總示例解析

    Spring IoC容器常見獲取Bean的方式匯總示例解析

    這篇文章主要為大家介紹了Spring IoC容器常見獲取Bean的方式匯總示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Java異常日志堆棧丟失的原因與排查

    Java異常日志堆棧丟失的原因與排查

    這篇文章主要給大家介紹了關(guān)于Java異常日志堆棧丟失的原因與排查的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java深入探究Object類的方法

    Java深入探究Object類的方法

    java繼承中說到的Object類是java中一個特殊的類,所有的類都是直接或者間接的繼承自O(shè)bject類,即如果某個類沒有使用extends關(guān)鍵字則默認(rèn)是java.lang.Object類的子類,所以所有的類都可以使用Object類中定義的方法,下面介紹Object類的常用方法
    2022-05-05
  • Maven中resources標(biāo)簽的用法詳解

    Maven中resources標(biāo)簽的用法詳解

    本文主要介紹了Maven中resources標(biāo)簽的用法詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Java的云打印Lodop

    Java的云打印Lodop

    這篇文章主要介紹了Java的云打印Lodop 的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • springboot集成mybatis-maven插件自動生成pojo的詳細(xì)教程

    springboot集成mybatis-maven插件自動生成pojo的詳細(xì)教程

    這篇文章主要介紹了springboot集成mybatis-maven插件自動生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01

最新評論