1.前端实现
1.1创建路由174
{ //174
path: '/page/user/userpay',
name: 'UserPayView',
component: () => import('../views/UserPayView.vue')
}
1.2按钮跳转174
UserCenterView.vue
1.3添加页面174
1.3.1UserPayView.vue
我的账户
充值
我的信息
投资记录
收益记录
第三方支付平台
请输入金额
温馨提示
1.为了您的使用安全,充值操作建议不要使用公共电脑。
2.银行卡充值限额,由各银行限制。
3.品台禁止用卡套现、虚拟交易、洗钱等行为,一经发现并确认,将终止该账户的使用。
4.如果充值中出现问题,请联系客服400-890-0000。
import Header from "@/components/common/Header";
import Footer from "@/components/common/Footer";
export default {
name: "UserPayView",
data(){
return {
userId:0
}
},
mounted() {
let userinfo = window.localStorage.getItem("userinfo");
if( userinfo ){
this.userId = JSON.parse(userinfo).uid;
}
},
components:{
// eslint-disable-next-line vue/no-unused-components
Header,
// eslint-disable-next-line vue/no-unused-components
Footer
},
methods:{
}
}
1.3.2优化form表单页面175
后端kqForm.html175
micr-pay
document.forms[0].submit(); //175
1.4测试175
点击支付
页面跳转成功
2.后端支付结果发送给商家175
2.1处理后续充值176
2.1.1业务接口RechargeService
micr-api
//处理充值 后续 176
int handleKQNotify(String orderId, String payAmount, String payResult);
2.1.2业务接口实现类RechargeServiceImpl176
根据订单号查询充值表记录176
在mapper中定义方法
RechargeRecordMapper
micr-dataservice
//根据订单号查询充值表 记录 176
RechargeRecord selectByRechargeNo(@Param("rechargeNo") String orderId);
编写sql176
RechargeRecordMapper.xml
micr-dataservi服务器托管网ce
select
from b_recharge_record
where recharge_no = #{rechargeNo} for update
更新资金账户178
在mapper中定义方法
FinanceAccountMapper
micr-dataservice
//充值更新金额 178
int updateAvailableMoneyByRecharge(@Param("uid") Integer uid,
@Param("rechargeMoney") BigDecimal rechargeMoney);
编写sql语句
FinanceAccountMapper.xml
micr-dataservice
update u_finance_account set available_money = available_money + #{rechargeMoney}
where uid = #{uid}
更新充值记录的状态178
在mapper中定义方法
RechargeRecordMapper
micr-dataservice
//更新充值记录的状态 178
int updateStatus(@Param("id") Integer id, @Param服务器托管网("newStatus") int rechargeStatusSuccess);
编写sql
RechargeRecordMapper.xml
micr-dataservice
update b_recharge_record set recharge_status = #{newStatus} where id = #{id}
实现类RechargeServiceImpl177-178
micr-dataservice
//处理充值 后续 176
@Transactional(rollbackFor = Exception.class)
@Override
public synchronized int handleKQNotify(String orderId, String payAmount, String payResult) {
int result = 0;//订单不存在
int rows = 0;
//1.查询订单 176
RechargeRecord record = rechargeMapper.selectByRechargeNo(orderId);
if(record != null ){ //177
if( record.getRechargeStatus() == YLBConstant.RECHARGE_STATUS_PROCESSING){
//2.判断金额是否一致 177
String fen = record.getRechargeMoney().multiply(new BigDecimal("100"))
.stripTrailingZeros().toPlainString();
if( fen.equals(payAmount)){
//金额一致 177
if("10".equals(payResult)){//判断快钱返回给我们得充值成功状态码
//成功 178
//充值更新金额 178
rows = accountMapper.updateAvailableMoneyByRecharge(record.getUid(),record.getRechargeMoney());
if(rows
2.2消费者接收快钱给商家的支付结果176
拷贝公钥到此179
资源在E:java学习盈利宝资料资料10-快钱支付人民币网关DEMOJAVA人民币网关支付rmbFIWebRootWEB-INFclassesUtil
添加资源插件179
验签Pkipair179
//验签得方法 166
public boolean enCodeByCer( String val, String msg) {
boolean flag = false;
try {
//快钱得公钥文件
//修改此方法使之可以读到中文路径
String filePath = Pkipair.class.getResource("99bill[1].cert.rsa.20140803.cer").toURI().getPath();
// 解码路径中的中文字符
String file = URLDecoder.decode(filePath, StandardCharsets.UTF_8.toString());
System.out.println("文件路径="+file);
FileInputStream inStream = new FileInputStream(file);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
PublicKey pk = cert.getPublicKey();
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(pk);
signature.update(val.getBytes());
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
System.out.println(new String(decoder.decodeBuffer(msg)));
flag = signature.verify(decoder.decodeBuffer(msg));
System.out.println(flag);
} catch (Exception e) {
e.printStackTrace();
System.out.println("no");
}
return flag;
}
KuaiQianService
micr-pay
//接收快钱给商家的支付结果 176
//处理异步通知
public void kqNotify(HttpServletRequest request) {
String merchantAcctId = request.getParameter("merchantAcctId");
String version = request.getParameter("version");
String language = request.getParameter("language");
String signType = request.getParameter("signType");
String payType = request.getParameter("payType");
String bankId = request.getParameter("bankId");
String orderId = request.getParameter("orderId");
String orderTime = request.getParameter("orderTime");
String orderAmount = request.getParameter("orderAmount");
String bindCard = request.getParameter("bindCard");
if(request.getParameter("bindCard")!=null){
bindCard = request.getParameter("bindCard");}
String bindMobile="";
if(request.getParameter("bindMobile")!=null){
bindMobile = request.getParameter("bindMobile");}
String dealId = request.getParameter("dealId");
String bankDealId = request.getParameter("bankDealId");
String dealTime = request.getParameter("dealTime");
String payAmount = request.getParameter("payAmount");
String fee = request.getParameter("fee");
String ext1 = request.getParameter("ext1");
String ext2 = request.getParameter("ext2");
String payResult = request.getParameter("payResult");
String aggregatePay = request.getParameter("aggregatePay");
String errCode = request.getParameter("errCode");
String signMsg = request.getParameter("signMsg");
//拼接签名计算的串 176
String merchantSignMsgVal = "";
merchantSignMsgVal = appendParam(merchantSignMsgVal,"merchantAcctId", merchantAcctId,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "version",version,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "language",language,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "signType",signType,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "payType",payType,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankId",bankId,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderId",orderId,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderTime",orderTime,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderAmount",orderAmount,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindCard",bindCard,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindMobile",bindMobile,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealId",dealId,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankDealId",bankDealId,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealTime",dealTime,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "payAmount",payAmount,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "fee", fee,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext1", ext1,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext2", ext2,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "payResult",payResult,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "aggregatePay",aggregatePay,null);
merchantSignMsgVal = appendParam(merchantSignMsgVal, "errCode",errCode,null);
Pkipair pki = new Pkipair();
boolean flag = pki.enCodeByCer(merchantSignMsgVal, signMsg);
System.out.println("flag==="+flag);
//为了方便测试我们模拟验签成功 178
flag = true;
if( flag ){
/**
* 可以处理业务逻辑 176
* 1.判断商户号是商家自己的吗
* 2.判断订单在商家是否存在,是否处理过
* 3.判断金额是否一致
* 4.如果成功,更新用户的资金
* 5.修改充值表的记录状态
* 6.删除redis中的处理过的订单号
*/
if("1001214035601".equals(merchantAcctId)){
int rechargeResult = rechargeService.handleKQNotify(orderId,payAmount,payResult);
System.out.println("订单"+orderId+",充值处理结果:"+rechargeResult);
} else {
System.out.println("订单"+orderId+",充值处理结果:商家号不正确");
}
} else {
System.out.println("订单"+orderId+"验签失败,不能处理");
}
//删除redis中的订单记录
stringRedisTemplate.boundZSetOps(RedisKey.KEY_ORDERID_SET).remove(orderId);
}
KuaiQianController170、179
micr-pay
//接收快钱给商家的支付结果 , 快钱以get方式,发送请求给商家 170
@GetMapping("/rece/notify")
@ResponseBody
public String payResultNotify(HttpServletRequest request){
kQService.kqNotify(request);
return "1http://localhost:8000/";
}
2.3测试179
debug启动micr-dataservice
debug启动micr-pay
浏览器输入
http://localhost:9000/pay/kq/rece/notify?merchantAcctId=1001214035601&version=v2.0&language=1&signType=4&payType=10&bankId=CCB&orderId=KQ2023080320121582617&orderAmount=1&orderTime=20190520094107&ext1=&ext2=&payAmount=1&dealId=3411469393&bankDealId=WG82301201905200944297620305&dealTime=20190520095014&payResult=10&errCode=&fee=1&signMsg=FbBOrXH6bBBd9Y6aytUeQMpi5j8b7FVO%2FGSgMQ56MJguZKvLCZULIv6fGAHun5VgGlAZ%2Bg8tTI%2FniyZLVP8oK7rRKCo7nXc1lztC5%2Bn5BIh67jT1Gn3PzXYQLxyy3gh0MsJ5fEs1BRc%2FZ%2FD9XW9r7Lmvlpusoeuy6pRgbEZI%2F0WnIebzPw9wGDTQwTsYpcPIqfPd15DB3VsLB86DVtJhlfaCoG0LVfFelAMTP1d3OR5Hm40p9W8XN7yvlpUm%2FZsHjeyb4JjpCJ9%2FAFXMou3TYrltnjbaQa%2BzlkD4SWNXQD4go%2BgqWj%2BFXeJrwqf8k5uk3C3SXSx31jj6bqgXRIxRQg%3D%3D
redis此记录,我们测试此订单号
看看数据库充值记录表
成功充值状态变为1代表充值成功
这是原来的资金表
成功增加1分钱
看看redis
成功删掉此订单,剩下的都是未处理订单
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
好几次,有朋友跟我说看了下面这张图很有感觉。 回忆了一下,我们服务过的公司、特别是偏传统行业的,都会觉得团队、产品负责人过于工程师思维了。 从社会大背景看,工程师思维更适合短缺时代的生产驱动模式,毕竟那时候用户没得挑,而生产力的提升在最近几十年显而易见,产品思…