暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

支付宝支付接口

Whoooops 2021-04-15
1165

支付宝支付场景是在pc网站中下单后,点击支付调起支付宝支付接口,然后再网站中显示支付二维码,用户扫码后支付。

支付流程:

  1. 在支付宝开放平台助手中获取应用私钥和应用公钥。支付宝采用的是非对称加密算法RSA。获取公钥后,将应用公钥和支付宝公钥互换。

  2. 商家使用支付宝公钥对订单信息加密,同时使应用私钥签名。支付宝收到订单信息后使用支付宝私钥解密,同时使用应用公钥对签名验签。

  3. 支付宝接收到请求后,进行验签。调起支付接口,用户扫码下单。

  4. 支付宝返回响应,异步回调,页面跳转return_url,跳转到前端页面,notify_url支付宝主动回调服务器后端方法。

项目中并没有使用支付宝SDK签名, 而是实现的自行签名。自行签名的步骤如下:

筛选并排序

获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除 sign 字段,剔除值为空的参数,并按照第一个字符的键值 ASCII 码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值 ASCII 码递增排序,以此类推。

拼接

将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用 & 字符连接起来,此时生成的字符串为待签名字符串

调用签名函数

使用各自语言对应的 SHA256WithRSA(对应sign_type为RSA2)或SHA1WithRSA(对应sign_type为RSA)签名函数利用商户私钥对待签名字符串进行签名,并进行 Base64 编码。

把生成的签名赋值给 sign 参数,拼接到请求参数中。

即:将所有需要发送的参数,sign除外,作为签名的内容。生成sign后,再将sign拼接到请求参数中。参数分为公共参数和请求参数,其中公共参数中的biz_content参数存放的是所有请求参数。biz_content是一个json字符串。


支付宝文档:

https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay


支付

    @RequestMapping(value = "/toform",method = RequestMethod.POST)
    @ResponseBody
    public Result toform(InfoBean map) throws Exception {
    //应用公钥
    String appPublicKey = "马赛克";
    //应用私钥
    String privateKey = "马赛克";
    //支付宝公钥
            String aliPayPublicKey = "马赛克";


    // 公共参数
    Map<String, String> treeMap = new TreeMap<>();
    treeMap.put("app_id","2021000116692708");
    treeMap.put("method","alipay.trade.page.pay");
    treeMap.put("charset","utf-8");
    treeMap.put("sign_type","RSA2");
    Date date = new Date();
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String format = sdf.format(date);
    treeMap.put("timestamp",format);
    treeMap.put("version","1.0");
    treeMap.put("notify_url","http://da61669ae53d.ngrok.io/aliReturnPay");//支付宝回调接口
    treeMap.put("return_url","http://127.0.0.1:8080/paysuccess.jsp");

    String biz_content="{\"out_trade_no\":\""+ map.getOut_trade_no() +"\","
    + "\"total_amount\":\""+ map.total_amount +"\","
    + "\"subject\":\""+ map.getSubject() +"\","


    + "\"body\":\""+ "body" +"\","


    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}";


    treeMap.put("biz_content",biz_content);
    // 将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用 & 字符连接起来,此时生成的字符串为待签名字符串。


    String mapToString = SignUtil.map_to_string(treeMap);
    System.out.println(mapToString);
    // String encrypt = SignUtil.encrypt(mapToString, aliPayPublicKey);//使用支付宝公钥对数据进行加密
    // 使用私钥对数据进行签名
    String signqm = SignUtil.signqm(mapToString, privateKey);


    treeMap.put("sign",signqm);
    String from = ToForm.from("https://openapi.alipaydev.com/gateway.do", treeMap);
    System.out.println(from);


    Map<String,String> maps=new ConcurrentHashMap<>();
    Result result=new Result();
    result.setCode("200");
    result.setMsg("success");
    result.setData(from);
    System.out.println(result.toString());
    return result;
    }

    验签方法:

      @RequestMapping(value = "/toform",method = RequestMethod.POST)
      @ResponseBody
      public Result toform(InfoBean map) throws Exception {
      //应用公钥
      String appPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn0L4oDCBqCaUQzuKFD/lcF3vZU5q3Mg6tb2er6ttHfxiICnCMRtv5AxmZ0z3kj5x5XDrucO6ldVM9GuCEqC2SnZBSoknDD+Vn/AASOhG5BJ+MG2h2YeLXrbfwghYUINqEMqeA57HpDPy9IS6kAuDbUi0ga2LCxUahHl8ncvd4vaTFRAkZvpvldHWThP1+KTQoCzn75H0giInDYuXQjsi4Lh/B3vwEfQViLzCbfqfV2phruUv1lS6d0pwF1t8QtbLXyGxova520iNCtIkna6l6WrkPkX59j16/RIFuzWEd3WVbDHZj0eDXfUJmLU3tsQjCKWFTeoRYLpOb2ayG0EVFwIDAQAB";
      //应用私钥
      String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfQvigMIGoJpRDO4oUP+VwXe9lTmrcyDq1vZ6vq20d/GIgKcIxG2/kDGZnTPeSPnHlcOu5w7qV1Uz0a4ISoLZKdkFKiScMP5Wf8ABI6EbkEn4wbaHZh4tett/CCFhQg2oQyp4DnsekM/L0hLqQC4NtSLSBrYsLFRqEeXydy93i9pMVECRm+m+V0dZOE/X4pNCgLOfvkfSCIicNi5dCOyLguH8He/AR9BWIvMJt+p9XamGu5S/WVLp3SnAXW3xC1stfIbGi9rnbSI0K0iSdrqXpauQ+Rfn2PXr9EgW7NYR3dZVsMdmPR4Nd9QmYtTe2xCMIpYVN6hFguk5vZrIbQRUXAgMBAAECggEARAfcorj1ubl5HdsiGZJN1RkbOSAtP9B8W8P7NDk7LFLyK6EK5eU9f6HYYIodOyhXiNYaq8izPGvYKpR+BK0IEXjAXTGHL5E9vgtMY9hs5+IKa295cq2W2Eev/3eHGiV4umGC7DL4Puk+ADtuYje41Yb4LGjQe1RxdmNa2yEJ0HgqRqlbENf+K66s02GX07IBiXjo3E94QsofIPGfJ9JburvEsbqiCcUyCu4hyeCDqCseTunmJdgqI7ZDBZWmtaAr/7/Rk9jygabhPyqsGzG9S9301PfmRxNA9JxU8KuBd15rFKyW7l/4NzzM1RHAZ7J0ZkmopH7Vnr8CUvLONRbWmQKBgQDzauqLZ1+XTp/0Fl05ExtwP3L3iudSJst5kBBZ+UqJb0ZUO7BsUzc0fZqPXeMzUXCqJ5tUSydI7p/52ZJ812UFNYvchW9XS3TAIv2ZeaNqSeBz3F9yHh6uNRWcof3s9oNPHO3EFQlqOHrHukFgwYyosZERqvzN/DT7HdNIXuEzmwKBgQCnfnCHtFOuqhy6UdhOLoCFwZJQG0nC6v66C4G7J58r+5ZUaHlDFv+P+ffA2RyvLvHgL0CqtI2wfFOHE+gIDLC4Ek4ZoQDnJG5Q14RoaUc5tNqxnFrDld0WW+eVYEi326kpC+IaswfgCYN5bETg3cyIPfyj3PG5hmePO9aT8EmSNQKBgF5b+tHRX8fqrazUIo0mcAOCRRHaobNB4KyeAQivz4oZPZ0XiltjosnRSuH6lkFld5QuSFNT0sW94vvasKN+Z+WuDSqN+0xOrtJwffhJo+RnAQBI1CMLs/76Cwet8B40rVA0uaLCOOUZQdc8x203ekxGkSLVMqyy8OLLfATY6tmzAoGBAIelqtT8gdkvA90Rc7C9kHDC+A/QSciGMI3Ty9kamZoxQupRQgPHmGmt86xHKSfnSRRasHCPkUChL7RxtrTuMiChEodHEUghBQaLxDwbJwfhJEw7aHaF5Gu7Oq6LL9lXGISZjyA4ZeRXUBcCTDYg6whby0OaKFosM6qYt4tQSwURAoGAYtYw+6EzDDIWH3X9IdGp60XmIUdI562TS/8V19TKTGvUQ3LzPLpBn3ZElGYPabKTKH4SxQEAqnuk8RY7sQFYkS7Y4uxFynw7aEvVQpLgNGZx96ZjKjoAjGy6hsbnASe2MzE0Weh9CWqaMhV0nmCRzjXZSUBZd3iXKp6WzTEWudM=";
      //支付宝公钥
      String aliPayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgizoJrPZVvPvE6nQ4pBxgmyj0uqyx+c5SsvLjiG9A0ZfD6Nt0aLvj5/MnYtCgHIzeh22sXIEEOsQobARfd9zByE7vTEwBWpUIt4BOCGeUWGepZJ76ErtHYSr3ntAHftA6JA11wBNdP9MZUCh4h5tf1NEXYfGIt+mIMVoUdLnxCZh7U29N+aJRfToTdK3vHJMixewULv/+mc2ImmFYL+HmQqQxbR82Z9Jeu96Hf6FYx4zf6AVBRHpA2hH1yefnZEBgvq6bb9K4M27jEwakJlQ8Dfz+9LPTc6mcWCQv3tApSj/AY/uBXgMO2+ttM5xmQoRtOT1aLscGlWFpDnAZSc/wwIDAQAB";


      // 公共参数
      Map<String, String> treeMap = new TreeMap<>();
      treeMap.put("app_id","2021000116692708");
      treeMap.put("method","alipay.trade.page.pay");
      treeMap.put("charset","utf-8");
      treeMap.put("sign_type","RSA2");
      Date date = new Date();
      SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String format = sdf.format(date);
      treeMap.put("timestamp",format);
      treeMap.put("version","1.0");
      treeMap.put("notify_url","http://da61669ae53d.ngrok.io/aliReturnPay");//支付宝回调接口
      treeMap.put("return_url","http://127.0.0.1:8080/paysuccess.jsp");

      String biz_content="{\"out_trade_no\":\""+ map.getOut_trade_no() +"\","
      + "\"total_amount\":\""+ map.total_amount +"\","
      + "\"subject\":\""+ map.getSubject() +"\","


      + "\"body\":\""+ "body" +"\","


      + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}";


      treeMap.put("biz_content",biz_content);
      // 将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用 & 字符连接起来,此时生成的字符串为待签名字符串。


      String mapToString = SignUtil.map_to_string(treeMap);
      System.out.println(mapToString);
      // String encrypt = SignUtil.encrypt(mapToString, aliPayPublicKey);//使用支付宝公钥对数据进行加密
      // 使用私钥对数据进行签名
      String signqm = SignUtil.signqm(mapToString, privateKey);


      treeMap.put("sign",signqm);
      String from = ToForm.from("https://openapi.alipaydev.com/gateway.do", treeMap);
      System.out.println(from);


      Map<String,String> maps=new ConcurrentHashMap<>();
      Result result=new Result();
      result.setCode("200");
      result.setMsg("success");
      result.setData(from);
      System.out.println(result.toString());
      return result;
      }


      文章转载自Whoooops,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论