支付宝与微信支付及原路退款(一)

          以前上一家公司做项目的,并没有做过支付宝app和微信app支付,现在这家公司是做自己的产品,涉及了支付业务。花了一天的时间集成,目前已使用了接近一年的时间。在这使用和开发过程中遇到许多坑,现在跟大家分享一下。

         一、支付宝app支付

                1、首先亲得在支付宝商户平台申请app应用,然后审核通过后获得相对应的应用配置:partner  签约账号 以2088开头;private_key  商户私钥  亲可以在支付宝官网下载对应操作系统的私钥生产工具;alipay_public_key  支付宝公钥,通过私钥生成工具生成的支付宝公钥,并上传至支付宝官网。sign_type  签名方式  ,本人使用的RSA;支付宝签名方式分为RSA和RSA2,小伙伴在开发时一定要注意自己私钥的格式以及对应的签名格式;input_charset  字符编码格式,使用utf-8;service  接口固定值mobile.securitypay.pay  ;seller  签约的公司支付宝账号 ;app_id  已经签约了app的id。

               2、配置好相对应的应用配置后就可以开发功能了,小伙伴可以在支付宝官网下载服务器端demo,使用其中的工具类。

               3、做好这些前期这些准备工作后直接上代码:

  //应用参数配制,根据不同应用,配置不同的参数
     //应用appid
String  app_id="";
//商户私钥
String  private_key="";
//支付宝公钥验签
String  alipay_public_key="";
//卖家账号
String  seller_id="";
//应用1
if("1".equals(appVersion)){
app_id=AlipayConfig.app_id;
private_key=AlipayConfig.private_key_refund;
alipay_public_key=AlipayConfig.alipay_public_key;
seller_id=AlipayConfig.partner;

}else{  //应用2
app_id=AlipayConfigSecond.APP_ID;
private_key=AlipayConfigSecond.PRIVATE_KEY;
alipay_public_key=AlipayConfigSecond.ALIPAY_PUBLIC_KEY;
seller_id=AlipayConfigSecond.PARTNER;

}
 
//此处使用redis并发处理,防止高并发请求
long size=requestRedisTemplate.boundValueOps("alipayment:lock:"+userId).increment(1);
requestRedisTemplate.expire("alipayment:lock:"+userId,3,TimeUnit.SECONDS);

if(size==1){
log.info("当前用户发起"+moduleName+"进行业务处理AlipayStart");
synchronized (lock){
//========================================以下是业务处理开始=========================================















//=====================================业务处理结束=================================================
log.info("当前用户发起"+moduleName+"业务处理结束AlipayEnd");
  //**************************************业务处理成功后进行支付宝参数封装返回json签名*****************************
//实例化支付宝客户端(这些类官网服务器端demo中都有)
AlipayClientApp alipayClient = new DefaultAlipayClientApp("https://openapi.alipay.com/gateway.do", app_id, private_key, "json", "utf-8", alipay_public_key);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
String tradeId = RandomUtil.getRandomFileName();
//业务订单描述
model.setSubject(subject);
//商户订单号
model.setOutTradeNo(tradeId);
//该订单的商品总价格
model.setTotalAmount(price);
//签约卖家的账号
model.setSellerId(seller_id);  
//销售产品码
model.setProductCode("QUICK_MSECURITY_PAY");
//禁用支付方式     此处充值禁用信用卡支付
if("2".equals(payType)){
model.setDisablePayChannels("credit_group");
}
//装载订单的业务参数
request.setBizModel(model);
//支付宝异步通知地址
request.setNotifyUrl(Property.getProperty("okamiNoifyUrl").trim()); 

//定义orderString返回给app客户端
String  orderString="";
try {
   //这里和普通的接口调用不同,使用的是sdkExecute
   AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
   //就是orderString 可以直接给客户端请求,无需再做处理。
   log.info("当前用户发起"+moduleName+"返回给app客户端签名串"+response.getBody());
      orderString=response.getBody();


    
   } catch (AlipayApiException e) {
     e.printStackTrace();
}
rv.setResult("success");
rv.setData(orderString);;
return new JsonMapper().toJson(rv);
}

}else{
rv.setResult("error");
rv.setMsg(ReturnUtil.REQUEST_OVER);
return new JsonMapper().toJson(rv);
}

               好了,到这边支付宝app支付功能算完成了

             4、支付宝异步通知业务处理(这边坑最多)

            @RequestMapping(value="payment/alipayAsynchronous",method=RequestMethod.POST,produces="text/html;charset=UTF-8")
@ResponseBody
public     String      alipayAsynchronous(HttpServletRequest request){
   log.info("支付宝异步通知发起模块名:"+moduleName+"方法名为:alipayAsynchronous");
   DecimalFormat df = new DecimalFormat("######0.00");
  //获取支付宝POST请求过来的反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
log.info("支付宝异步返回结果为:"+requestParams+"***result");
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);
}
//支付宝公钥验签
String  alipay_public_key="";
String appVersion="";
if(AlipayConfigSecond.APP_ID.equals(params.get("app_id"))){
alipay_public_key=AlipayConfigSecond.ALIPAY_PUBLIC_KEY;
appVersion="2";
}else{
alipay_public_key=AlipayConfig.alipay_public_key;
appVersion="1";
}
 
log.info("异步通知参数为:params"+params);
boolean  alipayFlag=false;
try {
//利用支付宝公钥验签
alipayFlag= AlipaySignatureNew.rsaCheckV1(params, alipay_public_key, "utf-8", "RSA");
} catch (AlipayApiException e) {
e.printStackTrace();
return "response fail";
}

log.info(moduleName+"支付宝公钥验签结果:"+"alipay_public_key result is "+alipayFlag);

//公钥验签成功
if(alipayFlag){
log.info(moduleName+"支付宝公钥验签通过了:"+"alipay_public_key is sign  success");
// 商户订单号
String out_trade_no=params.get("out_trade_no");
log.info(moduleName+"商户订单号:"+"out_trade_no is "+out_trade_no);
// 支付宝交易号
String trade_no=params.get("trade_no");
log.info(moduleName+"支付宝交易流水号:"+"trade_no is "+trade_no);
// 交易状态
String trade_status=params.get("trade_status");
log.info(moduleName+"支付宝交易状态:"+"trade_status is "+trade_status);
// 开发者账号
String partner = params.get("seller_id");
//用户实际支付金额
String total_fee=params.get("receipt_amount");
log.info(moduleName+"用户实际支付金额:"+"total_fee is "+total_fee);

                               if (trade_status.equals("TRADE_FINISHED")||trade_status.equals("TRADE_SUCCESS")) {

                                                 //这边最坑,在支付宝异步通知共有五次机会,所以使用redis对支付宝的请求进行处理,我们在他支付成功后,只默认承认他的第一次通知,其他的通知我们并不做处理,不然会影响业务处理
long size=requestRedisTemplate.boundValueOps("alipay:lock:"+trade_no).increment(1);
requestRedisTemplate.expire("alipay:lock:"+trade_no,93,TimeUnit.DAYS);
if(size==1){
                       //以下是业务处理

                             



}

}
return "success";
}



  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值