java写扫码支付系统框架设计利用什么框架好

工具类服务
编辑部专用服务
作者专用服务
基于Java技术的商业银行支付系统的设计与实现
随着计算机技术和因特网的普及,特别是近年来移动互联网的高速发展,电子商务得到了迅速的发展。电子商务为人类生活提供了一个全新的生活模式和经济模式。此外,电子商务本身还衍生出了新的产品和市场,逐渐将成为潜在的经济增长力,推动世界经济向前发展。随着电子商务的全球化,他将对人们的日常生活和商业的运作产生更为深远的影响。  
支付系统是电子商务系统的重要组成部分。通过支付系统,消费者、商家和金融机构之间可以完成商品和服务的交换。某银行原有的银行支付系统是十多年前开发的一个基于客户端/服务器(C/S)架构的系统。然而银行内部的金融系统需求又非常复杂,这些复杂的特殊领域的需求,对软件的架构提出了更高的要求。随着银行业的发展,银行内部的金融软件系统规模越来越大,结构也趋于越来越复杂。  
为了解决某银行原有支付系统的问题,本课题的主要工作是:采用SSH架构,即Struts+Spring+Hibernate组合框架来重新设计和实现一个上述银行支付系统。主要如下:本文首先从系统的功能性需求和非功能性需求两方面进行考虑,给出了系统的功能模型、业务流程,为接下来的系统设计做准备;然后本文根据上一阶段得到的需求模型,对整个系统进行定义细化,并结合银行系统的设计原则、现有的网络拓扑结构和目前成熟的技术实践,设计了系统的体系结构、划分出了具体的功能模块,完成了对系统的整体设计和规划;接着本文采用最新的大型软件系统实施思路,介绍了系统在实现过程中的一些细节,对软硬件系统的环境提出了要求。最后本文对整个系统进行了测试,通过结合单元测试和综合测试本文简要介绍了测试过程中用到的测试方法和测试工具。  
学科专业:
授予学位:
学位授予单位:
导师姓名:
学位年度:
在线出版日期:
本文读者也读过
相关检索词
万方数据知识服务平台--国家科技支撑计划资助项目(编号:2006BAH03B01)(C)北京万方数据股份有限公司
万方数据电子出版社匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。微信支付开发h5调用(Java 实现)
10880次浏览
这两天做微信支付开发。碰到大坑。纠结死我了。好不容做完。
后台java:直接上代码:注意区分前后端的变量大小写。。。
@RequestMapping(value = &/index&)
public Model
index(@RequestParam(value = &openid&, required = true) String openid ,Model model,HttpServletRequest request) throws Exception{
(&************openid***********为:&+openid);
//获取prepayid
Map&String ,String & map=new HashMap&String,String&();
WeiXinConfig wcf=weiXinBaseService.getWeiXinConfig();
String nonceStr=UUID.randomUUID().toString().substring(0, 32);
oauthService.shareFactory(request);
String appid=wcf.getAppid();
long timestamp = System.currentTimeMillis() / 1000;
map.put(&appid&, appid );
map.put(&mch_id&, WebConfig.get(&pay.mch_id&));
map.put(&nonce_str&,nonceStr);
map.put(&body&,
WebConfig.get(&pay.body&));
map.put(&out_trade_no&, payWxUtil.orderNum());
map.put(&total_fee&, WebConfig.get(&pay.price&));
map.put(&spbill_create_ip&,request.getRemoteAddr());
map.put(&notify_url&, WebConfig.get(&hostAddress&)+request.getContextPath()+&/babyShow/payInfo/info&);
map.put(&trade_type&, &JSAPI&);
map.put(&openid&, openid);
String paySign=SignUtil.getPayCustomSign(map,WebConfig.get(&pay.key&));
map.put(&sign&,paySign);
String xml=
CommonUtil.ArrayToXml(map);
String prepayid=
payWxUtil.getPrepayid(xml);
(&prepareid*****************************=&+prepayid);
//封装h5页面调用参数
Map&String ,String & signMap=new HashMap&String ,String &();
signMap.put(&appId&, appid);
(&appId=&+appid);
signMap.put(&timeStamp&, timestamp+&&);
(&timeStamp=&+timestamp);
signMap.put(&package&, &prepay_id=&+prepayid);
(&package=&+&prepay_id=&+prepayid);
signMap.put(&signType&, &MD5&);
(&singType=&+&MD5&);
signMap.put(&nonceStr&, nonceStr);
(&nonceStr=&+nonceStr);
model.addAttribute(&paytimestamp&, timestamp);
model.addAttribute(&paypackage&, &prepay_id=&+prepayid);
model.addAttribute(&paynonceStr&, nonceStr);
model.addAttribute(&paysignType&, &MD5&);
String paySign2=SignUtil.getPayCustomSign(signMap,WebConfig.get(&pay.key&));
model.addAttribute(&paySign&,paySign2 );
(&paySign=&+paySign2);
以上代码获取openid需要根据网页授权来获取。这里就不多讲了。主要讲讲获取prepayid和生成h5页面所需参数,
这里面比较麻烦的就是签名的获取
查看方法SignUtil.getPayCustomSign(signMap,WebConfig.get(&pay.key&))
* 获取支付所需签名
* @param ticket
* @param timeStamp
* @param card_id
* @param code
* @throws Exception
public static String getPayCustomSign(Map&String, String& bizObj,String key) throws Exception {
String bizString = CommonUtil.FormatBizQueryParaMap(bizObj,
(bizString);
return MD5SignUtil.sign(bizString, key);
其中CommonUtil.FormatBizQueryParaMap是用来做字典排序的。有参考了网上的例子。就没单独做。
public static String FormatBizQueryParaMap(Map&String, String& paraMap,
boolean urlencode) throws Exception {
String buff = &&;
List&Map.Entry&String, String&& infoIds = new ArrayList&Map.Entry&String, String&&(
paraMap.entrySet());
Collections.sort(infoIds,
new Comparator&Map.Entry&String, String&&() {
public int compare(Map.Entry&String, String& o1,
Map.Entry&String, String& o2) {
return (o1.getKey()).toString().compareTo(
o2.getKey());
for (int i = 0; i & infoIds.size(); i++) {
Map.Entry&String, String& item = infoIds.get(i);
//System.out.println(item.getKey());
if (item.getKey() != &&) {
String key = item.getKey();
String val = item.getValue();
if (urlencode) {
val = URLEncoder.encode(val, &utf-8&);
buff += key + &=& + val + &&&;
if (buff.isEmpty() == false) {
buff = buff.substring(0, buff.length() - 1);
} catch (Exception e) {
throw new Exception(e.getMessage());
其中MD5SignUtil.sign(bizString, key)方法如下
public static String sign(String content, String key)
throws Exception{
String signStr = &&;
signStr = content + &&key=& +
return MD5Util.MD5(signStr).toUpperCase();
其中MD5Util.MD5(signStr)方法如下
public final static String MD5(String s) {
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
byte[] btInput = s.getBytes();
MessageDigest mdInst = MessageDigest.getInstance(&MD5&);
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i & i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 &&& 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
return new String(str);
} catch (Exception e) {
e.printStackTrace();
CommonUtil.ArrayToXml(map)方法如下
public static String ArrayToXml(Map&String, String& arr) {
String xml = &&xml&&;
Iterator&Entry&String, String&& iter = arr.entrySet().iterator();
while (iter.hasNext()) {
Entry&String, String& entry = iter.next();
String key = entry.getKey();
String val = entry.getValue();
if (IsNumeric(val)) {
xml += &&& + key + &&& + val + &&/& + key + &&&;
xml += &&& + key + &&&![CDATA[& + val + &]]&&/& + key + &&&;
xml += &&/xml&&;
public static boolean IsNumeric(String str) {
if (str.matches(&\\d *&)) {
发送请求到微信获取prepayid代码如下
public static String URL=&https://api.mch./pay/unifiedorder&;
@SuppressWarnings(&deprecation&)
JSONObject getPrepayJson(String xml){
HttpClient httpClient = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true) );
InputStream is =
PostMethod method=
String url =URL;
method = HttpClientUtils.postMethod(url);
method.setRequestBody(xml);
httpClient.executeMethod(method);
//读取响应
is = method.getResponseBodyAsStream();
JSONObject o =Xml2JsonUtil.xml2JSON(is);
} catch (Exception e) {
e.printStackTrace();
if(method!=null){
method.releaseConnection();
if(is!=null){
is.close();
} catch (IOException e1) {
e1.printStackTrace();
String getPrepayid(String xml){
JSONObject jo=getPrepayJson(xml);
JSONObject element=jo.getJSONObject(&xml&);
String prepayid=((JSONArray)element.get(&prepay_id&)).get(0).toString();
} catch (Exception e) {
e.printStackTrace();
String orderNum(){
String chars = &&;
String order = System.currentTimeMillis()+&&;
String res = &&;
for (int i = 0; i & 19; i++) {
Random rd = new Random();
res += chars.charAt(rd.nextInt(chars.length() - 1));
xml转json方法Xml2JsonUtil.xml2JSON(is);。摘自网络
* 转换一个xml格式的字符串到json格式
* @param xml
xml格式的字符串
* @return 成功返回json 格式的字符串;失败反回null
@SuppressWarnings(&unchecked&)
public static
JSONObject xml2JSON(InputStream is) {
JSONObject obj = new JSONObject();
SAXReader sb = new SAXReader();
Document doc = sb.read(is);
Element root = doc.getRootElement();
obj.put(root.getName(), iterateElement(root));
} catch (Exception e) {
log.error(&传入XML后转换JSON出现错误===== Xml2JsonUtil--&xml2JSON============&&&,e);
* 一个迭代方法
* @param element
: org.jdom.Element
* @return java.util.Map 实例
@SuppressWarnings(&unchecked&)
private static Map
iterateElement(Element element) {
List jiedian = element.elements() ;
Element et =
Map obj = new HashMap();
List list =
for (int i = 0; i & jiedian.size(); i++) {
list = new LinkedList();
et = (Element) jiedian.get(i);
if (et.getTextTrim().equals(&&)) {
if (et.elements().size() == 0)
if (obj.containsKey(et.getName())) {
list = (List) obj.get(et.getName());
list.add(iterateElement(et));
obj.put(et.getName(), list);
if (obj.containsKey(et.getName())) {
list = (List) obj.get(et.getName());
list.add(et.getTextTrim());
obj.put(et.getName(), list);
服务端基本这么多
前端被微信和我自己挖了大坑,整整搞了两天,擦
先是看的微信文档jssdk文档(开始埋坑。。)
页面引入js
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '${appid}', // 必填,公众号的唯一标识
timestamp: '${timestamp}', // 必填,生成签名的时间戳
nonceStr: '${nonceStr}', // 必填,生成签名的随机串
signature: '${signature}',// 必填,签名,见附录1
jsApiList: [
'chooseWXPay'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
嗯。配置好了。如果传入jsconfig的参数。。。
然后看到jssdk里面有发送一个微信支付请求?
function pay(){
wx.chooseWXPay({
timestamp: ${paytimestamp}, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '${paynonceStr}', // 支付签名随机串,不长于 32 位
package: '${paypackage}', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: '${paysignType}', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '${paySign}', // 支付签名
success: function (res) {
alert(&支付成功&);
// 支付成功后的回调函数
然后发布,执行调试。。尼玛。怎么样都支付不了。一会儿报订单信息错误、一会儿报签名错误。。。找了N多资料均不对
后来想啊。大不了用商户平台提供的文档写接口什么的。于是加入了代码
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
&appId& : &${appid}&,
//公众号名称,由商户传入
&timeStamp&:&${paytimestamp}&,
//时间戳,自1970年以来的秒数
&nonceStr& : &${paynonceStr}&, //随机串
&package& : &${paypackage}&,
&signType& : &${paysignType}&,
//微信签名方式:
&paySign& : &${paySign}& //微信签名
function(res){
alert(res.err_msg);
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返
function pay2(){
if (typeof WeixinJSBridge == &undefined&){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
onBridgeReady();
发布调试。。。还是不对。。两个按钮pay()和pay2()均不对。pay方法还是一会儿订单信息错误一会儿签名错误。pay2()方法则一直报签名错误。。。尼玛。吧经历放后台签名。。怎么改都不行。签名明明对的啊。可以获取prepayid的。为毛封装h5参数时就出错了呢。。。折腾啊。。。搞了N久。。就尼玛不对。。。后来一个小错误pay方法js报错了。。结果pay2方法确可以执行了。。。吧pay的js报错去了之后pay2又不能用了。。我擦。。哥有预感。。难道两种方式冲突了??于是我把config和pay方法删除了再试试。。。尼玛果然可以了。不能加入config和pay。。。果然可以了。。。我擦。折腾的。。微信啃爹啊。第一种方式无法用有没有,误导人啊。。。正确结果就是商品平台的文档使用方法js如下:
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
&appId& : &${appid}&,
//公众号名称,由商户传入
&timeStamp&:&${paytimestamp}&,
//时间戳,自1970年以来的秒数
&nonceStr& : &${paynonceStr}&, //随机串
&package& : &${paypackage}&,
&signType& : &${paysignType}&,
//微信签名方式:
&paySign& : &${paySign}& //微信签名
function(res){
alert(res.err_msg);
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返
function pay(){
if (typeof WeixinJSBridge == &undefined&){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
onBridgeReady();
至此。终于把微信支付搞定了。留着博客。防止后人走弯路(config里面不能加入chooseWXPay方法。。切记)
您可能也会对以下文章感兴趣
QQ : 341470
Friend Link
New Member最全最强解析:支付宝钱包系统架构内部剖析(架构图)
招聘信息:
支付宝系统架构概况典型处理默认资金处理平台财务会计支付清算核算中心交易柔性事务支付宝的开源分布式消息中间件–Metamorphosis(MetaQ)Metamorphosis (MetaQ) 是一个高性能、高可用、可扩展的分布式消息中间件,类似于LinkedIn的Kafka,具有消息存储顺序写、吞吐量大和支持本地和XA事务等特性,适用 于大吞吐量、顺序消息、广播和日志数据传输等场景,在淘宝和支付宝有着广泛的应用,现已开源。Metamorphosis是淘宝开源的一个Java消息中间件。关于消息中间件,你应该听说过JMS规范,以及一些开源实现,如ActiveMQ和HornetQ等。Metamorphosis也是其中之一。Metamorphosis 的起源是我从对linkedin的开源MQ–现在转移到apache的kafka的学习开始的,这是一个设计很独特的MQ系统,它采用pull机制,而 不是一般MQ的push模型,它大量利用了zookeeper做服务发现和offset存储,它的设计理念我非常欣赏并赞同,强烈建议你阅读一下它的设计 文档,总体上说metamorphosis的设计跟它是完全一致的。但是为什么还需要meta呢?简单概括下我重新写出meta的原因:1.Kafka是scala写,我对scala不熟悉,并且kafka整个社区的发展太缓慢了。2.有一些功能是kakfa没有实现,但是我们却需要:事务、多种offset存储、高可用方案(HA)等3.Meta相对于kafka特有的一些功能:文本协议设计,非常透明,支持类似memcached stats的协议来监控broker纯Java实现,从通讯到存储,从client到server都是重新实现。提供事务支持,包括本地事务和XA分布式事务支持HA复制,包括异步复制和同步复制,保证消息的可靠性支持异步发送消息消费消息失败,支持本地恢复多种offset存储支持,数据库、磁盘、zookeeper,可自定义实现支持group commit,提升数据可靠性和吞吐量。支持消息广播模式一系列配套项目:python客户端、twitter storm的spout、tail4j等。因此meta相比于kafka的提升是巨大的。meta在淘宝和支付宝都得到了广泛应用,现在每天支付宝每天经由meta路由的消息达到120亿,淘宝也有每天也有上亿的消息量。Meta适合的应用日志传输,高吞吐量的日志传输本来就是kafka的强项;消息广播功能,如广播缓存配置失效;数据的顺序同步功能,如mysql binlog复制;分布式环境下(broker,producer,consumer都为集群)的消息路由,对顺序和可靠性有极高要求的场景;作为一般MQ来使用的其他功能。作者:雪姬来源:移动支付网(微信公众号:mpaypass)
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量7130点击量3966点击量3934点击量3495点击量3469点击量3369点击量3176点击量3097点击量2857
&2016 Chukong Technologies,Inc.
京公网安备89}

我要回帖

更多关于 oa系统框架 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信