支付宝支付
该方法建议放在业务层
public ConsultationPay readyPay(String id,String price){
try {
//实例化客户端
//配置支付宝的具体参数,商户号等。该对象没有源码,需要引入jar包
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", textConfig.getAlipayappid(), textConfig.getAlipayappprivatekey(), "json", textConfig.getAlipaycharset(), textConfig.getAlipaypublickey(), "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
//该对象没有源码,需要引入jar包
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
//该对象没有源码,需要引入jar包
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// 对一笔交易的具体描述信息,
model.setBody("医生充值");
// 商品的标题/交易标题/
model.setSubject("医生充值");
// 商户网站唯一订单号//pd.getString("memberid")
//该笔交易的订单号,唯一,这里做的是当前时间戳拼接该用户的手机号
String orderNo=OrderNoUtil.getOrderNo()+"_"+doctorMapper.findAllInformation(id).getString("phone");
model.setOutTradeNo(orderNo);
// 该笔订单允许的最晚付款时间,逾期将关闭交易。
model.setTimeoutExpress("30m");
// 订单总金额,单位为元
//model.setTotalAmount("0.01");
//测试时做的处理,默认每笔订单价格是0.01元,支付宝的价格默认是元
model.setTotalAmount(price);
//常量值
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
//这里是回调函数,如果客户端支付,回调函数会自动执行的方法,在这里配置路径
request.setNotifyUrl(textConfig.getPath()+"/api/purse/pay/notifyAilPay");
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
//因为该业务是为前端提供接口,在这里返回一个自定义对象,该对象属性为本次支付宝交易的id,这几交易的价格,还有支付宝的交易信息(String)
return new ConsultationPay(orderNo, Double.parseDouble(price), response.getBody());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
支付成功后的回调函数,该方法建议放在表现层
@ApiOperation(value = "第三方支付异步通知接口")
//发起支付时配置的回调路径
@PostMapping("/pay/notifyAilPay")
//游客可以访问的注释,开放权限
@TouristAuthority
public void notify_pay(HttpServletRequest request) {
// TODO 获取订单号,区分来自于微信OR支付宝
// 1、修改订单表状态
// 2、订单跟踪表插入数据
// 3、新增卡密进行分配
// 4、如果该订单用积分抵扣过,应扣除会员相应积分,并且插入积分变更表,加入注释(主要用于与其它项进行区分,为了最后与经验总数进行对账)
// projectOrderService.notify_pay();
// 获取支付宝POST过来反馈信息
Map requestParams = request.getParameterMap();
try {
purseService.notify_pay(requestParams);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
// 充值回调
@Transactional
public void notify_pay(Map requestParams) throws Exception {
Map<String,String> params = new HashMap<String,String>();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
logger.info("支付宝返回结果!!!!!!!!!》》》》》》》》》》》》》name="+name+"<<<<<<<<value="+valueStr);
}
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
//表示支付是否成功
boolean flag = AlipaySignature.rsaCheckV1(params, textConfig.getAlipaypkey(), textConfig.getAlipaycharset(), "RSA2");
// 订单金额
//String total_amount = params.get("total_amount");
// 商户订单号
//支付时创建的订单id,当前时间戳拼接用户手机号
String orderNo = params.get("out_trade_no");
// 用户支付金额
//客户端支付的金额
String amount = params.get("buyer_pay_amount");
if(flag) {
//支付成功,对数据库进行更改,因为订单id里拼接了手机号,这里通过手机号查找用户信息,所以必须保证手机号唯一
PageData data = purseMapper.findBalanceByPhone(orderNo.split("_")[1]);// 用户当前余额
Double balance = Double.parseDouble(data.get("balance").toString());
// mapper.updateMoney(myMoney.getId(), balance+Double.parseDouble(amount));
PageData pd = new PageData();
pd.put("type", 0);
pd.put("balance", balance+Double.parseDouble(amount));
pd.put("userid", data.getString("id"));
purseMapper.updatePurseInfo(pd);
pd.put("type", "0"); //0:收入 1:支出
pd.put("resource", "1"); // 1:支付宝 2:微信
pd.put("remark", "钱包充值");
pd.put("userid", data.getString("id"));
pd.put("usertype", "0"); // 0:医生 1:会员
pd.put("money", Double.parseDouble(amount));
pd.put("orderNo", orderNo); // 充值订单编号
purseMapper.savePurse(pd);
/*String ticketno = OrderTicketUtil.getOrderTicketNo();*/
/*mapper.saveTicket(ticketno, orderid);*/
//验证该订单是否使用积分抵扣,如果是,则扣除会员相应积分
/*PageData pd = mapper.getMemberIdAndScoreByOrderid(orderid);
if(pd.get("integral") != null || (int)pd.get("integral") != 0) {
integralService.calculateForPay(pd.get("member_id").toString(), (int)pd.get("integral"));
}*/
} else{
logger.error("支付宝支付失败!错误订单号:"+orderNo);
}
}
该方法建议放在业务层
public ConsultationPay readyPay(String id,String price){
try {
//实例化客户端
//配置支付宝的具体参数,商户号等。该对象没有源码,需要引入jar包
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", textConfig.getAlipayappid(), textConfig.getAlipayappprivatekey(), "json", textConfig.getAlipaycharset(), textConfig.getAlipaypublickey(), "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
//该对象没有源码,需要引入jar包
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
//该对象没有源码,需要引入jar包
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// 对一笔交易的具体描述信息,
model.setBody("医生充值");
// 商品的标题/交易标题/
model.setSubject("医生充值");
// 商户网站唯一订单号//pd.getString("memberid")
//该笔交易的订单号,唯一,这里做的是当前时间戳拼接该用户的手机号
String orderNo=OrderNoUtil.getOrderNo()+"_"+doctorMapper.findAllInformation(id).getString("phone");
model.setOutTradeNo(orderNo);
// 该笔订单允许的最晚付款时间,逾期将关闭交易。
model.setTimeoutExpress("30m");
// 订单总金额,单位为元
//model.setTotalAmount("0.01");
//测试时做的处理,默认每笔订单价格是0.01元,支付宝的价格默认是元
model.setTotalAmount(price);
//常量值
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
//这里是回调函数,如果客户端支付,回调函数会自动执行的方法,在这里配置路径
request.setNotifyUrl(textConfig.getPath()+"/api/purse/pay/notifyAilPay");
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
//因为该业务是为前端提供接口,在这里返回一个自定义对象,该对象属性为本次支付宝交易的id,这几交易的价格,还有支付宝的交易信息(String)
return new ConsultationPay(orderNo, Double.parseDouble(price), response.getBody());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
支付成功后的回调函数,该方法建议放在表现层
@ApiOperation(value = "第三方支付异步通知接口")
//发起支付时配置的回调路径
@PostMapping("/pay/notifyAilPay")
//游客可以访问的注释,开放权限
@TouristAuthority
public void notify_pay(HttpServletRequest request) {
// TODO 获取订单号,区分来自于微信OR支付宝
// 1、修改订单表状态
// 2、订单跟踪表插入数据
// 3、新增卡密进行分配
// 4、如果该订单用积分抵扣过,应扣除会员相应积分,并且插入积分变更表,加入注释(主要用于与其它项进行区分,为了最后与经验总数进行对账)
// projectOrderService.notify_pay();
// 获取支付宝POST过来反馈信息
Map requestParams = request.getParameterMap();
try {
purseService.notify_pay(requestParams);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
// 充值回调
@Transactional
public void notify_pay(Map requestParams) throws Exception {
Map<String,String> params = new HashMap<String,String>();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
logger.info("支付宝返回结果!!!!!!!!!》》》》》》》》》》》》》name="+name+"<<<<<<<<value="+valueStr);
}
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
//表示支付是否成功
boolean flag = AlipaySignature.rsaCheckV1(params, textConfig.getAlipaypkey(), textConfig.getAlipaycharset(), "RSA2");
// 订单金额
//String total_amount = params.get("total_amount");
// 商户订单号
//支付时创建的订单id,当前时间戳拼接用户手机号
String orderNo = params.get("out_trade_no");
// 用户支付金额
//客户端支付的金额
String amount = params.get("buyer_pay_amount");
if(flag) {
//支付成功,对数据库进行更改,因为订单id里拼接了手机号,这里通过手机号查找用户信息,所以必须保证手机号唯一
PageData data = purseMapper.findBalanceByPhone(orderNo.split("_")[1]);// 用户当前余额
Double balance = Double.parseDouble(data.get("balance").toString());
// mapper.updateMoney(myMoney.getId(), balance+Double.parseDouble(amount));
PageData pd = new PageData();
pd.put("type", 0);
pd.put("balance", balance+Double.parseDouble(amount));
pd.put("userid", data.getString("id"));
purseMapper.updatePurseInfo(pd);
pd.put("type", "0"); //0:收入 1:支出
pd.put("resource", "1"); // 1:支付宝 2:微信
pd.put("remark", "钱包充值");
pd.put("userid", data.getString("id"));
pd.put("usertype", "0"); // 0:医生 1:会员
pd.put("money", Double.parseDouble(amount));
pd.put("orderNo", orderNo); // 充值订单编号
purseMapper.savePurse(pd);
/*String ticketno = OrderTicketUtil.getOrderTicketNo();*/
/*mapper.saveTicket(ticketno, orderid);*/
//验证该订单是否使用积分抵扣,如果是,则扣除会员相应积分
/*PageData pd = mapper.getMemberIdAndScoreByOrderid(orderid);
if(pd.get("integral") != null || (int)pd.get("integral") != 0) {
integralService.calculateForPay(pd.get("member_id").toString(), (int)pd.get("integral"));
}*/
} else{
logger.error("支付宝支付失败!错误订单号:"+orderNo);
}
}