支付宝扫码支付


最近重构项目时,负责了支付模块,微信扫码支付(NATIVE)和 支付宝扫码支付,也是第一次接触,虽然根据官方文档和一些博客写出来了,但是遇到的问题却很多,走了很多弯路,浪费了很多精力和时间,抽出时间来记录一下,以后难免还是会用到。

微信扫码支付传送门

支付宝支付需要沙箱测试,需要配置沙箱环境。

沙箱配置方式和遇到的坑

支付宝官方文档 介绍的很详细,接下来直接上代码,文档和代码结合着思路会更清晰:

获取支付宝二维码支付:

private Map<String, Object> getPayCodeByAliPay(PayCodeRequest payCodeRequest) {log.info("获取支付宝二维码请求*******");Map<String, Object> resultMap = new HashMap<>(16);String currentUserID;String orderID;BizContentByAliPay bizContent;AlipayMakeContent makeCode;try {orderID = payCodeRequest.getOrderID();currentUserID = payCodeRequest.getCurrentUserID();SystemConfig queryOneSystemConfig = orderPayService.queryOneSystemConfig("cm2_aliPayAccount");bizContent = new BizContentByAliPay();bizContent.setOut_trade_no(CommonUtils.genPayId());bizContent.setSubject(payCodeRequest.getProductName());String payAmount = payCodeRequest.getPayAmount().replace(",", "");bizContent.setTotal_amount(new BigDecimal(payAmount));bizContent.setBody(payCodeRequest.getValidityPeriod());PayRecord queryOrderPayRecordByOrderID = orderPayService.queryPayRecordByOrderID(orderID);if (null != queryOrderPayRecordByOrderID && OrderPayStatusEnum.PAID.getValue() == queryOrderPayRecordByOrderID.getPayStatus()) {log.info("支付的类型:" + queryOrderPayRecordByOrderID.getPayType());log.debug("订单已存在支付过记录");resultMap.put("code", -20003);resultMap.put("desc", "订单已支付,无法再次操作");return resultMap;}makeCode = AliPayUtil.makeCode(queryOneSystemConfig.getConfigValue(), bizContent);if (null == makeCode || null == makeCode.getAlipay_trade_precreate_response()) {resultMap.put("code", -20001);resultMap.put("desc", "获取支付宝支付二维码失败");payLogService.createPayLog(currentUserID, new Gson().toJson(bizContent), orderID, new Gson().toJson(makeCode), 1);return resultMap;}AliPayMakeResponse alipay_trade_precreate_response = makeCode.getAlipay_trade_precreate_response();String qr_code = alipay_trade_precreate_response.getQr_code();//生成二维码String base64Code = QRCodeUtil.getBase64Code(qr_code);log.info("生成的二维码:", base64Code);/*** 有记录,且非已支付*/if (null != queryOrderPayRecordByOrderID) {queryOrderPayRecordByOrderID.setOrderID(payCodeRequest.getOrderID());queryOrderPayRecordByOrderID.setPayType(OrderPayTypeEnum.ALIPAY.getValue());queryOrderPayRecordByOrderID.setSign(makeCode.getSign());queryOrderPayRecordByOrderID.setEditor(payCodeRequest.getCurrentUserID());queryOrderPayRecordByOrderID.setEditTime(new Date());queryOrderPayRecordByOrderID.setPayStatus(OrderPayStatusEnum.UNPAID.getValue());queryOrderPayRecordByOrderID.setQr_code(qr_code);queryOrderPayRecordByOrderID.setOut_trade_no(bizContent.getOut_trade_no());long longValue = (new BigDecimal(payAmount).multiply(new BigDecimal("100"))).longValue();queryOrderPayRecordByOrderID.setPayAmount(longValue);orderPayService.updateOrderPayRecord(queryOrderPayRecordByOrderID);} else {PayRecord payRecord = new PayRecord();payRecord.setOrderID(payCodeRequest.getOrderID());payRecord.setPayType(OrderPayTypeEnum.ALIPAY.getValue());payRecord.setSign(makeCode.getSign());payRecord.setOperator(payCodeRequest.getCurrentUserID());payRecord.setCreateTime(new Date());payRecord.setPayStatus(OrderPayStatusEnum.UNPAID.getValue());long longValue = (new BigDecimal(payAmount).multiply(new BigDecimal("100"))).longValue();payRecord.setPayAmount(longValue);payRecord.setOut_trade_no(bizContent.getOut_trade_no());payRecord.setQr_code(qr_code);orderPayService.createOrderPayRecord(payRecord);}resultMap.put("code", 0);resultMap.put("desc", "获取成功");resultMap.put("data", base64Code);resultMap.put("out_trade_no", bizContent.getOut_trade_no());return resultMap;} catch (Exception e) {log.error("获取支付宝二维码处理异常*******", e);resultMap.put("code", -20001);resultMap.put("desc", "获取支付宝支付二维码失败");return resultMap;}

支付宝支付工具类

public class AliPayUtil {private static String FORMAT = "json";private static String CHARSET = "UTF-8";/*** @name 阿里获取二维码接口* @throws AlipayApiException* @Param out_trade_no 商户订单号,64个字符以内、只能包含字母、数字、下划线;需保证在商户端不重复* @Param total_amount 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 如果同时传入了【打折金额】,【不可打折金额】,* 【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】* @Param subject 订单标题* @Param store_id 商户门店编号* @Param timeout_express 该笔订单允许的最晚付款时间,逾期将关闭交易。* 取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。*/public static AlipayMakeContent makeCode(String aliPayAccountData, BizContentByAliPay bizContent) {log.info("获取支付宝支付二维码********");log.info("aliPayAccountData:" + aliPayAccountData);log.info("bizContent:" + new Gson().toJson(bizContent));AlipayMakeContent payMakeContent = null;try {AliPayAccount aliPayAccount = new Gson().fromJson(aliPayAccountData, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();String timeout_express = aliPayAccount.getTimeout_express();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类bizContent.setTimeout_express(timeout_express);if (null != aliPayAccount.getNotifyUrl() && !"".equals(aliPayAccount.getNotifyUrl())) {request.setNotifyUrl(aliPayAccount.getNotifyUrl());}if (null != aliPayAccount.getReturnUrl() && !"".equals(aliPayAccount.getReturnUrl())) {request.setReturnUrl(aliPayAccount.getReturnUrl());}//把订单信息转换为json对象的字符串request.setBizContent(new Gson().toJson(bizContent));AlipayTradePrecreateResponse response = alipayClient.execute(request);payMakeContent = new Gson().fromJson(response.getBody(), AlipayMakeContent.class);return payMakeContent;} catch (Exception e) {log.error("调用支付宝生产二维码异常:", e);return null;}}/*** 获取支付宝二维码* @param aliPayAccountData 支付宝账号json* @param bizContent 业务参数* @return*/public static Map<String, Object> orderPayByAliPay(String aliPayAccountData, BizContentByAliPay bizContent) {log.info("获取支付二维码body********");log.info("aliPayAccountData:" + aliPayAccountData);log.info("bizContent:" + new Gson().toJson(bizContent));Map<String, Object> resultMap = new HashMap<String, Object>();resultMap.put("code", 0);try {AliPayAccount aliPayAccount = new Gson().fromJson(aliPayAccountData, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();String notifyUrl = aliPayAccount.getNotifyUrl();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request/* alipayRequest.setReturnUrl(returnUrl);*/alipayRequest.setNotifyUrl(notifyUrl);//在公共参数中设置回跳和通知地址/* bizContent.setOut_trade_no(BaseUtil.genPayID());bizContent.setTotal_amount(new BigDecimal("799.90"));bizContent.setSubject("赛门铁克DV证书");bizContent.setBody("1年期证书");*/alipayRequest.setBizContent(new Gson().toJson(bizContent));AlipayTradePagePayResponse pageExecute = alipayClient.pageExecute(alipayRequest); //调用SDK生成表单if (pageExecute.isSuccess()) {String body = pageExecute.getBody();resultMap.put("data", body);return resultMap;}log.error("未成功获取支付二维码:", new Gson().toJson(pageExecute));resultMap.put("code", -20001);resultMap.put("desc", "获取支付宝支付二维码失败");return resultMap;} catch (Exception e) {log.error("获取支付二维码body异常:", e);resultMap.put("code", -20001);resultMap.put("desc", "获取支付宝支付二维码失败");return resultMap;}}/*** 查看支付交易信息* @param aliPayAccountData* @param query* @return*/public static AliPayQueryContent queryPay(String aliPayAccountData, BizContentQueryByAliPay query) {log.info("查询支付宝交易信息********");log.info("aliPayAccountData:" + aliPayAccountData);log.info("query:" + new Gson().toJson(query));AliPayQueryContent payContent = new AliPayQueryContent();try {AliPayAccount aliPayAccount = new Gson().fromJson(aliPayAccountData, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();request.setBizContent(new Gson().toJson(query));AlipayTradeQueryResponse response = alipayClient.execute(request);log.info("查询结果:" + response.getBody());payContent = new Gson().fromJson(response.getBody(), AliPayQueryContent.class);return payContent;} catch (Exception e) {log.error("查询支付宝交易信息异常:", e);return null;}}/*** 退款操作:* 退款成功注意事项。全额退款情况:trade_status= TRADE_CLOSED,而refund_status=REFUND_SUCCESS;非全额退款情况:trade_status= TRADE_SUCCESS,而refund_status=REFUND_SUCCESS* @param aliPayAccountData* @param refund* @return*/public static TradeResponseContent refund(String aliPayAccountData, BizContentRefundByAliPay refund) {log.info("支付宝进行退款操作********");log.info("aliPayAccountData:" + aliPayAccountData);log.info("query:" + new Gson().toJson(refund));TradeResponseContent tradeContent = null;try {AliPayAccount aliPayAccount = new Gson().fromJson(aliPayAccountData, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);//设置请求参数AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();alipayRequest.setBizContent(new Gson().toJson(refund));AlipayTradeRefundResponse execute = alipayClient.execute(alipayRequest);tradeContent = new Gson().fromJson(execute.getBody(), TradeResponseContent.class);return tradeContent;} catch (Exception e) {log.error("支付宝退款异常:", e);return null;}}/*** 查询退款信息* @param aliPayAccountData* @param tradeRefundQuery* @return*/public static TradeResponseContent refundQuery(String aliPayAccountData, TradeRefundQuery tradeRefundQuery) {log.info("查询支付宝退款详情操作********");log.info("aliPayAccountData:" + aliPayAccountData);log.info("tradeRefundQuery:" + new Gson().toJson(tradeRefundQuery));TradeResponseContent tradeContent = null;try {AliPayAccount aliPayAccount = new Gson().fromJson(aliPayAccountData, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);//设置请求参数AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();alipayRequest.setBizContent(new Gson().toJson(tradeRefundQuery));//请求String body = alipayClient.execute(alipayRequest).getBody();//输出tradeContent = new Gson().fromJson(body, TradeResponseContent.class);return tradeContent;} catch (AlipayApiException e) {log.error("查询支付宝退款异常:", e);return null;}}private static void query(String value) {BizContentQueryByAliPay query = new BizContentQueryByAliPay();query.setOut_trade_no("1909251da8f845545b6588");AliPayQueryContent queryPay = queryPay(value, query);System.err.println(new Gson().toJson(queryPay));}private static void pay(String value) throws Exception {BizContentByAliPay bizContent = new BizContentByAliPay();bizContent.setOut_trade_no("1909251da8f845545b6588");bizContent.setTotal_amount(new BigDecimal("0.01"));bizContent.setSubject("Symantec EV强制型");bizContent.setBody("1年期证书");AliPayAccount aliPayAccount = new Gson().fromJson(value, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();String timeout_express = aliPayAccount.getTimeout_express();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类bizContent.setTimeout_express(timeout_express);request.setNotifyUrl(aliPayAccount.getNotifyUrl());//把订单信息转换为json对象的字符串request.setBizContent(new Gson().toJson(bizContent));AlipayTradePrecreateResponse response = alipayClient.execute(request);AlipayMakeContent payMakeContent = new Gson().fromJson(response.getBody(), AlipayMakeContent.class);QRCodeUtil.encode(payMakeContent.getAlipay_trade_precreate_response().getQr_code(), "D:/" + bizContent.getOut_trade_no() + ".jpg");System.err.println(new Gson().toJson(payMakeContent));}public static void main1(String[] args) throws AlipayApiException {String value = "{\"applicationUrl\":\"https://openapi.alipaydev.com/gateway.do\",\"app_id\":\"2016082000290858\",\"app_private_key\":\"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCZ1RBO92Rl+JwlM8471+rlctOSeKblBz15k1RkGrbv8+dUzvnvBENylG811eIEqEhfWefsIMeqPnbAG3wpeDbyRDgmFWiZZmBGcO2UKAM2+tDI1AfEgDxs2sKeasdigVqzccXJsr5fRfB8+BnLjEceaaXutegQA61Bm45/bhXT8TErFgJWJX5ucHrIVGDX/xqCiuZ5AjKLM0bhSG2cmy7E5bnhtCzMWt9QcM9g3lMSp1745Op7Yw3S+LonEE564GEnR4jUuWMVfEE+dQHuiJ4RKY/n3vzJHVdt5BTj3CR5+J2kHWuHBw4/kuZxPtdAA+aPZYkv05XdPdRfIifr/cxDAgMBAAECggEBAIvFFS5KhYRJIMaEjYu+IQUdEbLxwOIzc920yWazByh6OePKszhCbW38BBesH9IPfMJ2E81t8zxxyL+/uU6MlZAF/+ZKaWGHrU4TaSnGOTWJKo5uaChYQ468LTx21HZiBaEpbIZYy7QQ/fLuEbHp4Ox3HXcI/LMgRBlqV0zdHyQTgYYMFZLOg49vKloNeC+DEqoFhBFskdc2nit0B7WvXTk5qZfdRTcLPHLz2Ih1rJrFz8niwLz5exBGG2jWFIsbhQ/hHFPmiaPYvYX0sCAZz5jxUlgFQ2DRAXrrPW9Qy0j83V9yn2jFBBGf5Ff5PcDb5OgaJppPo9pjw7y3/xzZ/zECgYEA7ARBC2QPh1PdRRUd1MIftN9Wi9q/W+rA1jp9OpCY6t1+CskajqNGLA5z402oHLqq+gOtf7lsZkrZVrlEmnJbojblWejrx7GbZHTLJXrPKxkOCaqPzqPdEaFfqvdVjB8xqJd0JdGxVLAEMWJYavWmqpTpmkdTwJHkoJ5nOKP7D1cCgYEApttvK3ySOBUEcWS6SnDqZvcvKzPe0zSc0v22zIvyxpAGOetRNMKPbWLrJsiYEOeEYlhjVb6Ovh7qjXiSWskSGkytjlDh1ReigEHnDjmKEr/5JqvRSzL7Jh03+ypmGWZ2NUlmee3TEZI5HnU5B2nnlV4MibqZnnq8YCCI4CT8EvUCgYB+aITh8fSzOYKwhm/UzSgoOtpiy4VkWKZx1x/NZzbPzFO+uRlFPkPOQutk2enpgT0j7SZW21woqXwgi9gnlIpppldOwYbPDNw6gKdxaoZdAe1X1gdx2KgF0lWn/xLNmsOBFaU6wEXnIuMMBC1xFCLxCBLZ88vyvvEh6dVFK+bCvwKBgQCTVZ3zazr9tGlI62Wnx87i/o8y+cle+80ibY/VTBoihRhKWmRJTycwsrDrfSLxgk0ePefw1aPbcxcvtnCdI4ENofl6eib/b7A4yniI0fv+lG8fW4YifbDQteoxqP2gnh3w7ZBER+EhWdl/8Ihb6ILqHLK7hv6QttXRl8jlCyNeZQKBgDz4HhUkc1Mig1bD8mgkQPkMiptd6/jidLoRJ/ExoR2Ctab4ixPGEYuPNfTqpK7wdto70z0i/HmtwWY3e3doeMYeF9PiNjDiqElx5266G8r3lFIbMKGj849h41u0k50swshAx3MboJv3y0N+oZ97u3E9a7FA5s319GCf9jE618xv\",\"alipay_public_key\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSpfv47tdtCJCZXhbEUtqoofSQLRCFLYCG6U8Q7wiDytFGVyI1Dby3M6bvHjREjb7imoox4Lrsg66lbnTLeEuetAnukU0GhAM/1zzVBnV6iTDy5fq4tEDVCWCY6+GLn6YNgOC+RVPrko5mYs+GIexWhT+QWvNcrewBYjdWWEY2PeoKf5ZgSkgfZELZcEPOWDaPzdn95J1U90cwakLL360C/E9s0h/mkRjxMSgQVfQef1JmNSpqyc+5uT3VJp4PcqQX1/RpawJG1B0NBaxmrAYJDdA1F7VgUzNIdLW6z+8IvQXG+7NuAayNgaelgdfkz+l3hebaMKrMxMKl2pNiqkpwIDAQAB\n\",\"sign_type\":\"RSA2\",\"returnUrl\":\"http://daguoge.vaiwan.com/callback/return\",\"notifyUrl\":\"http://daguoge.vaiwan.com/callback/notify\"}";value = "{\"applicationUrl\":\"https://openapi.alipaydev.com/gateway.do\",\"app_id\":\"2016101400684128\",\"app_private_key\":\"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCQsOVWbMEmpCk78dmXFAPM1tofr3OMLExNHKmZ9ysbtffnMAaa5LgLaeAZRaMOgFJuhO25MYAONKPrUfNMTeeqNIR2xf0C5faYSyE2ludrL84BlpufH6Wh6XE+gniagpytndtN7Qa/ZDQ+/jKLWL95NnYPXZiWuQWsrLDbKn10d1BmBF3klfnG0RZR7l7wXg8QvrrT6neU4nS/xqEtR+F/HRgGApq2w5BTINlob2IML7C0YOJiZUAhYBwpa6Tz2s9aafkCE1Xh02uJ5uliur0QFNPgrAKmtfbHJnNv3W45geRRvwq83EYSBsjJttVEKkhr/YpKGPdnnEcpwn7gXIILAgMBAAECggEALDwooRd2pZ2ijZUO9MVFtCYrYWx+YuhYG2sb3tpV747eT2u7WTd7nOGthYxooVJR4T/6fZfIko89XgAb5cQbg0mzBazaATzU+xJdARd5gKeIz6t/wFIojSuVV4sD3Bj6VYnhNh205mZ4IpoMUdW8FA62YVQ4Bjxio7vYBekjmas4u0gwIynFYpn8vaQ3Kg5O9bO09N52cJlCWxu1LD3uopD7aCBxEB0JvOfvB/kDorzrZGMbiU6kDTk5IwvAXuFGkXo1RPmHOmdYpyt0yhepqylBwBQ1ta7alKOFFl9vop79Rm3Ej+naXYQZXuXLlknDnAQM6N2tyHPN+OHUTzOywQKBgQDognTdCiopINAWryux8zrCMa9x0OnJ1p6IwrCtWIYnpTR/zYe35fzFk29MN8iEU/mj8UCaHkq6jQdK2ZSd/w8qZ5BDxvL3DQThvn4mk2jyUIwzYFuoPDJEd2JzTabKrRs2nWlGsb4tjiLTR3EBTzSNyhy3jaHEwz+LMYKt1RCVgwKBgQCfTyGT0pPGRM3zOKXkQjeTwgwiNqEQfvJDvIKNqrTPXH6SRyZjptdTy669y4Is8K2qnj7LdHmdznDB0p0uLG5ajSK0yAvstT2Be6DTtPEmWUfCXmd7dXHBFpmcJGeGCGgcYuGPIAp+BhUJdC14AzOlzwLMVgMZAnufpalJzJZC2QKBgEa6aJJU5T5dnO9JmiEnvFgWhSg6ROQBRXiUwOn6Y9TrjGzUONTYQWxYzSKCVZzrbqVQXjaDwHe/Lti2F194l0Ru/JOhkYdVjoadTAKwFNyhZAS86yTiKuho6KnqlTJSNlUGzV+T8iYpdq6OrPGZBoObV+D+VJdmTY4qIXZ/uevBAoGAaurgziT1qItk7WeHbrpCMph5LD0du8R3M57Av/Nhhgm9qM63pQnEWijJDfgXVbHx3CB4ZHO3a4Gxi2Oeue534a33LP1Vg3ff35bpSSyW6/Xfg0N4kBMyVTSlw3VrRTk/Jk32s+f9IrdSRxYBrhn3/7//UMQpMA/KiErWYwE7l4ECgYAzYfE2zUdUw3+NDFYP3d/rZdAhmlKW7Lx76tCfGYO1Bcbx1TDGYrqa9s12GX+jFsSc03a3QmUednf+NeLR3lYSb8Sm9BoYZKRmLt8p1HYeulsEjYMOd7tPqwXXl4B/HiZm9sPJeglr/pA6Rvp3KTQdk1+i075olUsPmryalsfLgw==\",\"alipay_public_key\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn12eE8oUUiZZIOqj6+1toJ71xyfx74r7GpgiqK9uWaebLMghFkjqqg4NApOgXcNckPRo5oDl5G6j20h8vAPS6zhkeQItph5qqSpCj7i06ieeBUReijmyeHY6jL0gMc8gMJyX4FbdASZQvE2D1B3aveDT1YL0X2AedTziBWxu+qlE5d3QA+KBfoxd6azzTjayi0VrDNN7rpni8/GKILBfty+KypLZc3ZrVUvEa+dkRY4VXAG36wYbU+FIudutra3BM2zTOGWPL+p9pbHrVZ/MGhRS1nWntRy+sCaYJidq9RVgY54UPb8OolvnL56LGi56BT1shFZetDfLnkfLDfIUvwIDAQAB\",\"sign_type\":\"RSA2\",\"returnUrl\":\"http://daguoge.vaiwan.com/callback/return\",\"notifyUrl\":\"http://daguoge.vaiwan.com/callback/notify\"}";AliPayAccount aliPayAccount = new Gson().fromJson(value, AliPayAccount.class);String URL = aliPayAccount.getApplicationUrl();String app_id = aliPayAccount.getApp_id();String alipay_public_key = aliPayAccount.getAlipay_public_key();String app_private_key = aliPayAccount.getApp_private_key();String sign_type = aliPayAccount.getSign_type();AlipayClient alipayClient = new DefaultAlipayClient(URL, app_id, app_private_key, FORMAT, CHARSET, alipay_public_key, sign_type);//设置请求参数AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();request.setBizContent("{" +"\"out_trade_no\":\"20150320010101001\"," +"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +"\"total_amount\":88.88," +"\"subject\":\"Iphone6 16G\"," +"\"body\":\"Iphone6 16G\"," +"\"time_expire\":\"2016-12-31 10:05:01\"," +"      \"goods_detail\":[{" +"        \"goods_id\":\"apple-01\"," +"\"alipay_goods_id\":\"20010001\"," +"\"goods_name\":\"ipad\"," +"\"quantity\":1," +"\"price\":2000," +"\"goods_category\":\"34543238\"," +"\"categories_tree\":\"124868003|126232002|126252004\"," +"\"body\":\"特价手机\"," +"\"show_url\":\"http://www.alipay.com/xxx.jpg\"" +"        }]," +"\"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +"\"extend_params\":{" +"\"sys_service_provider_id\":\"2088511833207846\"," +"\"hb_fq_num\":\"3\"," +"\"hb_fq_seller_percent\":\"100\"," +"\"industry_reflux_info\":\"{\\\\\\\"scene_code\\\\\\\":\\\\\\\"metro_tradeorder\\\\\\\",\\\\\\\"channel\\\\\\\":\\\\\\\"xxxx\\\\\\\",\\\\\\\"scene_data\\\\\\\":{\\\\\\\"asset_name\\\\\\\":\\\\\\\"ALIPAY\\\\\\\"}}\"," +"\"card_type\":\"S0JP0000\"" +"    }," +"\"goods_type\":\"0\"," +"\"timeout_express\":\"90m\"," +"\"promo_params\":\"{\\\"storeIdType\\\":\\\"1\\\"}\"," +"\"royalty_info\":{" +"\"royalty_type\":\"ROYALTY\"," +"        \"royalty_detail_infos\":[{" +"          \"serial_no\":1," +"\"trans_in_type\":\"userId\"," +"\"batch_no\":\"123\"," +"\"out_relation_id\":\"20131124001\"," +"\"trans_out_type\":\"userId\"," +"\"trans_out\":\"2088101126765726\"," +"\"trans_in\":\"2088101126708402\"," +"\"amount\":0.1," +"\"desc\":\"分账测试1\"," +"\"amount_percentage\":\"100\"" +"          }]" +"    }," +"\"sub_merchant\":{" +"\"merchant_id\":\"19023454\"," +"\"merchant_type\":\"alipay: 支付宝分配的间连商户编号, merchant: 商户端的间连商户编号\"" +"    }," +"\"merchant_order_no\":\"20161008001\"," +"\"enable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," +"\"store_id\":\"NJ_001\"," +"\"disable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," +"\"qr_pay_mode\":\"1\"," +"\"qrcode_width\":100," +"\"settle_info\":{" +"        \"settle_detail_infos\":[{" +"          \"trans_in_type\":\"cardAliasNo\"," +"\"trans_in\":\"A0001\"," +"\"summary_dimension\":\"A0001\"," +"\"settle_entity_id\":\"2088xxxxx;ST_0001\"," +"\"settle_entity_type\":\"SecondMerchant、Store\"," +"\"amount\":0.1" +"          }]" +"    }," +"\"invoice_info\":{" +"\"key_info\":{" +"\"is_support_invoice\":true," +"\"invoice_merchant_name\":\"ABC|003\"," +"\"tax_num\":\"1464888883494\"" +"      }," +"\"details\":\"[{\\\"code\\\":\\\"100294400\\\",\\\"name\\\":\\\"服饰\\\",\\\"num\\\":\\\"2\\\",\\\"sumPrice\\\":\\\"200.00\\\",\\\"taxRate\\\":\\\"6%\\\"}]\"" +"    }," +"\"agreement_sign_params\":{" +"\"personal_product_code\":\"GENERAL_WITHHOLDING_P\"," +"\"sign_scene\":\"INDUSTRY|CARRENTAL\"," +"\"external_agreement_no\":\"test\"," +"\"external_logon_id\":\"13852852877\"," +"\"sign_validity_period\":\"2m\"," +"\"third_party_type\":\"PARTNER\"," +"\"buckle_app_id\":\"1001164\"," +"\"buckle_merchant_id\":\"268820000000414397785\"," +"\"promo_params\":\"{\\\"key\\\",\\\"value\\\"}\"" +"    }," +"\"integration_type\":\"PCWEB\"," +"\"request_from_url\":\"https://\"," +"\"business_params\":\"{\\\"data\\\":\\\"123\\\"}\"," +"\"ext_user_info\":{" +"\"name\":\"李明\"," +"\"mobile\":\"16587658765\"," +"\"cert_type\":\"IDENTITY_CARD\"," +"\"cert_no\":\"362334768769238881\"," +"\"min_age\":\"18\"," +"\"fix_buyer\":\"F\"," +"\"need_check_info\":\"F\"" +"    }" +"  }");AlipayTradePagePayResponse response = alipayClient.pageExecute(request);if (response.isSuccess()) {System.out.println("调用成功");} else {System.out.println("调用失败");}}}

生成二维码

public class QRCodeUtil {private static final String CHARSET = "utf-8";private static final String FORMAT_NAME = "JPG";// 二维码尺寸private static final int QRCODE_SIZE = 300;// LOGO宽度private static final int WIDTH = 240;// LOGO高度private static final int HEIGHT = 240;private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, CHARSET);hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (imgPath == null || "".equals(imgPath)) {return image;}// 插入图片QRCodeUtil.insertImage(image, imgPath, needCompress);return image;}/*** 功能描述: 生成二维码 BufferedImage.** @param content* @param* @param* @return java.awt.image.BufferedImage* @author yangshao* @date 2019/9/25 10:13*/public static BufferedImage getBufferImage(String content) throws Exception {Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}return image;}/*** 功能描述:  生成base64格式二维码.** @param content  content* @return string* @author yangshao* @date 2019/9/25 10:28*/public static String getBase64Code(String content) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();try {BufferedImage image = getBufferImage(content);//转换成png格式的IO流ImageIO.write(image, "png", byteArrayOutputStream);} catch (Exception e) {e.printStackTrace();}byte[] bytes = byteArrayOutputStream.toByteArray();BASE64Encoder encoder = new BASE64Encoder();String base64 = encoder.encodeBuffer(bytes).trim();/*base64 = "data:image/png;base64," + base64;*/return base64;}private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {File file = new File(imgPath);if (!file.exists()) {System.err.println("" + imgPath + "   该文件不存在!");return;}Image src = ImageIO.read(new File(imgPath));int width = src.getWidth(null);int height = src.getHeight(null);if (needCompress) { // 压缩LOGOif (width > WIDTH) {width = WIDTH;}if (height > HEIGHT) {height = HEIGHT;}Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = tag.getGraphics();g.drawImage(image, 0, 0, null); // 绘制缩小后的图g.dispose();src = image;}// 插入LOGOGraphics2D graph = source.createGraphics();int x = (QRCODE_SIZE - width) / 2;int y = (QRCODE_SIZE - height) / 2;graph.drawImage(src, x, y, width, height, null);Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);mkdirs(destPath);// String file = new Random().nextInt(99999999)+".jpg";// ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));ImageIO.write(image, FORMAT_NAME, new File(destPath));}public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);return image;}public static void mkdirs(String destPath) {File file = new File(destPath);// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)if (!file.exists() && !file.isDirectory()) {file.mkdirs();}}public static void encode(String content, String imgPath, String destPath) throws Exception {QRCodeUtil.encode(content, imgPath, destPath, false);}// 被注释的方法/** public static void encode(String content, String destPath, boolean* needCompress) throws Exception { QRCodeUtil.encode(content, null, destPath,* needCompress); }*/public static void encode(String content, String destPath) throws Exception {QRCodeUtil.encode(content, null, destPath, false);}public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);ImageIO.write(image, FORMAT_NAME, output);}public static void encode(String content, OutputStream output) throws Exception {QRCodeUtil.encode(content, null, output, false);}public static String decode(File file) throws Exception {BufferedImage image;image = ImageIO.read(file);if (image == null) {return null;}BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));Result result;Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();hints.put(DecodeHintType.CHARACTER_SET, CHARSET);result = new MultiFormatReader().decode(bitmap, hints);String resultStr = result.getText();return resultStr;}public static String decode(String path) throws Exception {return QRCodeUtil.decode(new File(path));}}

支付宝回调接口


这部分 坑就在于 验签功能,验签失败,可能是由于沙箱环境配置问题。注意支付宝公钥和私钥不要对应错。
回调接口 在沙箱中一样要被本地代码对应(回调路径要放到服务器上测试)

public String doNotify() {Map<String, String> params = new HashMap<String, String>();String orderID = "";try {//获取支付宝POST过来反馈信息Map<String, String[]> requestParams = request.getParameterMap();for (Iterator<String> 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);}log.info("异步的参数:" + params.toString());SystemConfig queryOneSystemConfig = orderPayService.queryOneSystemConfig("cm2_aliPayAccount");AliPayAccount aliPayAccount = new Gson().fromJson(queryOneSystemConfig.getConfigValue(), AliPayAccount.class);String alipay_public_key = aliPayAccount.getAlipay_public_key();String sign_type = aliPayAccount.getSign_type();log.info("alipay_public_key:" + alipay_public_key);log.info("CHARSET:" + CHARSET);log.info("sign_type:" + sign_type);/*** 调用SDK验证签名*/boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, CHARSET, sign_type);log.info("验证结果:" + signVerified);/*** 实际验证过程建议商户务必添加以下校验:*             1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,*             2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),*             3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)*             4、验证app_id是否为该商户本身。*//*** 商户订单号*/String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), CHARSET);log.info("out_trade_no : " + out_trade_no);PayRecord queryOrderPayRecordByOrderID = this.orderPayService.queryOrderPayRecordByOut_Trade_NoAndType(out_trade_no, OrderPayTypeEnum.ALIPAY.getValue());if (null == queryOrderPayRecordByOrderID) {log.error("当前商户订单号不存在");return "fail";}orderID = queryOrderPayRecordByOrderID.getOrderID();if (signVerified) {//支付宝交易号String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), CHARSET);log.info("trade_no : " + trade_no);//付款金额String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), CHARSET);log.info("total_amount : " + total_amount);String formatAmountByCent = CommonUtils.formatAmountByCent(queryOrderPayRecordByOrderID.getPayAmount());if (!total_amount.equals(formatAmountByCent)) {this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 1, "支付异步调用,支付金额和返回金额不匹配");log.error("支付的金额和返回的金额不匹配");return "fail";}//交易状态String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), CHARSET);log.info("交易状态:" + trade_status);String seller_id = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"), CHARSET);log.info("seller_id:" + seller_id);//支付时间String gmt_payment = new String(request.getParameter("gmt_payment").getBytes("ISO-8859-1"), CHARSET);log.info("gmt_payment:" + gmt_payment);String sign = new String(request.getParameter("sign").getBytes("ISO-8859-1"), CHARSET);if (OrderPayStatusEnum.PAID.getValue() == queryOrderPayRecordByOrderID.getPayStatus() || OrderPayStatusEnum.PAYMENT_END.getValue() == queryOrderPayRecordByOrderID.getPayStatus()) {log.info("数据库状态已更新,不需要操作:" + queryOrderPayRecordByOrderID.getPayStatus());this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 1, "支付异步调用,支付状态已完成");return "success";}String buyer_logon_id = new String(request.getParameter("buyer_logon_id").getBytes("ISO-8859-1"), CHARSET);long longValue = (new BigDecimal(total_amount).multiply(new BigDecimal("100"))).longValue();queryOrderPayRecordByOrderID.setPayAmount(longValue);queryOrderPayRecordByOrderID.setTrade_no(trade_no);queryOrderPayRecordByOrderID.setPayType(OrderPayTypeEnum.ALIPAY.getValue());queryOrderPayRecordByOrderID.setComment(queryOrderPayRecordByOrderID.getComment() + "时间:" + new Date() + "==>支付宝异步数据");queryOrderPayRecordByOrderID.setEditTime(new Date());queryOrderPayRecordByOrderID.setSeller_id(seller_id);queryOrderPayRecordByOrderID.setBuyer_logon_id(buyer_logon_id);Date payTime = null;if (null != gmt_payment && !"".equals(gmt_payment)) {SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");payTime = sDateFormat.parse(gmt_payment);}queryOrderPayRecordByOrderID.setPayTime(payTime);queryOrderPayRecordByOrderID.setSign(sign);//交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)if (trade_status.equals("TRADE_FINISHED")) {//注意://退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知queryOrderPayRecordByOrderID.setPayStatus(OrderPayStatusEnum.PAYMENT_END.getValue());this.orderPayService.updateOrderPayRecord(queryOrderPayRecordByOrderID);} else if (trade_status.equals("TRADE_SUCCESS")) {queryOrderPayRecordByOrderID.setPayStatus(OrderPayStatusEnum.PAID.getValue());this.orderPayService.updateOrderPayRecord(queryOrderPayRecordByOrderID);} else if (trade_status.equals("TRADE_CLOSED")) {queryOrderPayRecordByOrderID.setPayStatus(OrderPayStatusEnum.PAYMENT_FAILED.getValue());this.orderPayService.updateOrderPayRecord(queryOrderPayRecordByOrderID);} else {log.error("当前状态不作处理,让支付再次异步:" + trade_status);this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 1, "支付异步调用,状态不处理");return "fail";}this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 0, "支付异步调用");return "success";} else {//验证失败log.error("异步同步数据验证失败");this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 1, "支付异步调用,验证失败");return "fail";}} catch (Exception e) {log.error("异步同步数据异常:", e);this.payLogService.createPayLogByReceive(orderID, new Gson().toJson(params), 1, "支付异步调用异常");return "fail";}}

支付宝扫码支付,回调和退款(沙箱环境配置和完整代码)相关推荐

  1. 支付宝扫码支付-PC版(沙箱环境)

    前言 最近开发了PC端支付宝扫码支付的功能,使用的是沙箱环境.所谓的沙箱环境,其实就是支付宝提供的测试环境(毕竟正式环境需要营业执照等信息进行注册,注册通过后还有一些流程,才能进行正式的扫码支付.对于 ...

  2. 视频教程-PHP支付宝扫码支付-PHP

    PHP支付宝扫码支付 我是一名计算机教师,从事于教学10多年,在计算机教学方面有丰富的经验. 孙培超 ¥40.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...

  3. 支付宝扫码支付(沙箱环境)

    支付宝扫码支付(沙箱环境) 编写时间:2021年7月23日 什么是支付宝扫码支付? ​ 现如今,手机支付已相当普遍,而作为开发人员应该对手机支付操作有所了解.而支付宝接口是支付宝提供的一个接口,用来对 ...

  4. Java-Spring Boot支付宝扫码支付以及支付回调

    前言:最近开发支付宝支付功能,总结一下做个分享 官方文档:https://opendocs.alipay.com/apis 支付宝沙箱地址: https://openhome.alipay.com/p ...

  5. 【SpringBoot深入浅出系列】SpringBoot之实现支付宝扫码支付(沙箱环境编码实现)

    目录 一.准备工作 1.应用 APPID 2.商户私钥,即应用私钥 3.支付宝公钥 4.签名方式 5.字符编码格式 6.支付宝网关 二.沙箱环境编码实现 1.项目说明 2.创建 Spring Init ...

  6. java实现支付宝扫码支付和回调的Demo源码

    java实现支付宝扫码支付Demo源码 扫码效果图 需要现成源码的朋友,可以加Q76949433,提供技术支持! 项目结构截图: package com.pay.common; public clas ...

  7. C# Winform窗体实现支付宝扫码支付

    C# Winform窗体项目实现支付宝扫码支付 一.内容介绍 啪嗒!( 搬好小板凳 ) 大家好,本次学习的内容是在博主大一winform窗体项目中实现的一个功能--支付宝扫码支付: 主要功能通过支付宝 ...

  8. java调用支付宝扫码支付接口

    说明: 由于没有商户账号,所以本文使用的是沙箱账号,本质跟真实账号是一样的,是支付宝为了方便开发人员开发调试而推出的策略.在真实开发中将商户公钥等修改为真实的商户即可. 支付基本流程 用户下单 商户账 ...

  9. 支付宝扫码支付示例源码

    支付宝扫码支付示例源码 支付宝扫码付,相对来说根据开发文档开发的话,基本上可以一遍过的.直接上代码. controller: @RequestMapping(value = {"/api/a ...

最新文章

  1. 使用roslyn代替MSBuild完成解决方案编译
  2. tensorflow创建张量
  3. 拼接图像亮度均匀调整_液晶拼接屏如何才能达到更好的显示效果
  4. manual php,PHP - Manual: 介绍 (官方文档)
  5. 下拉加载 实现 java_[Java教程]iscroll5实现一个下拉刷新上拉加载的效果
  6. Windows7中启动Mysql服务时提示:拒绝访问的一种解决方式
  7. linux下达梦数据库启动_linux 平台 达梦DM 7 数据库 启动与关闭
  8. java如何实现tcp传输图像_如何在java中实现TCP服务器和TCP客户端传输文件
  9. PHP学习总结(13)——PHP入门篇之常量
  10. 使用JavaScript分别实现4种样式的九九乘法表(1X1分别在左上、左下、右上、右下)...
  11. Ubuntu下安装python3
  12. 运动matlab分析机械振动,《运用Matlab分析机械振动》-毕业论文.doc
  13. 用Python写前端
  14. javaEE之----------java代码发送邮件
  15. 家用计算机按键不灵怎么修,空格键失灵了怎么办?电脑键盘按键失灵的解决办法...
  16. echarts地图api series_ECharts地图绘制和钻取简易接口详解
  17. 麒麟Linux系统根目录与单目录扩容详解,适用于大多数的centeros系统
  18. 阿里云Linux服务器搭建WordPress教程
  19. css3 svg 背景图 data:image/svg+xml;base64
  20. 永久一键关闭QQ频道,不用重新安装

热门文章

  1. 烟气监测数据转IEC104规约对接电业局平台-国能赤峰生物发电项目
  2. Chrome:拖入crx文件时,显示“无法从该网站添加应用、扩展程序和用户脚本”问题
  3. 腾讯云商标注册入口链接大全
  4. A5133 5.8GHz RFIC收发器
  5. arcmap 坡降工具_ArcGIS水文分析实战教程(10)河流平均比降计算
  6. ElasticSearch的安装与使用必知问题
  7. 分类齐全,免费的数据接口
  8. 天猫这些规则你还不知道就摊上大事了
  9. [国产PLC]耐特稳定PLC在多色印刷机械怎么运用
  10. 喜忧参半的AI,“裸奔”之下的隐私焦虑 1