支付宝app-java后台

App支付快速接入网址: https://docs.open.alipay.com/204/105297/

第一步:创建应用并获取APPID


第二步:配置应用

添加app支付功能

签约


配置密钥

        这里的秘钥分为两种,支付宝公钥和应用公私玥.支付宝公钥是支付宝在回调判断请求是否来自于支付宝的请求的秘钥,需要设置在app应用里的公钥,应用公私玥是支付宝交易中对交易项进行加密的钥匙,公钥需要上传到app应用中,私钥则需要存在自己的app上,这些参数在java后台都需要存入配置文件中.(秘钥的方式都尽量采取RSA2格式)

上传应用公钥并获取支付宝公钥 https://docs.open.alipay.com/291/105972

第三步:集成和开发




以上配置完成,主要分为app创建应用,应用开通app支付功能,应用公私玥的生成与上传以及支付宝公钥的上传,sdk在android和ios集成后,服务端这边就可以直接编写接口,主要大概分为两个接口,支付接口和回调接口;

支付宝配置文件类,主要是存储支付宝参数

public class AlipayConfig {

  // 1.商户appid

  public static String APPID = "";

  // 2.支付宝公钥

  public static String ALIPAY_KEY = "";

  // 3. 支付宝应用私钥

  public static String ALIPAY_PRIVATE_KEY ="";

  // 4.服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问

  public static String notify_url = "http://www.xxx.com/alipay/notify_url.do";


  // 5.页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址

  public static String return_url = "http://www.xxx.com/alipay/notify_url.do";

  // 6.请求网关地址

  public static String URL = "https://openapi.alipay.com/gateway.do";

  // 7.编码

  public static String CHARSET = "UTF-8";

  // 8.返回格式

  public static String FORMAT = "json";

  // 9.加密类型

  public static String SIGNTYPE = "RSA2";

}

预支付的接口


@ApiOperation(value= "支付宝预支付", httpMethod= "POST")

@PostMapping(value= "/aliPayReady", produces= "application/json;charset=UTF-8")

@ResponseBody

public RespBaseDto aliPayReady(

      @RequestBody AlipayVo info) throws AlipayApiException {

  String out_trade_no= info.getOut_trade_no();

  String total_amount= info.getTotal_amount();

  RespBaseDto baseDto= new RespBaseDto<>();

  String orderStr= "";

  try {

      FxSdCarriageOrder order= orderService.selectOrderByOrderSn(Long.parseLong(out_trade_no));

      if(order!=null&&order.getStatus()==1){

        BigDecimal orderTotalAccount= order.getDispatchPrice();

        int i= orderTotalAccount.compareTo(new BigDecimal(total_amount));

        if(i==0){

            //传入订单金额正确

            Map orderMap= new LinkedHashMap();            //订单实体

            Map bizModel= new LinkedHashMap();            //公共实体

            // 商户订单号,商户网站订单系统中唯一订单号,必填

            orderMap.put("out_trade_no",out_trade_no);

            // 订单名称,必填

            orderMap.put("subject","手机网站支付购买游戏币");

            // 付款金额,必填

            orderMap.put("total_amount",total_amount);

            // 商品描述,可空

            orderMap.put("body","您购买游戏币"+total_amount+"元");

            // 超时时间 可空

            orderMap.put("timeout_express","5m");

            // 销售产品码 必填

            orderMap.put("product_code","QUICK_MSECURITY_PAY");

            /****** 2.商品参数封装结束 *****/

            /******--------------- 3.公共参数封装 开始 ------------------------*****/        //支付宝用

            //1.商户appid

            bizModel.put("app_id",AlipayConfig.APPID);

            //2.请求网关地址

            bizModel.put("method",AlipayConfig.URL);

            //3.请求格式

            bizModel.put("format",AlipayConfig.FORMAT);

            //4.回调地址

            bizModel.put("return_url",AlipayConfig.return_url);

            //5.私钥

            bizModel.put("private_key",AlipayConfig.ALIPAY_PRIVATE_KEY);

            //6.商家id

            bizModel.put("seller_id","2088102170411333");

            //7.加密格式

            bizModel.put("sign_type",AlipayConfig.SIGNTYPE+"");

            //8.回调地址

            bizModel.put("notify_url",AlipayConfig.notify_url);

            /******--------------- 3.公共参数封装 结束 ------------------------*****/

            //实例化客户端

            AlipayClient alipayClient= new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",

                  AlipayConfig.APPID, AlipayConfig.ALIPAY_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_KEY, "RSA2");

            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay

            AlipayTradeAppPayRequest request= new AlipayTradeAppPayRequest();

            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。

            AlipayTradeAppPayModel model= new AlipayTradeAppPayModel();

            model.setBody("帮我买-帮我取-帮我送");

            model.setSubject("成都小短腿");

            model.setOutTradeNo(out_trade_no);//更换为自己的订单编号

            model.setTimeoutExpress("5m");

            model.setTotalAmount(total_amount);//订单价格

            model.setProductCode("QUICK_MSECURITY_PAY");

            request.setBizModel(model);

            request.setNotifyUrl("");//回调地址不可以带参数,这里的设置有效使用

            //String orderStr = "";

            try {

              //这里和普通的接口调用不同,使用的是sdkExecute

              AlipayTradeAppPayResponse response= alipayClient.sdkExecute(request);

              orderStr= response.getBody();

              System.out.println(orderStr);//就是orderString 可以直接给客户端请求,无需再做处理。

            } catch (AlipayApiException e) {

              e.printStackTrace();

}

            baseDto.setMessage("订单生成成功");

            baseDto.setState(200);

            baseDto.setData(orderStr);

        //订单号不存在

        }else{

            baseDto.setMessage(EWarning.OrderAccountError.getName());

            baseDto.setState(EWarning.OrderAccountError.getValue());

            baseDto.setData(orderStr);

}

      }else{

        baseDto.setMessage(EWarning.NoOrderInfo.getName());

        baseDto.setState(EWarning.NoOrderInfo.getValue());

        baseDto.setData(orderStr);

}

  } catch (Exception e) {

      baseDto.setMessage("订单生成失败");

      baseDto.setState(400);

      baseDto.setData(orderStr);

}

  return baseDto;

}

回调接口(这里也需要在app应用中设置回调位置)

@RequestMapping(value="/notify",method={RequestMethod.POST,RequestMethod.GET})

@ResponseBody

public String notify(HttpServletRequest request, HttpServletResponse response) throws IOException {

  Map params= new HashMap<>();

  //Trade trade =null;

  //1.从支付宝回调的request域中取值

  Map requestParams2= request.getParameterMap();

  for (Iterator iter= requestParams2.keySet().iterator(); iter.hasNext();) {

      String name= iter.next();

      String[] values= requestParams2.get(name);

      String valueStr= "";

      for (int i= 0; i< values.length; i++) {

        valueStr= (i== values.length - 1) ? valueStr+ values[i] : valueStr+ values[i] + ",";

}

      // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化

      // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");

      params.put(name, valueStr);

}

  //2.封装必须参数

  String out_trade_no= request.getParameter("out_trade_no");            // 商户订单号

  String orderType= request.getParameter("body");                    // 订单内容

  String tradeStatus= request.getParameter("trade_status");            //交易状态

  String tradeNo= request.getParameter("trade_no");

  System.out.println("orderType:"+orderType);

  System.out.println("tradeNo:"+tradeNo);

  //3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)

  boolean signVerified= false;

  try {

      //3.1调用SDK验证签名

      signVerified= AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);

  } catch (AlipayApiException e) {

      e.printStackTrace();

}

  //4.对验签进行处理

  if (signVerified) {    //验签通过

      if(tradeStatus.equals("TRADE_SUCCESS")) {    //只处理支付成功的订单: 修改交易表状态,支付成功

        FxSdCarriageOrder order= orderService.selectOrderByOrdersn(out_trade_no);

        if(order!=null){

            FxSdUserMember fxSdUserMember= userService.selectUserByUserId(order.getMemberId() + "");

            order.setStatus((byte)2);

            order.setPayType((byte)22);

            System.out.println(tradeNo);

            order.setTransId(tradeNo);

            orderService.updateOrder(order);

            //logger.info("订单号:"+out_trade_no+",订单状态修改成功orderStatus:"+order.getStatus());

            logger.info("订单编号:"+order.getOrdersn()+",下单用户电话:"+fxSdUserMember.getMobile()+",收货人电话:"+order.getEndPhone()

                  +",支付类型:"+order.getPayType()+",订单类型:"+order.getOrderType()+",运费:"+order.getDispatchPrice()+

                  ",小费:"+order.getTipPrice()+",第三方支付编号:"+order.getTransId()+",订单内容:"+order.getRemark()+

                  ",下单时间:"+order.getCreateTime()+",抢单时间:"+order.getOrderTime()+",订单状态:"+order.getStatus());

            return "success";

        }else{

            return "fail";

}

      }else{

        return "fail";

}

  } else {  //验签不通过

      System.err.println("验签失败");

      return "fail";

}

}

支付到此就可以了.然后还有一系列的退款,提现类似,依葫芦画瓢就可以了.支付宝java后端集成官网都有很好的例子,也很简单,业务逻辑自己添加即可.自己写下来铭记就怕以后忘记了.

服务端java https://docs.open.alipay.com/54/106370

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容