发布时间:2022-11-21 02:30:22 文章来源:互联网
微博 微信 QQ空间

微信搜一搜,方便以后开发用哦!官方文档支付宝手机网站支付

微信搜一搜,方便以后开发用哦!官方文档支付宝手机网站支付

前言

微信APP支付、微信授权、微信JSAPI支付、微信退款、支付宝APP支付、支付宝手机网站支付、支付宝退款。作者已经放在公众号:JAVA大贼船上了。微信搜索未来发展!

官方文件

支付宝手机网站支付不像微信支付那么琐碎(在这里真的要吐槽一下wxpay,配置太多支付宝使用说明书,文档也不好看!!),支付宝官方文档已经写的很详细了,所以这个文章没有详细说明参数的解释

开放能力文档:

/打开/203/107084

手机网站支付接口

/apis/api_1/alipay.trade.wap.pay

开发准备

开发者使用支付宝账户登录开放平台(需要实名认证的支付宝账户),根据实际需要创建应用(如“支付应用”)。

备注:创建应用时应用状态为“开发中”支付宝使用说明书,不能正式在线调用接口。

代码实现引入依赖

    
        <dependency>
            <groupId>com.alipay.sdkgroupId>
            <artifactId>alipay-sdk-javaartifactId>
            <version>4.9.5.ALLversion>
        dependency>

参数配置

应用.yml

# 支付宝相关
ALIPAY:
 # 应用ID
  APP_ID: 
  # 应用私钥
  APP_PRIVATE_KEY: 
  #应用公钥
  APP_PUBLIC_KEY: 
  # 支付宝公钥
  ALIPAY_PUBLIC_KEY: 
  # 统一签名算法
  SIGN_TYPE: RSA2
  # 统一字符
  CHARSET: utf-8
  # 返回数据格式
  FORMAT: json
  # 支付基础API
  SERVER_URL: https://openapi.alipay.com/gateway.do
  #支付宝支付回调地址
  ALIPAY_NOTIFY_URL: 
  # 支付宝H5收银台会自动跳转回商户return_url指定的页面。
  RETURN_URL:
  # 支付宝Api版本
  API_VERSION: 1.0
   # 产品码 
  PROD_CODE: 
  # 终端信息
  TERMINAL_INFO: 
  # 终端信息类型
  TERMINAL_TYPE: 
?

yml 参数

    //支付宝相关
    @Value("$${ALIPAY.APP_ID}")
    private String appId;
?
    @Value("$${ALIPAY.APP_PRIVATE_KEY}")
    private String appPrivatekey;
?
    @Value("$${ALIPAY.APP_PUBLIC_KEY}")
    private String appPublickey;
?
    @Value("$${ALIPAY.ALIPAY_PUBLIC_KEY}")
    private String alipayPublickey;
?
    @Value("$${ALIPAY.SIGN_TYPE}")
    private String signType;
?
    @Value("$${ALIPAY.CHARSET}")
    private String charset;
?
    @Value("$${ALIPAY.FORMAT}")
    private String format;
?
    @Value("$${ALIPAY.SERVER_URL}")
    private String serverUrl;
?
    @Value("$${ALIPAY.ALIPAY_NOTIFY_URL}")
    private String alipayNotifyUrl;
?
    @Value("$${ALIPAY.RETURN_URL}")
    private String returnUrl;
?
    @Value("$${ALIPAY.API_VERSION}")
    private String apiVersion;
?
    @Value("$${ALIPAY.PROD_CODE}")
    private String prodCode;
?
    @Value("$${ALIPAY.TERMINAL_INFO}")
    private String terminalInfo;
?
    @Value("$${ALIPAY.TERMINAL_TYPE}")
    private String terminalType;
?

初始化支付宝支付配置

支付宝配置

    @Autowired
   private YmlParament ymlParament;
   
   /**
    * 设置支付宝客户端
    * @return
    */
   @Bean
   public AlipayClient setAlipayClient() {
      return new DefaultAlipayClient(
            ymlParament.getServerUrl(), 
            ymlParament.getAppId(),
            ymlParament.getAppPrivatekey(), 
            ymlParament.getFormat(), 
            ymlParament.getCharset(), 
          //这里不要搞错,这里是应用公钥而不是支付宝公钥
            ymlParament.getAppPublickey(), 
            ymlParament.getSignType()
            ); 
   }
   
/**
     * 设置网页支付请求基础参数
     * @return
     */
    @Bean
    public AlipayTradeWapPayRequest setAlipayTradeWapPayRequest() {
        AlipayTradeWapPayRequest atwpr = new AlipayTradeWapPayRequest();
        atwpr.setApiVersion(ymlParament.getApiVersion());
        atwpr.setProdCode(ymlParament.getProdCode());// 产品码
        atwpr.setTerminalInfo(ymlParament.getTerminalInfo());// 终端信息
        atwpr.setTerminalType(ymlParament.getTerminalType());// 终端信息类型
        return atwpr;
    }
?

手机网站支付

中方支付

    /**
     * 手机网站支付
     * 
     * @param ac        支付宝客户端,传入 @Autowired AlipayClient
     * @param rquest    基础参数,传入 @Autowired AlipayTradeWapPayRequest
     * @param returnUrl 付款成功后跳转的页面
     * @param notifyUrl 付款成功后通知的页面或方法
     * @param mode      实际参数,参考:https://opendocs.alipay.com/open/203/107090
     */
    public static AlipayTradeWapPayResponse wapPay(AlipayClient ac, AlipayTradeWapPayRequest rquest, String returnUrl,
            String notifyUrl, AlipayTradeWapPayModel mode) throws AlipayApiException {
        rquest.setBizModel(mode);
        rquest.setReturnUrl(returnUrl);
        rquest.setNotifyUrl(notifyUrl);
        return ac.pageExecute(rquest);
    }
?
    /**
     * 手机网站支付,处理业务参数
     */
    public static AlipayTradeWapPayResponse wapPay(AlipayClient ac, AlipayTradeWapPayRequest rquest, String returnUrl,
            String notifyUrl, String orderNo,String subject,String orderAmount) throws AlipayApiException {
        AlipayTradeWapPayModel mode = new AlipayTradeWapPayModel();
        mode.setOutTradeNo(orderNo);
        mode.setSubject(subject);
        mode.setTotalAmount(orderAmount);
        return wapPay(ac, rquest, returnUrl, notifyUrl, mode);
    }
?
/**
     * 支付宝支付回调验证签名
     * 验证签名;参考:https://opendocs.alipay.com/open/203/105286
     * @param params       参数
     * @param alipayPublickey 传入支付宝公钥
     * @return true 正确 false 失败
     * @throws AlipayApiException
     */
    public static boolean rsaCheckV1(Map<String, String> params, String alipayPublickey) throws AlipayApiException {
        return AlipaySignature.rsaCheckV1(params, alipayPublickey, "utf-8", "RSA2");
    }
?

服务层(业务逻辑省略)

    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private AlipayTradeWapPayRequest alipayTradeWapPayRequest;  
?
?
    @Transactional
    @Override
    public String insertAlipayH5PayInfo(String sendOrderNo,String subject, String orderAmount){
        try {
            AlipayTradeWapPayResponse alipayTradeWapPayResponse = ZfbPay.wapPay(alipayClient, alipayTradeWapPayRequest, ymlParament.getReturnUrl(),
                    ymlParament.getAlipayNotifyUrl(), sendOrderNo, subject, orderAmount);
            /* 获取页面成功 */
            if (!alipayTradeWapPayResponse.isSuccess()) {
                throw new RuntimeException(alipayTradeWapPayResponse.getMsg());
            }
            return alipayTradeWapPayResponse.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

控制器(略)

到这里支付宝支付就成功了,微信支付是不是简单多了^_^,然后支付宝回调通知成功后会回调页面和服务器

官方文档:/open/203/105286

?
    @ApiOperation("支付宝回调")
    @PostMapping("callback")
    public String callback(HttpServletRequest request) throws Exception {
        Object object = new Object();
        Map<String, String> params = convertRequestParamsToMap(request);
        log.info("支付宝回调:已回调,参数为====" + params);
           try {
              checkCallbackAlipay(params);
               /*处理一些业务*/
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ZfbUtils.RETURN_SUCCESS;
        }
    }
?
/**
     * 校验签名
     *验签文档:https://opendocs.alipay.com/open/203/105286
     */
    private void checkCallbackAlipay(Map<String, String> params) throws Exception {
        if (!"TRADE_SUCCESS".equals(params.get("trade_status"))) {
            throw new Exception("支付宝支付失败!");
        }
        //校验签名
        if (!ZfbPay.rsaCheckV1(params, ymlParament.getAlipayPublickey())) {
            throw new Exception("支付宝回调签名认证失败");
        }
        //校验一些业务逻辑
        //订单是否支付重复
        //判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
        //.....
        // 校验通知中的seller_id(或者seller_email)是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),
        // 验证app_id是否为该商户本身。
        if (!params.get("app_id").equals(ymlParament.getAppId())) {
            throw new Exception("APPID不对!");
        }
    }
?
/**
     * 获取支付宝回调参数
     */
private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;
            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }
        return retMap;
    }

交易查询

如果您不想在回调支付的时候做验签,那么我们可以主动查询订单是否支付成功

 /*查询订单是否支付成功*/
AlipayTradeQueryResponse response = orderQuery(ac, params.get("out_trade_no"));
                if (!"TRADE_SUCCESS".equals(response.getTradeStatus())){
                    throw new Exception("<==支付宝支付失败==>订单号为【"+ params.get("out_trade_no")+ "】的订单");
                }
?
/**
     * 交易查询接口,处理业务参数                            https://opendocs.alipay.com/apis/api_1/alipay.trade.query#%E5%93%8D%E5%BA%94%E5%8F%82%E6%95%B0  
     * @param outTradeNo 订单号
     * @return
     * @throws AlipayApiException
     */
    public static AlipayTradeQueryResponse orderQuery(AlipayClient ac , String outTradeNo) throws Exception {
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(outTradeNo);
        AlipayTradeQueryResponse response = tradeQuery(ac,model);
        if(!response.isSuccess()){
            throw new Exception("调用支付宝查询接口失败");
        }
        return response;
    }
?
/*交易查询接口*/
    public static AlipayTradeQueryResponse tradeQuery(AlipayClient ac,AlipayTradeQueryModel model) throws AlipayApiException{
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizModel(model);
        return ac.execute(request);
    }

另一视角

换一换