2023微信支付对接全流程

article/2025/11/11 17:06:24

简单说一下微信支付的几种类型的应用场景以及前提条件
官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml

前提条件:

1.需要一个载体公众号或者小程序,公众号要是服务号不是订阅号。
2.小程序和公众号支付都要认证,要300rmb。
3.需要一个商户号,绑定公众号或者小程序。

1.jsapi支付:

就是在微信平台内,微信内置浏览器或者小程序唤起微信支付

对接流程:

在自己的后台请求微信接口下预订单,然后将下单参数各种加密传到前端,用微信浏览器内置对象方法唤起支付WeixinJSBridge.invoke,小程序用
wx.requestPayment唤起支付,用户支付成功后将回调给你在下单参数中的回调地址,你再根据订单号自己处理结果。注意,两个方法的参数名相同,但是小程序支付唤起参数requestPayment下单接口参数中的openid和appid必须用小程序的,微信浏览器的同理。

2.h5支付:

普通浏览器,或者app的webview里面访问下单接口返回的h5_url,可通过访问该url来拉起微信客户端,完成支付。

对接流程:

在自己的后台请求微信接口下预订单,然后接口返回h5_url,前端浏览器访问这个url即可唤起客户端。

3Native下单

生成二维码,用户扫码支付,这个比较适用于PC网站等非移动端。

对接流程:

在自己的后台请求微信接口下预订单,然后接口返回code_url,将这个code_url转换成二维码即可。

以上这几个几乎满足所有需求情况了,上点代码,研究全流程细节和坑点

开发示例

这里jspapi为例
1.申请个公众号 https://mp.weixin.qq.com,必须是服务号不然无法开通支付。
2.在后台通过微信认证,要不然商户号没办法绑定你的公众号
在这里插入图片描述
3.申请个商户号 https://pay.weixin.qq.com/
4.商户号绑定公众号,在商户号后台
在这里插入图片描述
5.这里开始看后台代码,接口参数缺的我们再找,首先微信支付的加密解密签名太复杂,而且也不是我们关注的点,已经有大佬写好了,IJPay,不仅微信,还封装了、支付宝支付、银联支付常用的支付方式以及各种常用的接口,源码及示例工程gitee :https://gitee.com/luozhizkang/IJPay
也可以引个maven,这里只引微信支付需要的

		<dependency><groupId>com.github.javen205</groupId><artifactId>IJPay-WxPay</artifactId><version>2.9.4</version></dependency>

6.参数准备类

@Component
@Data
public class WxPayV3Bean {@Value("${wxPay.appId}")private String appId ;//小程序appid@Value("${wxPay.keyPath}")private String keyPath;@Value("${wxPay.certPath}")private String certPath ;@Value("${wxPay.certP12Path}")private String certP12Path ;@Value("${wxPay.platformCertPath}")private String platformCertPath ;@Value("${wxPay.mchId}")private String mchId;//商户号mchId@Value("${wxPay.apiKey}")private String apiKey ;@Value("${wxPay.apiKey3}")private String apiKey3 ;@Value("${wxPay.domain}")private String domain;//支付成功回调地址
}

剩下这几个参数怎么获取呢?
在这里插入图片描述
在商户平台中按照指引“申请api证书”,会得到几个文件
在这里插入图片描述
keyPath就是 apiclient_key.pem的绝对路径,例如:D://xxx/apiclient_key.pem
certPath就是 apiclient_cert.pem的绝对路径
certP12Path就是 apiclient_cert.p12的绝对路径
platformCertPath 等会要根据上面的秘钥和证书生成一个文件名字叫platformCertPath.pem,你只需要将绝对路径写好在这就行了,后面程序启动再通过接口下载。例如:D://xxx/platformCertPath.pem
apiKey 可以不用填。
domain就是支付成功的回调地址,这个回调地址的域名要在商户平台配置。

建个controller

@RestController
@RequestMapping("/api/v3")
public class WxPayV3Controller {private final Logger log = LoggerFactory.getLogger(this.getClass());private final static int OK = 200;@ResourceWxPayV3Bean wxPayV3Bean;String serialNo;String platSerialNo;@RequestMapping("/getSerialNumber")@ResponseBodypublic String serialNumber() {return getSerialNumber();}@RequestMapping("/getPlatSerialNumber")@ResponseBodypublic String platSerialNumber() {return getPlatSerialNumber();}private String getSerialNumber() {if (StrUtil.isEmpty(serialNo)) {// 获取证书序列号X509Certificate certificate = PayKit.getCertificate(wxPayV3Bean.getCertPath());if (null != certificate) {serialNo = certificate.getSerialNumber().toString(16).toUpperCase();// 提前两天检查证书是否有效boolean isValid = PayKit.checkCertificateIsValid(certificate, wxPayV3Bean.getMchId(), -2);log.info("证书是否可用 {} 证书有效期为 {}", isValid, DateUtil.format(certificate.getNotAfter(), DatePattern.NORM_DATETIME_PATTERN));}
//            System.out.println("输出证书信息:\n" + certificate.toString());
//            // 输出关键信息,截取部分并进行标记
//            System.out.println("证书序列号:" + certificate.getSerialNumber().toString(16));
//            System.out.println("版本号:" + certificate.getVersion());
//            System.out.println("签发者:" + certificate.getIssuerDN());
//            System.out.println("有效起始日期:" + certificate.getNotBefore());
//            System.out.println("有效终止日期:" + certificate.getNotAfter());
//            System.out.println("主体名:" + certificate.getSubjectDN());
//            System.out.println("签名算法:" + certificate.getSigAlgName());
//            System.out.println("签名:" + certificate.getSignature().toString());}System.out.println("serialNo:" + serialNo);return serialNo;}private String getPlatSerialNumber() {if (StrUtil.isEmpty(platSerialNo)) {// 获取平台证书序列号X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wxPayV3Bean.getPlatformCertPath()));platSerialNo = certificate.getSerialNumber().toString(16).toUpperCase();}System.out.println("platSerialNo:" + platSerialNo);return platSerialNo;}private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {try {AesUtil aesUtil = new AesUtil(wxPayV3Bean.getApiKey3().getBytes(StandardCharsets.UTF_8));// 平台证书密文解密// encrypt_certificate 中的  associated_data nonce  ciphertextString publicKey = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),cipherText);// 保存证书FileWriter writer = new FileWriter(certPath);writer.write(publicKey);// 获取平台证书序列号X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));return certificate.getSerialNumber().toString(16).toUpperCase();} catch (Exception e) {e.printStackTrace();return e.getMessage();}}@RequestMapping("/get")@ResponseBodypublic String v3Get() {// 获取平台证书列表try {IJPayHttpResponse response = WxPayApi.v3(RequestMethodEnum.GET,WxDomainEnum.CHINA.toString(),OtherApiEnum.GET_CERTIFICATES.toString(),wxPayV3Bean.getMchId(),getSerialNumber(),null,wxPayV3Bean.getKeyPath(),"");String timestamp = response.getHeader("Wechatpay-Timestamp");String nonceStr = response.getHeader("Wechatpay-Nonce");String serialNumber = response.getHeader("Wechatpay-Serial");String signature = response.getHeader("Wechatpay-Signature");String body = response.getBody();int status = response.getStatus();log.info("serialNumber: {}", serialNumber);log.info("status: {}", status);log.info("body: {}", body);int isOk = 200;if (status == isOk) {JSONObject jsonObject = JSONUtil.parseObj(body);JSONArray dataArray = jsonObject.getJSONArray("data");// 默认认为只有一个平台证书JSONObject encryptObject = dataArray.getJSONObject(0);JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");String associatedData = encryptCertificate.getStr("associated_data");String cipherText = encryptCertificate.getStr("ciphertext");String nonce = encryptCertificate.getStr("nonce");String serialNo = encryptObject.getStr("serial_no");final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, wxPayV3Bean.getPlatformCertPath());log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);}// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());System.out.println("verifySignature:" + verifySignature);return body;} catch (Exception e) {e.printStackTrace();return null;}}@RequestMapping("/nativePay")@ResponseBodypublic String nativePay() {try {String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(wxPayV3Bean.getAppId()).setMchid(wxPayV3Bean.getMchId()).setDescription("IJPay 让支付触手可及").setOut_trade_no(PayKit.generateStr()).setTime_expire(timeExpire).setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX").setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify")).setAmount(new Amount().setTotal(1));log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));IJPayHttpResponse response = WxPayApi.v3(RequestMethodEnum.POST,WxDomainEnum.CHINA.toString(),BasePayApiEnum.NATIVE_PAY.toString(),wxPayV3Bean.getMchId(),getSerialNumber(),null,wxPayV3Bean.getKeyPath(),JSONUtil.toJsonStr(unifiedOrderModel));log.info("统一下单响应 {}", response);// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());log.info("verifySignature: {}", verifySignature);return response.getBody();} catch (Exception e) {e.printStackTrace();return e.getMessage();}}@RequestMapping("/jsApiPay")@ResponseBodypublic String jsApiPay(@RequestParam(value = "openId", required = false, defaultValue = "o-_-itxuXeGW3O1cxJ7FXNmq8Wf8") String openId) {try {String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(wxPayV3Bean.getAppId()).setMchid(wxPayV3Bean.getMchId()).setDescription("IJPay 让支付触手可及").setOut_trade_no(PayKit.generateStr()).setTime_expire(timeExpire).setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX").setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify")).setAmount(new Amount().setTotal(1)).setPayer(new Payer().setOpenid(openId));log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));IJPayHttpResponse response = WxPayApi.v3(RequestMethodEnum.POST,WxDomainEnum.CHINA.toString(),BasePayApiEnum.JS_API_PAY.toString(),wxPayV3Bean.getMchId(),getSerialNumber(),null,wxPayV3Bean.getKeyPath(),JSONUtil.toJsonStr(unifiedOrderModel));log.info("统一下单响应 {}", response);// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());log.info("verifySignature: {}", verifySignature);if (response.getStatus() == OK && verifySignature) {String body = response.getBody();JSONObject jsonObject = JSONUtil.parseObj(body);String prepayId = jsonObject.getStr("prepay_id");//这些参数传到前端去,是小程序或者微信浏览器唤起支付的参数Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), prepayId, wxPayV3Bean.getKeyPath());log.info("唤起支付参数:{}", map);return JSONUtil.toJsonStr(map);}return JSONUtil.toJsonStr(response);} catch (Exception e) {e.printStackTrace();return e.getMessage();}}//支付成功回调@RequestMapping(value = "/payNotify", method = {org.springframework.web.bind.annotation.RequestMethod.POST, org.springframework.web.bind.annotation.RequestMethod.GET})@ResponseBodypublic void payNotify(HttpServletRequest request, HttpServletResponse response) {Map<String, String> map = new HashMap<>(12);try {String timestamp = request.getHeader("Wechatpay-Timestamp");String nonce = request.getHeader("Wechatpay-Nonce");String serialNo = request.getHeader("Wechatpay-Serial");String signature = request.getHeader("Wechatpay-Signature");log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);String result = HttpKit.readData(request);log.info("支付通知密文 {}", result);// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,wxPayV3Bean.getApiKey3(), wxPayV3Bean.getPlatformCertPath());log.info("支付通知明文 {}", plainText);if (StrUtil.isNotEmpty(plainText)) {//完成订单充值com.alibaba.fastjson.JSONObject plain = com.alibaba.fastjson.JSONObject.parseObject(plainText);orderService.updateOrderStatus(plain.getString("out_trade_no"));response.setStatus(200);map.put("code", "SUCCESS");map.put("message", "SUCCESS");} else {response.setStatus(500);map.put("code", "ERROR");map.put("message", "签名错误");}response.setHeader("Content-type", ContentType.JSON.toString());response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));response.flushBuffer();} catch (Exception e) {e.printStackTrace();}}
}

上面的代码也是从IJPay的示例工程中copy来的,如果运行有什么问题直接去gitee去复制源码,我上面有贴gitee地址
启动成功后,调用 /get 接口下载 platformCertPath.pem
调用 /jsApiPay 接口生成微信预支付订单,并将参数传到前端,唤起支付,用户支付成功后会回调到 /payNotify 接口,但是回调地址的域名必须在商户后台配置过,在产品中心->开发配置 里面设置业务域名,如果是本地调试,可以用花生壳或者natapp伪装一个域名,建议用natapp。
前端唤起:
微信浏览器

//order是调用/jsApiPay接口返回的参数
WeixinJSBridge.invoke('getBrandWCPayRequest', order,function(res) {if (res.err_msg == "get_brand_wcpay_request:ok") {// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。} else {}});

小程序

//order是调用/jsApiPay接口返回的参数
wx.requestPayment({'timeStamp':order.timeStamp,'nonceStr': order.nonceStr,'package': order.package,'signType': order.signType,'paySign': order.paySign,'success':function(res){},'fail':function(res){},})

这里一定要记得 /jsApiPay接口的 openid 如果是公众号的方式获取的,wxPayV3Bean.getAppId 也要是公众号的appid,小程序同理。
openid是微信的 相对于载体的用户唯一标识,公众号用户openid获取方式文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
用户openid获取简单流程就是
1.引导用户访问
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
scope 为snsapi_base时只能获取appid ,scope为snsapi_userinfo 可以获取用户的具体信息,可以来做微信登录(其他参数自己文档里看)
用授权成功后候回调到 REDIRECT_URI 并带着参数code
2.拿这个code到后台
访问接口
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
获得用户的 appid

以上就是本人对接微信支付的过程记录,如果碰到什么问题欢迎大家留言讨论


http://chatgpt.dhexx.cn/article/Zd1CuimW.shtml

相关文章

java okhttp 线程池_基于OkHttp实现Java多线程下载方案分析与实现

说明 这篇文章主要是为了演示OkHttp和多线程的简单运用&#xff0c;利用多线程和HTTP断点续传的特性实现多线程下载。总体分为三种实现发难&#xff0c;并且实现了这三种方案。这里先说明&#xff0c;这只是一个Demo程序&#xff0c;为了快速实现功能&#xff0c;所以没有太多设…

抖音短视频seo矩阵系统源码开发搭建分享

一、 什么是账号矩阵&#xff1f; 抖音短视频seo矩阵系统源码开发搭建分享是通过不同平台不同账号之间建立联系&#xff0c;通过将同一品牌下不同平台不同账号的粉丝流量进行账号互通&#xff0c;根据平台不同的规则及内容&#xff0c;来输出企业及品牌信息&#xff0c;通过矩…

ChatGPT | 分割Word文字及表格,优化文本分析

知识库读取Word内容时&#xff0c;由于embedding切片操作&#xff0c;可能会出现表格被分割成多个切片的情况。这种切片方式可能导致“列名栏”和“内容栏”之间的Y轴关系链断裂&#xff0c;从而无法准确地确定每一列的数据对应关系&#xff0c;从而使得无法准确知道每一列的数…

有效利用数学学习资源,提高学习效率!

数学作为一门学科&#xff0c;具有重要的理论和实践应用价值&#xff0c;是许多高中生和大学生必修的课程。然而&#xff0c;许多学生在学习数学时会遇到各种各样的问题&#xff0c;例如难以理解概念、难以解决问题、学习效率低等。为了提高数学学习效率&#xff0c;学生可以利…

羽毛球知识

最近在网上看羽毛球拍&#xff0c;被球拍的名字搞得云里雾里&#xff0c;刚好趁机一边学习一边整理一下羽毛球的相关小知识 关于厂商 主要三大厂商 VICTOR 胜利(蓝厂)&#xff0c;YONEX尤尼克斯(绿厂),李宁(红厂) 关于选拍 球拍的选择可以参考中羽在线的这篇帖子 //不让放…

2022生成模型进展有多快?新论文盘点9类生成模型代表作

萧箫 发自 凹非寺量子位 | 公众号 QbitAI ChatGPT的出现&#xff0c;彻底将生成AI推向爆发。 但别忘了&#xff0c;AI生成模型可不止ChatGPT一个&#xff0c;光是基于文本输入的就有7种—— 图像、视频、代码、3D模型、音频、文本、科学知识…… 尤其2022年&#xff0c;效果好的…

大模型技术发展概述 - (一)

文本内容参考论文《A Survey of Large Language Models》 论文标题&#xff1a;A Survey of Large Language Models 论文链接&#xff1a;https://arxiv.org/pdf/2303.18223v10.pdf 因为这个论文内容太多了&#xff0c;所以我的文章分成几篇来展示&#xff01;目录如下&#x…

高二学生爆肝10个月!自学数电在《我的世界》里打造理论最快计算器,5天涨粉1万...

金磊 梦晨 发自 凹非寺量子位 报道 | 公众号 QbitAI 辛丑牛年&#xff08;2021&#xff09;&#xff0c;《我的世界》&#xff0c;一高二学生因爆肝在B站火了。 他从未接触过数电&#xff0c;一切从零开始&#xff0c;仅仅是为了搞清计算器的原理。 然后……然后…… 就直接在《…

数据分析师获取数据的方式有哪些?

1、外部购买数据 有很多公司或者平台是专门做数据收集和分析的&#xff0c;企业会直接从那里购买数据或者相关服务给数据分析师&#xff0c;这是一种常见的获取数据的方式之一。 2、网络爬取数据 除了购买数据以外&#xff0c;数据分析师还可以通过网络爬虫从网络上爬取数据…

马斯克是全人类的?他旗下有9家公司,特斯拉被评为最没技术含量

最近&#xff0c;“马仔很忙”一词被人们津津乐道。其主角马斯克正被“逼捐事件”“亿万富翁税”搞得焦头烂额。连同前一阵子特斯拉股价暴涨的原因&#xff0c;马斯克成为了舆论关注焦点。不了解他的人&#xff0c;只是感慨特斯拉这个企业的庞大潜力。 人们不知道的是&#xf…

世界大学排名:KIIT成为奥里萨邦和印度东部排名第一的大学

印度布巴内斯瓦尔2021年9月6日 /美通社/ -- 布巴内斯瓦尔的卡林加工业技术学院&#xff08;KIIT&#xff09;取得了令人注目的成就&#xff0c;于2021年9月2日宣布的2022年度《泰晤士高等教育》世界大学排名中&#xff0c;其全球排名跃升200位&#xff0c;位列801 - 1000之间。…

《美国新闻与世界报道》公布2021年全球最佳大学排行榜

全球教育排名权威机构《美国新闻与世界报道》(U.S. News & World Report)公布2021年全球最佳大学排名。今年的榜单包括来自86个国家/地区的学校&#xff0c;多于去年的81个。该排名根据学术研究和声誉对近1500所学校进行评估。在总排名中&#xff0c;美国的大学入选数量最多…

清华大学登顶亚洲第一:2019泰晤士高等教育世界大学排名发布

原文&#xff1a;清华小五爷园&#xff08;ID&#xff1a;xiaowuyeyuanthu&#xff09;量子位 获授权编辑转载 2018年9月26日全球四大权威高校排行榜之一&#xff0c;泰晤士高等教育世界大学排名&#xff08;Times Higher Education World University Rankings&#xff09;公布…

2020莱斯大学计算机全球排名,2020QS世界大学排名:美国莱斯大学排名全球第85位,高于中科大...

原标题&#xff1a;2020QS世界大学排名&#xff1a;美国莱斯大学排名全球第85位&#xff0c;高于中科大 美国莱斯大学是一所中等大小的私立综合性全国大学&#xff0c;是美国最著名的大学之一&#xff0c;素有“南方常春藤”之称。美国莱斯大学2020年usnews排名17&#xff0c;2…

USNews:2019世界大学排行榜

今天&#xff08;10月30日&#xff09;&#xff0c;USNews发布2019世界大学排行榜&#xff0c;来自全球70多个国家的1250所知名大学入围&#xff0c;其中中国高校161所。 今年的USNews世界大学排名主要指标如下&#xff1a;全球研究声誉12.5%&#xff0c;地区性研究声誉 12.5%&…

最新!泰晤士2022世界大学排名发布:97所中国大陆高校上榜!

点击下方卡片&#xff0c;关注“CVer”公众号 AI/CV重磅干货&#xff0c;第一时间送达 来源&#xff1a;泰晤士高等教育 转载自&#xff1a;双一流高校 刚刚&#xff08;北京时间2021年9月2日上午7时&#xff09;&#xff0c;泰晤士高等教育发布了2022年度世界大学排名&#xf…

CMU霸榜,北大第2,清华第3!AIRankings世界高校人工智能排行榜出炉

来源&#xff1a;新智元 要说当下最火的专业&#xff0c;莫过于人工智能了。 恰好最近AIRankings发布了一份全球大学AI相关专业排行榜。 让我们一起看看有哪些大学和机构榜上有名吧。 AI世界排名&#xff1a;北清综合前三 AIRankings排名综合过去十年的研究&#xff0c;以及通用…

19所大陆高校上榜!2021泰晤士世界大学影响力排名发布

来源&#xff1a;青塔学术 青塔学术获悉&#xff0c;4月21日&#xff0c;2021年泰晤士高等教育&#xff08;THE&#xff09;世界大学影响力排名&#xff08;简称&#xff1a;影响力排名&#xff09;发布。 今年&#xff0c;共有19所中国大陆高校参加影响力排名&#xff0c;13所…

麦吉尔大学计算机工程的世界排名,加拿大十大名校世界排名:麦吉尔大学上榜,第一名全球排名20...

加拿大是北美的发达国家&#xff0c;幅员辽阔&#xff0c;自然资源丰富&#xff0c;教育资源也同样非常超前&#xff0c;这里许多名校在世界都是鼎鼎有名的&#xff0c;来看看都有哪些吧! 加拿大十大名校世界排名 1、多伦多大学 排行榜&#xff0c;品牌排行榜 2、麦吉尔大学 排…

2021年度泰晤士全球大学【计算机科学排名】公布

转载于 青塔 泰晤士世界大学学科排名&#xff08;THE World University Rankings by Subject&#xff09;涵盖工程技术、理学、生命科学、计算机科学、教育学、临床前期与临床健康、商业与经济、法学、社会科学、艺术与人文、心理学等11个学科领域。 学科排名采用与世界大学排名…